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 Extract:
427 case Set:
428 case WasmAddress:
429 case WasmBoundsCheck:
430 return sizeof(Value*);
431 case Add:
432 case Sub:
433 case Mul:
434 case Div:
435 case UDiv:
436 case Mod:
437 case UMod:
438 case BitAnd:
439 case BitOr:
440 case BitXor:
441 case Shl:
442 case SShr:
443 case ZShr:
444 case RotR:
445 case RotL:
446 case Equal:
447 case NotEqual:
448 case LessThan:
449 case GreaterThan:
450 case LessEqual:
451 case GreaterEqual:
452 case Above:
453 case Below:
454 case AboveEqual:
455 case BelowEqual:
456 case EqualOrUnordered:
457 case AtomicXchgAdd:
458 case AtomicXchgAnd:
459 case AtomicXchgOr:
460 case AtomicXchgSub:
461 case AtomicXchgXor:
462 case AtomicXchg:
463 case Store8:
464 case Store16:
465 case Store:
466 return 2 * sizeof(Value*);
467 case Select:
468 case AtomicWeakCAS:
469 case AtomicStrongCAS:
470 return 3 * sizeof(Value*);
471 case CCall:
472 case Check:
473 case CheckAdd:
474 case CheckSub:
475 case CheckMul:
476 case Patchpoint:
477 return sizeof(Vector<Value*, 3>);
478#ifdef NDEBUG
479 default:
480 break;
481#endif
482 }
483 RELEASE_ASSERT_NOT_REACHED();
484 return 0;
485 }
486
487private:
488 static char* allocateSpace(Opcode opcode, size_t size)
489 {
490 size_t adjacencyListSpace = Value::adjacencyListSpace(opcode);
491 // We must allocate enough space that replaceWithIdentity can work without buffer overflow.
492 size_t allocIdentitySize = sizeof(Value) + sizeof(Value*);
493 size_t allocSize = std::max(size + adjacencyListSpace, allocIdentitySize);
494 return static_cast<char*>(WTF::fastMalloc(allocSize));
495 }
496
497protected:
498 template<typename ValueType, typename... Arguments>
499 static ValueType* allocate(Arguments... arguments)
500 {
501 char* alloc = allocateSpace(ValueType::opcodeFromConstructor(arguments...), sizeof(ValueType));
502 return new (alloc) ValueType(arguments...);
503 }
504 template<typename ValueType>
505 static ValueType* allocate(const ValueType& valueToClone)
506 {
507 char* alloc = allocateSpace(valueToClone.opcode(), sizeof(ValueType));
508 ValueType* result = new (alloc) ValueType(valueToClone);
509 result->buildAdjacencyList(sizeof(ValueType), valueToClone);
510 return result;
511 }
512
513 // Protected so it will only be called from allocate above, possibly through the subclasses'copy constructors
514 Value(const Value&) = default;
515
516 Value(Value&&) = delete;
517 Value& operator=(const Value&) = delete;
518 Value& operator=(Value&&) = delete;
519
520 size_t adjacencyListOffset() const;
521
522 friend class Procedure;
523 friend class SparseCollection<Value>;
524
525private:
526 template<typename... Arguments>
527 void buildAdjacencyList(NumChildren numChildren, Arguments... arguments)
528 {
529 if (numChildren == VarArgs) {
530 new (childrenAlloc()) Vector<Value*, 3> { arguments... };
531 return;
532 }
533 ASSERT(numChildren == sizeof...(arguments));
534 new (childrenAlloc()) Value*[sizeof...(arguments)] { arguments... };
535 }
536 void buildAdjacencyList(size_t offset, const Value& valueToClone)
537 {
538 switch (valueToClone.m_numChildren) {
539 case VarArgs:
540 new (bitwise_cast<char*>(this) + offset) Vector<Value*, 3> (valueToClone.childrenVector());
541 break;
542 case Three:
543 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[2] = valueToClone.childrenArray()[2];
544 FALLTHROUGH;
545 case Two:
546 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[1] = valueToClone.childrenArray()[1];
547 FALLTHROUGH;
548 case One:
549 bitwise_cast<Value**>(bitwise_cast<char*>(this) + offset)[0] = valueToClone.childrenArray()[0];
550 break;
551 case Zero:
552 break;
553 }
554 }
555
556 // Checks that this kind is valid for use with B3::Value.
557 ALWAYS_INLINE static NumChildren numChildrenForKind(Kind kind, unsigned numArgs)
558 {
559 switch (kind.opcode()) {
560 case FramePointer:
561 case Nop:
562 case Phi:
563 case Jump:
564 case Oops:
565 case EntrySwitch:
566 if (UNLIKELY(numArgs))
567 badKind(kind, numArgs);
568 return Zero;
569 case Return:
570 if (UNLIKELY(numArgs > 1))
571 badKind(kind, numArgs);
572 return numArgs ? One : Zero;
573 case Identity:
574 case Opaque:
575 case Neg:
576 case Clz:
577 case Abs:
578 case Ceil:
579 case Floor:
580 case Sqrt:
581 case SExt8:
582 case SExt16:
583 case Trunc:
584 case SExt32:
585 case ZExt32:
586 case FloatToDouble:
587 case IToD:
588 case DoubleToFloat:
589 case IToF:
590 case BitwiseCast:
591 case Branch:
592 case Depend:
593 if (UNLIKELY(numArgs != 1))
594 badKind(kind, numArgs);
595 return One;
596 case Add:
597 case Sub:
598 case Mul:
599 case Div:
600 case UDiv:
601 case Mod:
602 case UMod:
603 case BitAnd:
604 case BitOr:
605 case BitXor:
606 case Shl:
607 case SShr:
608 case ZShr:
609 case RotR:
610 case RotL:
611 case Equal:
612 case NotEqual:
613 case LessThan:
614 case GreaterThan:
615 case LessEqual:
616 case GreaterEqual:
617 case Above:
618 case Below:
619 case AboveEqual:
620 case BelowEqual:
621 case EqualOrUnordered:
622 if (UNLIKELY(numArgs != 2))
623 badKind(kind, numArgs);
624 return Two;
625 case Select:
626 if (UNLIKELY(numArgs != 3))
627 badKind(kind, numArgs);
628 return Three;
629 default:
630 badKind(kind, numArgs);
631 break;
632 }
633 return VarArgs;
634 }
635
636protected:
637 enum CheckedOpcodeTag { CheckedOpcode };
638
639 // Instantiate values via Procedure.
640 // This form requires specifying the type explicitly:
641 template<typename... Arguments>
642 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin, Value* firstChild, Arguments... arguments)
643 : m_kind(kind)
644 , m_type(type)
645 , m_numChildren(numChildren)
646 , m_origin(origin)
647 {
648 buildAdjacencyList(numChildren, firstChild, arguments...);
649 }
650 // This form is for specifying the type explicitly when the opcode has no children:
651 explicit Value(CheckedOpcodeTag, Kind kind, Type type, NumChildren numChildren, Origin origin)
652 : m_kind(kind)
653 , m_type(type)
654 , m_numChildren(numChildren)
655 , m_origin(origin)
656 {
657 buildAdjacencyList(numChildren);
658 }
659 // This form is for those opcodes that can infer their type from the opcode alone, and that don't
660 // take any arguments:
661 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin)
662 : m_kind(kind)
663 , m_type(typeFor(kind, nullptr))
664 , m_numChildren(numChildren)
665 , m_origin(origin)
666 {
667 buildAdjacencyList(numChildren);
668 }
669 // This form is for those opcodes that can infer their type from the opcode and first child:
670 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild)
671 : m_kind(kind)
672 , m_type(typeFor(kind, firstChild))
673 , m_numChildren(numChildren)
674 , m_origin(origin)
675 {
676 buildAdjacencyList(numChildren, firstChild);
677 }
678 // This form is for those opcodes that can infer their type from the opcode and first and second child:
679 template<typename... Arguments>
680 explicit Value(CheckedOpcodeTag, Kind kind, NumChildren numChildren, Origin origin, Value* firstChild, Value* secondChild, Arguments... arguments)
681 : m_kind(kind)
682 , m_type(typeFor(kind, firstChild, secondChild))
683 , m_numChildren(numChildren)
684 , m_origin(origin)
685 {
686 buildAdjacencyList(numChildren, firstChild, secondChild, arguments...);
687 }
688
689 // This is the constructor you end up actually calling, if you're instantiating Value
690 // directly.
691 explicit Value(Kind kind, Type type, Origin origin)
692 : Value(CheckedOpcode, kind, type, Zero, origin)
693 {
694 RELEASE_ASSERT(numChildrenForKind(kind, 0) == Zero);
695 }
696 // We explicitly convert the extra arguments to Value* (they may be pointers to some subclasses of Value) to limit template explosion
697 template<typename... Arguments>
698 explicit Value(Kind kind, Origin origin, Arguments... arguments)
699 : Value(CheckedOpcode, kind, numChildrenForKind(kind, sizeof...(arguments)), origin, static_cast<Value*>(arguments)...)
700 {
701 }
702 template<typename... Arguments>
703 explicit Value(Kind kind, Type type, Origin origin, Value* firstChild, Arguments... arguments)
704 : Value(CheckedOpcode, kind, type, numChildrenForKind(kind, 1 + sizeof...(arguments)), origin, firstChild, static_cast<Value*>(arguments)...)
705 {
706 }
707
708private:
709 friend class CheckValue; // CheckValue::convertToAdd() modifies m_kind.
710
711 static Type typeFor(Kind, Value* firstChild, Value* secondChild = nullptr);
712
713 // m_index to m_numChildren are arranged to fit in 64 bits.
714protected:
715 unsigned m_index { UINT_MAX };
716private:
717 Kind m_kind;
718 Type m_type;
719protected:
720 NumChildren m_numChildren;
721private:
722 Origin m_origin;
723
724 NO_RETURN_DUE_TO_CRASH static void badKind(Kind, unsigned);
725
726public:
727 BasicBlock* owner { nullptr }; // computed by Procedure::resetValueOwners().
728};
729
730class DeepValueDump {
731public:
732 DeepValueDump(const Procedure* proc, const Value* value)
733 : m_proc(proc)
734 , m_value(value)
735 {
736 }
737
738 void dump(PrintStream& out) const;
739
740private:
741 const Procedure* m_proc;
742 const Value* m_value;
743};
744
745inline DeepValueDump deepDump(const Procedure& proc, const Value* value)
746{
747 return DeepValueDump(&proc, value);
748}
749inline DeepValueDump deepDump(const Value* value)
750{
751 return DeepValueDump(nullptr, value);
752}
753
754// The following macros are designed for subclasses of B3::Value to use.
755// They are never required for correctness, but can improve the performance of child/lastChild/numChildren/children methods,
756// for users that already know the specific subclass of Value they are manipulating.
757// 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:
758// - B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN: always 0 children (e.g. Const32Value)
759// - B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n): always n children, with n in {1, 2, 3} (e.g. UpsilonValue, with n = 1)
760// - 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)
761// - B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN: always a varargs (e.g. CCallValue)
762// The second set is only to be used by classes that we know are not further subclassed by anyone adding fields,
763// as they hardcode the offset of the children array/vector (which is equal to the size of the object).
764// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN
765// - B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN
766#define B3_SPECIALIZE_VALUE_FOR_NO_CHILDREN \
767 unsigned numChildren() const { return 0; } \
768 WTF::IteratorRange<Value**> children() { return {nullptr, nullptr}; } \
769 WTF::IteratorRange<Value* const*> children() const { return { nullptr, nullptr}; }
770
771#define B3_SPECIALIZE_VALUE_FOR_FIXED_CHILDREN(n) \
772public: \
773 unsigned numChildren() const { return n; } \
774 Value*& child(unsigned index) \
775 { \
776 ASSERT(index <= n); \
777 return childrenArray()[index]; \
778 } \
779 Value* child(unsigned index) const \
780 { \
781 ASSERT(index <= n); \
782 return childrenArray()[index]; \
783 } \
784 Value*& lastChild() \
785 { \
786 return childrenArray()[n - 1]; \
787 } \
788 Value* lastChild() const \
789 { \
790 return childrenArray()[n - 1]; \
791 } \
792 WTF::IteratorRange<Value**> children() \
793 { \
794 Value** buffer = childrenArray(); \
795 return {buffer, buffer + n }; \
796 } \
797 WTF::IteratorRange<Value* const*> children() const \
798 { \
799 Value* const* buffer = childrenArray(); \
800 return {buffer, buffer + n }; \
801 } \
802
803#define B3_SPECIALIZE_VALUE_FOR_NON_VARARGS_CHILDREN \
804public: \
805 unsigned numChildren() const { return m_numChildren; } \
806 Value*& child(unsigned index) { return childrenArray()[index]; } \
807 Value* child(unsigned index) const { return childrenArray()[index]; } \
808 Value*& lastChild() { return childrenArray()[numChildren() - 1]; } \
809 Value* lastChild() const { return childrenArray()[numChildren() - 1]; } \
810 WTF::IteratorRange<Value**> children() \
811 { \
812 Value** buffer = childrenArray(); \
813 return {buffer, buffer + numChildren() }; \
814 } \
815 WTF::IteratorRange<Value* const*> children() const \
816 { \
817 Value* const* buffer = childrenArray(); \
818 return {buffer, buffer + numChildren() }; \
819 } \
820
821#define B3_SPECIALIZE_VALUE_FOR_VARARGS_CHILDREN \
822public: \
823 unsigned numChildren() const { return childrenVector().size(); } \
824 Value*& child(unsigned index) { return childrenVector()[index]; } \
825 Value* child(unsigned index) const { return childrenVector()[index]; } \
826 Value*& lastChild() { return childrenVector().last(); } \
827 Value* lastChild() const { return childrenVector().last(); } \
828 WTF::IteratorRange<Value**> children() \
829 { \
830 Vector<Value*, 3>& vec = childrenVector(); \
831 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
832 } \
833 WTF::IteratorRange<Value* const*> children() const \
834 { \
835 const Vector<Value*, 3>& vec = childrenVector(); \
836 return WTF::makeIteratorRange(&*vec.begin(), &*vec.end()); \
837 } \
838
839// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
840// Also there is no point in applying this to classes with no children, as they don't have a children array to access.
841#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_FIXED_CHILDREN \
842private: \
843 Value** childrenArray() \
844 { \
845 return bitwise_cast<Value**>(bitwise_cast<char*>(this) + sizeof(*this)); \
846 } \
847 Value* const* childrenArray() const \
848 { \
849 return bitwise_cast<Value* const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
850 }
851
852// Only use this for classes with no subclass that add new fields (as it uses sizeof(*this))
853#define B3_SPECIALIZE_VALUE_FOR_FINAL_SIZE_VARARGS_CHILDREN \
854private: \
855 Vector<Value*, 3>& childrenVector() \
856 { \
857 return *bitwise_cast<Vector<Value*, 3>*>(bitwise_cast<char*>(this) + sizeof(*this)); \
858 } \
859 const Vector<Value*, 3>& childrenVector() const \
860 { \
861 return *bitwise_cast<Vector<Value*, 3> const*>(bitwise_cast<char const*>(this) + sizeof(*this)); \
862 } \
863
864} } // namespace JSC::B3
865
866#endif // ENABLE(B3_JIT)
867