1/*
2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
26#pragma once
27
28#if ENABLE(B3_JIT)
29
30#include "B3Bank.h"
31#include "B3Effects.h"
32#include "B3FrequentedBlock.h"
33#include "B3Kind.h"
34#include "B3Origin.h"
35#include "B3SparseCollection.h"
36#include "B3Type.h"
37#include "B3ValueKey.h"
38#include "B3Width.h"
39#include <wtf/CommaPrinter.h>
40#include <wtf/FastMalloc.h>
41#include <wtf/IteratorRange.h>
42#include <wtf/StdLibExtras.h>
43#include <wtf/TriState.h>
44
45namespace JSC { namespace B3 {
46
47class BasicBlock;
48class CheckValue;
49class InsertionSet;
50class PhiChildren;
51class Procedure;
52
53class JS_EXPORT_PRIVATE Value {
54 WTF_MAKE_FAST_ALLOCATED;
55public:
56 static const char* const dumpPrefix;
57
58 static bool accepts(Kind) { return true; }
59
60 virtual ~Value();
61
62 unsigned index() const { return m_index; }
63
64 // Note that the kind is immutable, except for replacing values with:
65 // Identity, Nop, Oops, Jump, and Phi. See below for replaceWithXXX() methods.
66 Kind kind() const { return m_kind; }
67
68 Opcode opcode() const { return kind().opcode(); }
69
70 // Note that the kind is meant to be immutable. Do this when you know that this is safe. It's not
71 // usually safe.
72 void setKindUnsafely(Kind kind) { m_kind = kind; }
73 void setOpcodeUnsafely(Opcode opcode) { m_kind.setOpcode(opcode); }
74
75 // It's good practice to mirror Kind methods here, so you can say value->isBlah()
76 // instead of value->kind().isBlah().
77 bool isChill() const { return kind().isChill(); }
78 bool traps() const { return kind().traps(); }
79
80 Origin origin() const { return m_origin; }
81 void setOrigin(Origin origin) { m_origin = origin; }
82
83 Type type() const { return m_type; }
84 void setType(Type type) { m_type = type; }
85
86 // This is useful when lowering. Note that this is only valid for non-void values.
87 Bank resultBank() const { return bankForType(type()); }
88 Width resultWidth() const { return widthForType(type()); }
89
90 unsigned numChildren() const
91 {
92 if (m_numChildren == VarArgs)
93 return childrenVector().size();
94 return m_numChildren;
95 }
96
97 Value*& child(unsigned index)
98 {
99 ASSERT(index < numChildren());
100 return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index];
101 }
102 Value* child(unsigned index) const
103 {
104 ASSERT(index < numChildren());
105 return m_numChildren == VarArgs ? childrenVector()[index] : childrenArray()[index];
106 }
107
108 Value*& lastChild()
109 {
110 if (m_numChildren == VarArgs)
111 return childrenVector().last();
112 ASSERT(m_numChildren >= 1);
113 return childrenArray()[m_numChildren - 1];
114 }
115 Value* lastChild() const
116 {
117 if (m_numChildren == VarArgs)
118 return childrenVector().last();
119 ASSERT(m_numChildren >= 1);
120 return childrenArray()[m_numChildren - 1];
121 }
122
123 WTF::IteratorRange<Value**> children()
124 {
125 if (m_numChildren == VarArgs) {
126 Vector<Value*, 3>& vec = childrenVector();
127 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end());
128 }
129 Value** buffer = childrenArray();
130 return {buffer, buffer + m_numChildren };
131 }
132 WTF::IteratorRange<Value* const*> children() const
133 {
134 if (m_numChildren == VarArgs) {
135 const Vector<Value*, 3>& vec = childrenVector();
136 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end());
137 }
138 Value* const* buffer = childrenArray();
139 return {buffer, buffer + m_numChildren };
140 }
141
142 // If you want to replace all uses of this value with a different value, then replace this
143 // value with Identity. Then do a pass of performSubstitution() on all of the values that use
144 // this one. Usually we do all of this in one pass in pre-order, which ensures that the
145 // X->replaceWithIdentity() calls happen before the performSubstitution() calls on X's users.
146 void replaceWithIdentity(Value*);
147
148 // It's often necessary to kill a value. It's tempting to replace the value with Nop or to
149 // just remove it. But unless you are sure that the value is Void, you will probably still
150 // have other values that use this one. Sure, you may kill those later, or you might not. This
151 // method lets you kill a value safely. It will replace Void values with Nop and non-Void
152 // values with Identities on bottom constants. For this reason, this takes a callback that is
153 // responsible for creating bottoms. There's a utility for this, see B3BottomProvider.h. You
154 // can also access that utility using replaceWithBottom(InsertionSet&, size_t).
155 //
156 // You're guaranteed that bottom is zero.
157 template<typename BottomProvider>
158 void replaceWithBottom(const BottomProvider&);
159
160 void replaceWithBottom(InsertionSet&, size_t index);
161
162 // Use this if you want to kill a value and you are sure that the value is Void.
163 void replaceWithNop();
164
165 // Use this if you want to kill a value and you are sure that nobody is using it anymore.
166 void replaceWithNopIgnoringType();
167
168 void replaceWithPhi();
169
170 // These transformations are only valid for terminals.
171 void replaceWithJump(BasicBlock* owner, FrequentedBlock);
172 void replaceWithOops(BasicBlock* owner);
173
174 // You can use this form if owners are valid. They're usually not valid.
175 void replaceWithJump(FrequentedBlock);
176 void replaceWithOops();
177
178 void dump(PrintStream&) const;
179 void deepDump(const Procedure*, PrintStream&) const;
180
181 virtual void dumpSuccessors(const BasicBlock*, PrintStream&) const;
182
183 // This is how you cast Values. For example, if you want to do something provided that we have a
184 // ArgumentRegValue, you can do:
185 //
186 // if (ArgumentRegValue* argumentReg = value->as<ArgumentRegValue>()) {
187 // things
188 // }
189 //
190 // This will return null if this kind() != ArgumentReg. This works because this returns nullptr
191 // if T::accepts(kind()) returns false.
192 template<typename T>
193 T* as();
194 template<typename T>
195 const T* as() const;
196
197 // What follows are a bunch of helpers for inspecting and modifying values. Note that we have a
198 // bunch of different idioms for implementing such helpers. You can use virtual methods, and
199 // override from the various Value subclasses. You can put the method inside Value and make it
200 // non-virtual, and the implementation can switch on kind. The method could be inline or not.
201 // If a method is specific to some Value subclass, you could put it in the subclass, or you could
202 // put it on Value anyway. It's fine to pick whatever feels right, and we shouldn't restrict
203 // ourselves to any particular idiom.
204
205 bool isConstant() const;
206 bool isInteger() const;
207
208 virtual Value* negConstant(Procedure&) const;
209 virtual Value* addConstant(Procedure&, int32_t other) const;
210 virtual Value* addConstant(Procedure&, const Value* other) const;
211 virtual Value* subConstant(Procedure&, const Value* other) const;
212 virtual Value* mulConstant(Procedure&, const Value* other) const;
213 virtual Value* checkAddConstant(Procedure&, const Value* other) const;
214 virtual Value* checkSubConstant(Procedure&, const Value* other) const;
215 virtual Value* checkMulConstant(Procedure&, const Value* other) const;
216 virtual Value* checkNegConstant(Procedure&) const;
217 virtual Value* divConstant(Procedure&, const Value* other) const; // This chooses Div<Chill> semantics for integers.
218 virtual Value* uDivConstant(Procedure&, const Value* other) const;
219 virtual Value* modConstant(Procedure&, const Value* other) const; // This chooses Mod<Chill> semantics.
220 virtual Value* uModConstant(Procedure&, const Value* other) const;
221 virtual Value* bitAndConstant(Procedure&, const Value* other) const;
222 virtual Value* bitOrConstant(Procedure&, const Value* other) const;
223 virtual Value* bitXorConstant(Procedure&, const Value* other) const;
224 virtual Value* shlConstant(Procedure&, const Value* other) const;
225 virtual Value* sShrConstant(Procedure&, const Value* other) const;
226 virtual Value* zShrConstant(Procedure&, const Value* other) const;
227 virtual Value* rotRConstant(Procedure&, const Value* other) const;
228 virtual Value* rotLConstant(Procedure&, const Value* other) const;
229 virtual Value* bitwiseCastConstant(Procedure&) const;
230 virtual Value* iToDConstant(Procedure&) const;
231 virtual Value* iToFConstant(Procedure&) const;
232 virtual Value* doubleToFloatConstant(Procedure&) const;
233 virtual Value* floatToDoubleConstant(Procedure&) const;
234 virtual Value* absConstant(Procedure&) const;
235 virtual Value* ceilConstant(Procedure&) const;
236 virtual Value* floorConstant(Procedure&) const;
237 virtual Value* sqrtConstant(Procedure&) const;
238
239 virtual TriState equalConstant(const Value* other) const;
240 virtual TriState notEqualConstant(const Value* other) const;
241 virtual TriState lessThanConstant(const Value* other) const;
242 virtual TriState greaterThanConstant(const Value* other) const;
243 virtual TriState lessEqualConstant(const Value* other) const;
244 virtual TriState greaterEqualConstant(const Value* other) const;
245 virtual TriState aboveConstant(const Value* other) const;
246 virtual TriState belowConstant(const Value* other) const;
247 virtual TriState aboveEqualConstant(const Value* other) const;
248 virtual TriState belowEqualConstant(const Value* other) const;
249 virtual TriState equalOrUnorderedConstant(const Value* other) const;
250
251 // If the value is a comparison then this returns the inverted form of that comparison, if
252 // possible. It can be impossible for double comparisons, where for example LessThan and
253 // GreaterEqual behave differently. If this returns a value, it is a new value, which must be
254 // either inserted into some block or deleted.
255 Value* invertedCompare(Procedure&) const;
256
257 bool hasInt32() const;
258 int32_t asInt32() const;
259 bool isInt32(int32_t) const;
260
261 bool hasInt64() const;
262 int64_t asInt64() const;
263 bool isInt64(int64_t) const;
264
265 bool hasInt() const;
266 int64_t asInt() const;
267 bool isInt(int64_t value) const;
268
269 bool hasIntPtr() const;
270 intptr_t asIntPtr() const;
271 bool isIntPtr(intptr_t) const;
272
273 bool hasDouble() const;
274 double asDouble() const;
275 bool isEqualToDouble(double) const; // We say "isEqualToDouble" because "isDouble" would be a bit equality.
276
277 bool hasFloat() const;
278 float asFloat() const;
279
280 bool hasNumber() const;
281 template<typename T> bool isRepresentableAs() const;
282 template<typename T> T asNumber() const;
283
284 // Booleans in B3 are Const32(0) or Const32(1). So this is true if the type is Int32 and the only
285 // possible return values are 0 or 1. It's OK for this method to conservatively return false.
286 bool returnsBool() const;
287
288 bool isNegativeZero() const;
289
290 bool isRounded() const;
291
292 TriState asTriState() const;
293 bool isLikeZero() const { return asTriState() == FalseTriState; }
294 bool isLikeNonZero() const { return asTriState() == TrueTriState; }
295
296 Effects effects() const;
297
298 // This returns a ValueKey that describes that this Value returns when it executes. Returns an
299 // empty ValueKey if this Value is impure. Note that an operation that returns Void could still
300 // have a non-empty ValueKey. This happens for example with Check operations.
301 ValueKey key() const;
302
303 Value* foldIdentity() const;
304
305 // Makes sure that none of the children are Identity's. If a child points to Identity, this will
306 // repoint it at the Identity's child. For simplicity, this will follow arbitrarily long chains
307 // of Identity's.
308 bool performSubstitution();
309
310 // Free values are those whose presence is guaranteed not to hurt code. We consider constants,
311 // Identities, and Nops to be free. Constants are free because we hoist them to an optimal place.
312 // Identities and Nops are free because we remove them.
313 bool isFree() const;
314
315 // Walk the ancestors of this value (i.e. the graph of things it transitively uses). This
316 // either walks phis or not, depending on whether PhiChildren is null. Your callback gets
317 // called with the signature:
318 //
319 // (Value*) -> WalkStatus
320 enum WalkStatus {
321 Continue,
322 IgnoreChildren,
323 Stop
324 };
325 template<typename Functor>
326 void walk(const Functor& functor, PhiChildren* = nullptr);
327
328 // B3 purposefully only represents signed 32-bit offsets because that's what x86 can encode, and
329 // ARM64 cannot encode anything bigger. The IsLegalOffset type trait is then used on B3 Value
330 // methods to prevent implicit conversions by C++ from invalid offset types: these cause compilation
331 // to fail, instead of causing implementation-defined behavior (which often turns to exploit).
332 // OffsetType isn't sufficient to determine offset validity! Each Value opcode further has an
333 // isLegalOffset runtime method used to determine value legality at runtime. This is exposed to users
334 // of B3 to force them to reason about the target's offset.
335 typedef int32_t OffsetType;
336 template<typename Int>
337 struct IsLegalOffset {
338 static constexpr bool value = std::is_integral<Int>::value
339 && std::is_signed<Int>::value
340 && sizeof(Int) <= sizeof(OffsetType);
341 };
342
343protected:
344 Value* cloneImpl() const;
345
346 void replaceWith(Kind, Type, BasicBlock*);
347 void replaceWith(Kind, Type, BasicBlock*, Value*);
348
349 virtual void dumpChildren(CommaPrinter&, PrintStream&) const;
350 virtual void dumpMeta(CommaPrinter&, PrintStream&) const;
351
352 // The specific value of VarArgs does not matter, but the value of the others is assumed to match their meaning.
353 enum NumChildren : uint8_t { Zero = 0, One = 1, Two = 2, Three = 3, VarArgs = 4};
354
355 char* childrenAlloc() { return bitwise_cast<char*>(this) + adjacencyListOffset(); }
356 const char* childrenAlloc() const { return bitwise_cast<const char*>(this) + adjacencyListOffset(); }
357 Vector<Value*, 3>& childrenVector()
358 {
359 ASSERT(m_numChildren == VarArgs);
360 return *bitwise_cast<Vector<Value*, 3>*>(childrenAlloc());
361 }
362 const Vector<Value*, 3>& childrenVector() const
363 {
364 ASSERT(m_numChildren == VarArgs);
365 return *bitwise_cast<Vector<Value*, 3> const*>(childrenAlloc());
366 }
367 Value** childrenArray()
368 {
369 ASSERT(m_numChildren != VarArgs);
370 return bitwise_cast<Value**>(childrenAlloc());
371 }
372 Value* const* childrenArray() const
373 {
374 ASSERT(m_numChildren != VarArgs);
375 return bitwise_cast<Value* const*>(childrenAlloc());
376 }
377
378 template<typename... Arguments>
379 static Opcode opcodeFromConstructor(Kind kind, Arguments...) { return kind.opcode(); }
380 ALWAYS_INLINE static size_t adjacencyListSpace(Kind kind)
381 {
382 switch (kind.opcode()) {
383 case FramePointer:
384 case Nop:
385 case Phi:
386 case Jump:
387 case Oops:
388 case EntrySwitch:
389 case ArgumentReg:
390 case Const32:
391 case Const64:
392 case ConstFloat:
393 case ConstDouble:
394 case Fence:
395 case SlotBase:
396 case Get:
397 return 0;
398 case Return:
399 case Identity:
400 case Opaque:
401 case Neg:
402 case Clz:
403 case Abs:
404 case Ceil:
405 case Floor:
406 case Sqrt:
407 case SExt8:
408 case SExt16:
409 case Trunc:
410 case SExt32:
411 case ZExt32:
412 case FloatToDouble:
413 case IToD:
414 case DoubleToFloat:
415 case IToF:
416 case BitwiseCast:
417 case Branch:
418 case Depend:
419 case Load8Z:
420 case Load8S:
421 case Load16Z:
422 case Load16S:
423 case Load:
424 case Switch:
425 case Upsilon:
426 case Set:
427 case WasmAddress:
428 case WasmBoundsCheck:
429 return sizeof(Value*);
430 case Add:
431 case Sub:
432 case Mul:
433 case Div:
434 case UDiv:
435 case Mod:
436 case UMod:
437 case BitAnd:
438 case BitOr:
439 case BitXor:
440 case Shl:
441 case SShr:
442 case ZShr:
443 case RotR:
444 case RotL:
445 case Equal:
446 case NotEqual:
447 case LessThan:
448 case GreaterThan:
449 case LessEqual:
450 case GreaterEqual:
451 case Above:
452 case Below:
453 case AboveEqual:
454 case BelowEqual:
455 case EqualOrUnordered:
456 case AtomicXchgAdd:
457 case AtomicXchgAnd:
458 case AtomicXchgOr:
459 case AtomicXchgSub:
460 case AtomicXchgXor:
461 case AtomicXchg:
462 case Store8:
463 case Store16:
464 case Store:
465 return 2 * sizeof(Value*);
466 case Select:
467 case AtomicWeakCAS:
468 case AtomicStrongCAS:
469 return 3 * sizeof(Value*);
470 case CCall:
471 case Check:
472 case CheckAdd:
473 case CheckSub:
474 case CheckMul:
475 case Patchpoint:
476 return sizeof(Vector<Value*, 3>);
477 default:
478 break;
479 }
480 RELEASE_ASSERT_NOT_REACHED();
481 return 0;
482 }
483
484private:
485 static char* allocateSpace(Opcode opcode, size_t size)
486 {
487 size_t adjacencyListSpace = Value::adjacencyListSpace(opcode);
488 // We must allocate enough space that replaceWithIdentity can work without buffer overflow.
489 size_t allocIdentitySize = sizeof(Value) + sizeof(Value*);
490 size_t allocSize = std::max(size + adjacencyListSpace, allocIdentitySize);
491 return static_cast<char*>(WTF::fastMalloc(allocSize));
492 }
493
494protected:
495 template<typename ValueType, typename... Arguments>
496 static ValueType* allocate(Arguments... arguments)
497 {
498 char* alloc = allocateSpace(ValueType::opcodeFromConstructor(arguments...), sizeof(ValueType));
499 return new (alloc) ValueType(arguments...);
500 }
501 template<typename ValueType>
502 static ValueType* allocate(const ValueType& valueToClone)
503 {
504 char* alloc = allocateSpace(valueToClone.opcode(), sizeof(ValueType));
505 ValueType* result = new (alloc) ValueType(valueToClone);
506 result->buildAdjacencyList(sizeof(ValueType), valueToClone);
507 return result;
508 }
509
510 // Protected so it will only be called from allocate above, possibly through the subclasses'copy constructors
511 Value(const Value&) = default;
512
513 Value(Value&&) = delete;
514 Value& operator=(const Value&) = delete;
515 Value& operator=(Value&&) = delete;
516
517 size_t adjacencyListOffset() const;
518
519 friend class Procedure;
520 friend class SparseCollection<Value>;
521
522private:
523 template<typename... Arguments>
524 void buildAdjacencyList(NumChildren numChildren, Arguments... arguments)
525 {
526 if (numChildren == VarArgs) {
527 new (childrenAlloc()) Vector<Value*, 3> { arguments... };
528 return;
529 }
530 ASSERT(numChildren == sizeof...(arguments));
531 new (childrenAlloc()) Value*[sizeof...(arguments)] { arguments... };
532 }
533 void buildAdjacencyList(size_t offset, const Value& valueToClone)
534 {
535 switch (valueToClone.m_numChildren) {
536 case VarArgs:
537 new (bitwise_cast<char*>(this) + offset) Vector<Value*, 3> (valueToClone.childrenVector());
538 break;
539 case Three:
540 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[2] = valueToClone.childrenArray()[2];
541 FALLTHROUGH;
542 case Two:
543 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[1] = valueToClone.childrenArray()[1];
544 FALLTHROUGH;
545 case One:
546 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[0] = valueToClone.childrenArray()[0];
547 break;
548 case Zero:
549 break;
550 }
551 }
552
553 // Checks that this kind is valid for use with B3::Value.
554 ALWAYS_INLINE static NumChildren numChildrenForKind(Kind kind, unsigned numArgs)
555 {
556 switch (kind.opcode()) {
557 case FramePointer:
558 case Nop:
559 case Phi:
560 case Jump:
561 case Oops:
562 case EntrySwitch:
563 if (UNLIKELY(numArgs))
564 badKind(kind, numArgs);
565 return Zero;
566 case Return:
567 if (UNLIKELY(numArgs > 1))
568 badKind(kind, numArgs);
569 return numArgs ? One : Zero;
570 case Identity:
571 case Opaque:
572 case Neg:
573 case Clz:
574 case Abs:
575 case Ceil:
576 case Floor:
577 case Sqrt:
578 case SExt8:
579 case SExt16:
580 case Trunc:
581 case SExt32:
582 case ZExt32:
583 case FloatToDouble:
584 case IToD:
585 case DoubleToFloat:
586 case IToF:
587 case BitwiseCast:
588 case Branch:
589 case Depend:
590 if (UNLIKELY(numArgs != 1))
591 badKind(kind, numArgs);
592 return One;
593 case Add:
594 case Sub:
595 case Mul:
596 case Div:
597 case UDiv:
598 case Mod:
599 case UMod:
600 case BitAnd:
601 case BitOr:
602 case BitXor:
603 case Shl:
604 case SShr:
605 case ZShr:
606 case RotR:
607 case RotL:
608 case Equal:
609 case NotEqual:
610 case LessThan:
611 case GreaterThan:
612 case LessEqual:
613 case GreaterEqual:
614 case Above:
615 case Below:
616 case AboveEqual:
617 case BelowEqual:
618 case EqualOrUnordered:
619 if (UNLIKELY(numArgs != 2))
620 badKind(kind, numArgs);
621 return Two;
622 case Select:
623 if (UNLIKELY(numArgs != 3))
624 badKind(kind, numArgs);
625 return Three;
626 default:
627 badKind(kind, numArgs);
628 break;
629 }
630 return VarArgs;
631 }
632
633protected:
634 enum CheckedOpcodeTag { CheckedOpcode };
635
636 // Instantiate values via Procedure.
637 // This form requires specifying the type explicitly:
638 template<typename... Arguments>
639 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Value* firstChild, Arguments... arguments)
640 : m_kind(kind)
641 , m_type(type)
642 , m_numChildren(numChildren)
643 , m_origin(origin)
644 {
645 buildAdjacencyList(numChildren, firstChild, arguments...);
646 }
647 // This form is for specifying the type explicitly when the opcode has no children:
648 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin)
649 : m_kind(kind)
650 , m_type(type)
651 , m_numChildren(numChildren)
652 , m_origin(origin)
653 {
654 buildAdjacencyList(numChildren);
655 }
656 // This form is for those opcodes that can infer their type from the opcode alone, and that don't
657 // take any arguments:
658 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin)
659 : m_kind(kind)
660 , m_type(typeFor(kind, nullptr))
661 , m_numChildren(numChildren)
662 , m_origin(origin)
663 {
664 buildAdjacencyList(numChildren);
665 }
666 // This form is for those opcodes that can infer their type from the opcode and first child:
667 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild)
668 : m_kind(kind)
669 , m_type(typeFor(kind, firstChild))
670 , m_numChildren(numChildren)
671 , m_origin(origin)
672 {
673 buildAdjacencyList(numChildren, firstChild);
674 }
675 // This form is for those opcodes that can infer their type from the opcode and first and second child:
676 template<typename... Arguments>
677 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
678 : m_kind(kind)
679 , m_type(typeFor(kind, firstChild, secondChild))
680 , m_numChildren(numChildren)
681 , m_origin(origin)
682 {
683 buildAdjacencyList(numChildren, firstChild, secondChild, arguments...);
684 }
685
686 // This is the constructor you end up actually calling, if you're instantiating Value
687 // directly.
688 explicit Value(Kind kind, Type type, Origin origin)
689 : Value(CheckedOpcode, kind, type, Zero, origin)
690 {
691 RELEASE_ASSERT(numChildrenForKind(kind, 0) == Zero);
692 }
693 // We explicitly convert the extra arguments to Value* (they may be pointers to some subclasses of Value) to limit template explosion
694 template<typename... Arguments>
695 explicit Value(Kind kind, Origin origin, Arguments... arguments)
696 : Value(CheckedOpcode, kind, numChildrenForKind(kind, sizeof...(arguments)), origin, static_cast<Value*>(arguments)...)
697 {
698 }
699 template<typename... Arguments>
700 explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments)
701 : Value(CheckedOpcode, kind, type, numChildrenForKind(kind, 1 + sizeof...(arguments)), origin, firstChild, static_cast<Value*>(arguments)...)
702 {
703 }
704
705private:
706 friend class CheckValue; // CheckValue::convertToAdd() modifies m_kind.
707
708 static Type typeFor(Kind, Value* firstChild, Value* secondChild = nullptr);
709
710 // m_index to m_numChildren are arranged to fit in 64 bits.
711protected:
712 unsigned m_index { UINT_MAX };
713private:
714 Kind m_kind;
715 Type m_type;
716protected:
717 NumChildren m_numChildren;
718private:
719 Origin m_origin;
720
721 NO_RETURN_DUE_TO_CRASH static void badKind(Kind, unsigned);
722
723public:
724 BasicBlock* owner { nullptr }; // computed by Procedure::resetValueOwners().
725};
726
727class DeepValueDump {
728public:
729 DeepValueDump(const Procedure* proc, const Value* value)
730 : m_proc(proc)
731 , m_value(value)
732 {
733 }
734
735 void dump(PrintStream& out) const;
736
737private:
738 const Procedure* m_proc;
739 const Value* m_value;
740};
741
742inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
743{
744 return DeepValueDump(&proc, value);
745}
746inline DeepValueDump deepDump(const Value* value)
747{
748 return DeepValueDump(nullptr, value);
749}
750
751// The following macros are designed for subclasses of B3::Value to use.
752// They are never required for correctness, but can improve the performance of child/lastChild/numChildren/children methods,
753// for users that already know the specific subclass of Value they are manipulating.
754// The first set is to be used when you know something about the number of children of all values of a class, including its subclasses:
755// - B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN: always 0 children (e.g. Const32Value)
756// - B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n): always n children, with n in {1, 2, 3} (e.g. UpsilonValue, with n = 1)
757// - B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN: different numbers of children, but never a variable number at runtime (e.g. MemoryValue, that can have between 1 and 3 children)
758// - B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN: always a varargs (e.g. CCallValue)
759// The second set is only to be used by classes that we know are not further subclassed by anyone adding fields,
760// as they hardcode the offset of the children array/vector (which is equal to the size of the object).
761// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
762// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
763#define B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN \
764 unsigned numChildren() const { return 0; } \
765 WTF::IteratorRange<Value**> children() { return {nullptr, nullptr}; } \
766 WTF::IteratorRange<Value* const*> children() const { return { nullptr, nullptr}; }
767
768#define B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n) \
769public: \
770 unsigned numChildren() const { return n; } \
771 Value*& child(unsigned index) \
772 { \
773 ASSERT(index <= n); \
774 return childrenArray()[index]; \
775 } \
776 Value* child(unsigned index) const \
777 { \
778 ASSERT(index <= n); \
779 return childrenArray()[index]; \
780 } \
781 Value*& lastChild() \
782 { \
783 return childrenArray()[n - 1]; \
784 } \
785 Value* lastChild() const \
786 { \
787 return childrenArray()[n - 1]; \
788 } \
789 WTF::IteratorRange<Value**> children() \
790 { \
791 Value** buffer = childrenArray(); \
792 return {buffer, buffer + n }; \
793 } \
794 WTF::IteratorRange<Value* const*> children() const \
795 { \
796 Value* const* buffer = childrenArray(); \
797 return {buffer, buffer + n }; \
798 } \
799
800#define B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN \
801public: \
802 unsigned numChildren() const { return m_numChildren; } \
803 Value*& child(unsigned index) { return childrenArray()[index]; } \
804 Value* child(unsigned index) const { return childrenArray()[index]; } \
805 Value*& lastChild() { return childrenArray()[numChildren() - 1]; } \
806 Value* lastChild() const { return childrenArray()[numChildren() - 1]; } \
807 WTF::IteratorRange<Value**> children() \
808 { \
809 Value** buffer = childrenArray(); \
810 return {buffer, buffer + numChildren() }; \
811 } \
812 WTF::IteratorRange<Value* const*> children() const \
813 { \
814 Value* const* buffer = childrenArray(); \
815 return {buffer, buffer + numChildren() }; \
816 } \
817
818#define B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN \
819public: \
820 unsigned numChildren() const { return childrenVector().size(); } \
821 Value*& child(unsigned index) { return childrenVector()[index]; } \
822 Value* child(unsigned index) const { return childrenVector()[index]; } \
823 Value*& lastChild() { return childrenVector().last(); } \
824 Value* lastChild() const { return childrenVector().last(); } \
825 WTF::IteratorRange<Value**> children() \
826 { \
827 Vector<Value*, 3>& vec = childrenVector(); \
828 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
829 } \
830 WTF::IteratorRange<Value* const*> children() const \
831 { \
832 const Vector<Value*, 3>& vec = childrenVector(); \
833 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
834 } \
835
836// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
837// Also there is no point in applying this to classes with no children, as they don't have a children array to access.
838#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN \
839private: \
840 Value** childrenArray() \
841 { \
842 return bitwise_cast<Value**>(bitwise_cast<char*>(this) + sizeof(*this)); \
843 } \
844 Value* const* childrenArray() const \
845 { \
846 return bitwise_cast<Value* const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
847 }
848
849// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
850#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN \
851private: \
852 Vector<Value*, 3>& childrenVector() \
853 { \
854 return *bitwise_cast<Vector<Value*, 3>*>(bitwise_cast<char*>(this) + sizeof(*this)); \
855 } \
856 const Vector<Value*, 3>& childrenVector() const \
857 { \
858 return *bitwise_cast<Vector<Value*, 3> const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
859 } \
860
861} } // namespace JSC::B3
862
863#endif // ENABLE(B3_JIT)
864