1// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
6#define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
7
8#include <iosfwd>
9
10#include "src/base/compiler-specific.h"
11#include "src/codegen/machine-type.h"
12#include "src/codegen/tnode.h"
13#include "src/common/globals.h"
14#include "src/compiler/common-operator.h"
15#include "src/compiler/feedback-source.h"
16#include "src/compiler/node-properties.h"
17#include "src/compiler/operator.h"
18#include "src/compiler/types.h"
19#include "src/compiler/write-barrier-kind.h"
20#include "src/deoptimizer/deoptimize-reason.h"
21#include "src/handles/handles.h"
22#include "src/handles/maybe-handles.h"
23#include "src/objects/objects.h"
24#include "src/objects/type-hints.h"
25#include "src/zone/zone-handle-set.h"
26
27namespace v8 {
28class CFunctionInfo;
29
30namespace internal {
31
32// Forward declarations.
33enum class AbortReason : uint8_t;
34class Zone;
35
36namespace compiler {
37
38// Forward declarations.
39class Operator;
40struct SimplifiedOperatorGlobalCache;
41class CallDescriptor;
42
43enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
44
45size_t hash_value(BaseTaggedness);
46
47std::ostream& operator<<(std::ostream&, BaseTaggedness);
48
49struct ConstFieldInfo {
50  // the map that introduced the const field, if any. An access is considered
51  // mutable iff the handle is null.
52  MaybeHandle<Map> owner_map;
53
54  ConstFieldInfo() : owner_map(MaybeHandle<Map>()) {}
55  explicit ConstFieldInfo(Handle<Map> owner_map) : owner_map(owner_map) {}
56
57  bool IsConst() const { return !owner_map.is_null(); }
58
59  // No const field owner, i.e., a mutable field
60  static ConstFieldInfo None() { return ConstFieldInfo(); }
61};
62
63V8_EXPORT_PRIVATE bool operator==(ConstFieldInfo const&, ConstFieldInfo const&);
64
65size_t hash_value(ConstFieldInfo const&);
66
67V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
68                                           ConstFieldInfo const&);
69
70// An access descriptor for loads/stores of fixed structures like field
71// accesses of heap objects. Accesses from either tagged or untagged base
72// pointers are supported; untagging is done automatically during lowering.
73struct FieldAccess {
74  BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
75  int offset;                     // offset of the field, without tag.
76  MaybeHandle<Name> name;         // debugging only.
77  MaybeHandle<Map> map;           // map of the field value (if known).
78  Type type;                      // type of the field.
79  MachineType machine_type;       // machine type of the field.
80  WriteBarrierKind write_barrier_kind;  // write barrier hint.
81  ConstFieldInfo const_field_info;      // the constness of this access, and the
82                                    // field owner map, if the access is const
83  bool is_store_in_literal;  // originates from a kStoreInLiteral access
84#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
85  ExternalPointerTag external_pointer_tag = kExternalPointerNullTag;
86#endif
87  bool maybe_initializing_or_transitioning_store;  // store is potentially
88                                                   // initializing a newly
89                                                   // allocated object or part
90                                                   // of a map transition.
91
92  FieldAccess()
93      : base_is_tagged(kTaggedBase),
94        offset(0),
95        type(Type::None()),
96        machine_type(MachineType::None()),
97        write_barrier_kind(kFullWriteBarrier),
98        const_field_info(ConstFieldInfo::None()),
99        is_store_in_literal(false),
100        maybe_initializing_or_transitioning_store(false) {}
101
102  FieldAccess(BaseTaggedness base_is_tagged, int offset, MaybeHandle<Name> name,
103              MaybeHandle<Map> map, Type type, MachineType machine_type,
104              WriteBarrierKind write_barrier_kind,
105              ConstFieldInfo const_field_info = ConstFieldInfo::None(),
106              bool is_store_in_literal = false,
107#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
108              ExternalPointerTag external_pointer_tag = kExternalPointerNullTag,
109#endif
110              bool maybe_initializing_or_transitioning_store = false)
111      : base_is_tagged(base_is_tagged),
112        offset(offset),
113        name(name),
114        map(map),
115        type(type),
116        machine_type(machine_type),
117        write_barrier_kind(write_barrier_kind),
118        const_field_info(const_field_info),
119        is_store_in_literal(is_store_in_literal),
120#ifdef V8_SANDBOXED_EXTERNAL_POINTERS
121        external_pointer_tag(external_pointer_tag),
122#endif
123        maybe_initializing_or_transitioning_store(
124            maybe_initializing_or_transitioning_store) {
125    DCHECK_GE(offset, 0);
126    DCHECK_IMPLIES(
127        machine_type.IsMapWord(),
128        offset == HeapObject::kMapOffset && base_is_tagged != kUntaggedBase);
129    DCHECK_IMPLIES(machine_type.IsMapWord(),
130                   (write_barrier_kind == kMapWriteBarrier ||
131                    write_barrier_kind == kNoWriteBarrier ||
132                    write_barrier_kind == kAssertNoWriteBarrier));
133  }
134
135  int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
136};
137
138V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
139
140size_t hash_value(FieldAccess const&);
141
142V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
143
144V8_EXPORT_PRIVATE FieldAccess const& FieldAccessOf(const Operator* op)
145    V8_WARN_UNUSED_RESULT;
146
147template <>
148void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
149                                            PrintVerbosity verbose) const;
150
151// An access descriptor for loads/stores of indexed structures like characters
152// in strings or off-heap backing stores. Accesses from either tagged or
153// untagged base pointers are supported; untagging is done automatically during
154// lowering.
155struct ElementAccess {
156  BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
157  int header_size;                // size of the header, without tag.
158  Type type;                      // type of the element.
159  MachineType machine_type;       // machine type of the element.
160  WriteBarrierKind write_barrier_kind;  // write barrier hint.
161
162  ElementAccess()
163      : base_is_tagged(kTaggedBase),
164        header_size(0),
165        type(Type::None()),
166        machine_type(MachineType::None()),
167        write_barrier_kind(kFullWriteBarrier) {}
168
169  ElementAccess(BaseTaggedness base_is_tagged, int header_size, Type type,
170                MachineType machine_type, WriteBarrierKind write_barrier_kind)
171      : base_is_tagged(base_is_tagged),
172        header_size(header_size),
173        type(type),
174        machine_type(machine_type),
175        write_barrier_kind(write_barrier_kind) {}
176
177  int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
178};
179
180V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&);
181
182size_t hash_value(ElementAccess const&);
183
184V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&);
185
186V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op)
187    V8_WARN_UNUSED_RESULT;
188
189ExternalArrayType ExternalArrayTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
190
191// An access descriptor for loads/stores of CSA-accessible structures.
192struct ObjectAccess {
193  MachineType machine_type;             // machine type of the field.
194  WriteBarrierKind write_barrier_kind;  // write barrier hint.
195
196  ObjectAccess()
197      : machine_type(MachineType::None()),
198        write_barrier_kind(kFullWriteBarrier) {}
199
200  ObjectAccess(MachineType machine_type, WriteBarrierKind write_barrier_kind)
201      : machine_type(machine_type), write_barrier_kind(write_barrier_kind) {}
202
203  int tag() const { return kHeapObjectTag; }
204};
205
206V8_EXPORT_PRIVATE bool operator==(ObjectAccess const&, ObjectAccess const&);
207
208size_t hash_value(ObjectAccess const&);
209
210V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ObjectAccess const&);
211
212V8_EXPORT_PRIVATE ObjectAccess const& ObjectAccessOf(const Operator* op)
213    V8_WARN_UNUSED_RESULT;
214
215// The ConvertReceiverMode is used as parameter by ConvertReceiver operators.
216ConvertReceiverMode ConvertReceiverModeOf(Operator const* op)
217    V8_WARN_UNUSED_RESULT;
218
219// A the parameters for several Check nodes. The {feedback} parameter is
220// optional. If {feedback} references a valid CallIC slot and this MapCheck
221// fails, then speculation on that CallIC slot will be disabled.
222class CheckParameters final {
223 public:
224  explicit CheckParameters(const FeedbackSource& feedback)
225      : feedback_(feedback) {}
226
227  FeedbackSource const& feedback() const { return feedback_; }
228
229 private:
230  FeedbackSource feedback_;
231};
232
233bool operator==(CheckParameters const&, CheckParameters const&);
234
235size_t hash_value(CheckParameters const&);
236
237std::ostream& operator<<(std::ostream&, CheckParameters const&);
238
239CheckParameters const& CheckParametersOf(Operator const*) V8_WARN_UNUSED_RESULT;
240
241enum class CheckBoundsFlag : uint8_t {
242  kConvertStringAndMinusZero = 1 << 0,  // instead of deopting on such inputs
243  kAbortOnOutOfBounds = 1 << 1,         // instead of deopting if input is OOB
244};
245using CheckBoundsFlags = base::Flags<CheckBoundsFlag>;
246DEFINE_OPERATORS_FOR_FLAGS(CheckBoundsFlags)
247
248class CheckBoundsParameters final {
249 public:
250  CheckBoundsParameters(const FeedbackSource& feedback, CheckBoundsFlags flags)
251      : check_parameters_(feedback), flags_(flags) {}
252
253  CheckBoundsFlags flags() const { return flags_; }
254  const CheckParameters& check_parameters() const { return check_parameters_; }
255
256 private:
257  CheckParameters check_parameters_;
258  CheckBoundsFlags flags_;
259};
260
261bool operator==(CheckBoundsParameters const&, CheckBoundsParameters const&);
262
263size_t hash_value(CheckBoundsParameters const&);
264
265std::ostream& operator<<(std::ostream&, CheckBoundsParameters const&);
266
267CheckBoundsParameters const& CheckBoundsParametersOf(Operator const*)
268    V8_WARN_UNUSED_RESULT;
269
270class CheckIfParameters final {
271 public:
272  explicit CheckIfParameters(DeoptimizeReason reason,
273                             const FeedbackSource& feedback)
274      : reason_(reason), feedback_(feedback) {}
275
276  FeedbackSource const& feedback() const { return feedback_; }
277  DeoptimizeReason reason() const { return reason_; }
278
279 private:
280  DeoptimizeReason reason_;
281  FeedbackSource feedback_;
282};
283
284bool operator==(CheckIfParameters const&, CheckIfParameters const&);
285
286size_t hash_value(CheckIfParameters const&);
287
288std::ostream& operator<<(std::ostream&, CheckIfParameters const&);
289
290CheckIfParameters const& CheckIfParametersOf(Operator const*)
291    V8_WARN_UNUSED_RESULT;
292
293enum class CheckFloat64HoleMode : uint8_t {
294  kNeverReturnHole,  // Never return the hole (deoptimize instead).
295  kAllowReturnHole   // Allow to return the hole (signaling NaN).
296};
297
298size_t hash_value(CheckFloat64HoleMode);
299
300std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
301
302class CheckFloat64HoleParameters {
303 public:
304  CheckFloat64HoleParameters(CheckFloat64HoleMode mode,
305                             FeedbackSource const& feedback)
306      : mode_(mode), feedback_(feedback) {}
307
308  CheckFloat64HoleMode mode() const { return mode_; }
309  FeedbackSource const& feedback() const { return feedback_; }
310
311 private:
312  CheckFloat64HoleMode mode_;
313  FeedbackSource feedback_;
314};
315
316CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(Operator const*)
317    V8_WARN_UNUSED_RESULT;
318
319std::ostream& operator<<(std::ostream&, CheckFloat64HoleParameters const&);
320
321size_t hash_value(CheckFloat64HoleParameters const&);
322
323bool operator==(CheckFloat64HoleParameters const&,
324                CheckFloat64HoleParameters const&);
325bool operator!=(CheckFloat64HoleParameters const&,
326                CheckFloat64HoleParameters const&);
327
328// Parameter for CheckClosure node.
329Handle<FeedbackCell> FeedbackCellOf(const Operator* op);
330
331enum class CheckTaggedInputMode : uint8_t {
332  kNumber,
333  kNumberOrBoolean,
334  kNumberOrOddball,
335};
336
337size_t hash_value(CheckTaggedInputMode);
338
339V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
340
341class CheckTaggedInputParameters {
342 public:
343  CheckTaggedInputParameters(CheckTaggedInputMode mode,
344                             const FeedbackSource& feedback)
345      : mode_(mode), feedback_(feedback) {}
346
347  CheckTaggedInputMode mode() const { return mode_; }
348  const FeedbackSource& feedback() const { return feedback_; }
349
350 private:
351  CheckTaggedInputMode mode_;
352  FeedbackSource feedback_;
353};
354
355const CheckTaggedInputParameters& CheckTaggedInputParametersOf(const Operator*)
356    V8_WARN_UNUSED_RESULT;
357
358std::ostream& operator<<(std::ostream&,
359                         const CheckTaggedInputParameters& params);
360
361size_t hash_value(const CheckTaggedInputParameters& params);
362
363bool operator==(CheckTaggedInputParameters const&,
364                CheckTaggedInputParameters const&);
365
366enum class CheckForMinusZeroMode : uint8_t {
367  kCheckForMinusZero,
368  kDontCheckForMinusZero,
369};
370
371size_t hash_value(CheckForMinusZeroMode);
372
373V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
374                                           CheckForMinusZeroMode);
375
376CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*)
377    V8_WARN_UNUSED_RESULT;
378
379class CheckMinusZeroParameters {
380 public:
381  CheckMinusZeroParameters(CheckForMinusZeroMode mode,
382                           const FeedbackSource& feedback)
383      : mode_(mode), feedback_(feedback) {}
384
385  CheckForMinusZeroMode mode() const { return mode_; }
386  const FeedbackSource& feedback() const { return feedback_; }
387
388 private:
389  CheckForMinusZeroMode mode_;
390  FeedbackSource feedback_;
391};
392
393V8_EXPORT_PRIVATE const CheckMinusZeroParameters& CheckMinusZeroParametersOf(
394    const Operator* op) V8_WARN_UNUSED_RESULT;
395
396V8_EXPORT_PRIVATE std::ostream& operator<<(
397    std::ostream&, const CheckMinusZeroParameters& params);
398
399size_t hash_value(const CheckMinusZeroParameters& params);
400
401bool operator==(CheckMinusZeroParameters const&,
402                CheckMinusZeroParameters const&);
403
404enum class CheckMapsFlag : uint8_t {
405  kNone = 0u,
406  kTryMigrateInstance = 1u << 0,
407};
408using CheckMapsFlags = base::Flags<CheckMapsFlag>;
409
410DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags)
411
412std::ostream& operator<<(std::ostream&, CheckMapsFlags);
413
414// A descriptor for map checks. The {feedback} parameter is optional.
415// If {feedback} references a valid CallIC slot and this MapCheck fails,
416// then speculation on that CallIC slot will be disabled.
417class CheckMapsParameters final {
418 public:
419  CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps,
420                      const FeedbackSource& feedback)
421      : flags_(flags), maps_(maps), feedback_(feedback) {}
422
423  CheckMapsFlags flags() const { return flags_; }
424  ZoneHandleSet<Map> const& maps() const { return maps_; }
425  FeedbackSource const& feedback() const { return feedback_; }
426
427 private:
428  CheckMapsFlags const flags_;
429  ZoneHandleSet<Map> const maps_;
430  FeedbackSource const feedback_;
431};
432
433bool operator==(CheckMapsParameters const&, CheckMapsParameters const&);
434
435size_t hash_value(CheckMapsParameters const&);
436
437std::ostream& operator<<(std::ostream&, CheckMapsParameters const&);
438
439CheckMapsParameters const& CheckMapsParametersOf(Operator const*)
440    V8_WARN_UNUSED_RESULT;
441
442ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const*) V8_WARN_UNUSED_RESULT;
443
444// Parameters for CompareMaps operator.
445ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const*)
446    V8_WARN_UNUSED_RESULT;
447
448// A descriptor for growing elements backing stores.
449enum class GrowFastElementsMode : uint8_t {
450  kDoubleElements,
451  kSmiOrObjectElements
452};
453
454inline size_t hash_value(GrowFastElementsMode mode) {
455  return static_cast<uint8_t>(mode);
456}
457
458std::ostream& operator<<(std::ostream&, GrowFastElementsMode);
459
460class GrowFastElementsParameters {
461 public:
462  GrowFastElementsParameters(GrowFastElementsMode mode,
463                             const FeedbackSource& feedback)
464      : mode_(mode), feedback_(feedback) {}
465
466  GrowFastElementsMode mode() const { return mode_; }
467  const FeedbackSource& feedback() const { return feedback_; }
468
469 private:
470  GrowFastElementsMode mode_;
471  FeedbackSource feedback_;
472};
473
474bool operator==(const GrowFastElementsParameters&,
475                const GrowFastElementsParameters&);
476
477inline size_t hash_value(const GrowFastElementsParameters&);
478
479std::ostream& operator<<(std::ostream&, const GrowFastElementsParameters&);
480
481const GrowFastElementsParameters& GrowFastElementsParametersOf(const Operator*)
482    V8_WARN_UNUSED_RESULT;
483
484// A descriptor for elements kind transitions.
485class ElementsTransition final {
486 public:
487  enum Mode : uint8_t {
488    kFastTransition,  // simple transition, just updating the map.
489    kSlowTransition   // full transition, round-trip to the runtime.
490  };
491
492  ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
493      : mode_(mode), source_(source), target_(target) {}
494
495  Mode mode() const { return mode_; }
496  Handle<Map> source() const { return source_; }
497  Handle<Map> target() const { return target_; }
498
499 private:
500  Mode const mode_;
501  Handle<Map> const source_;
502  Handle<Map> const target_;
503};
504
505bool operator==(ElementsTransition const&, ElementsTransition const&);
506
507size_t hash_value(ElementsTransition);
508
509std::ostream& operator<<(std::ostream&, ElementsTransition);
510
511ElementsTransition const& ElementsTransitionOf(const Operator* op)
512    V8_WARN_UNUSED_RESULT;
513
514// Parameters for TransitionAndStoreElement, or
515// TransitionAndStoreNonNumberElement, or
516// TransitionAndStoreNumberElement.
517Handle<Map> DoubleMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
518Handle<Map> FastMapParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
519
520// Parameters for TransitionAndStoreNonNumberElement.
521Type ValueTypeParameterOf(const Operator* op) V8_WARN_UNUSED_RESULT;
522
523// A hint for speculative number operations.
524enum class NumberOperationHint : uint8_t {
525  kSignedSmall,        // Inputs were Smi, output was in Smi.
526  kSignedSmallInputs,  // Inputs were Smi, output was Number.
527  kNumber,             // Inputs were Number, output was Number.
528  kNumberOrBoolean,    // Inputs were Number or Boolean, output was Number.
529  kNumberOrOddball,    // Inputs were Number or Oddball, output was Number.
530};
531
532enum class BigIntOperationHint : uint8_t {
533  kBigInt,
534};
535
536size_t hash_value(NumberOperationHint);
537size_t hash_value(BigIntOperationHint);
538
539V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
540V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BigIntOperationHint);
541V8_EXPORT_PRIVATE NumberOperationHint NumberOperationHintOf(const Operator* op)
542    V8_WARN_UNUSED_RESULT;
543
544class NumberOperationParameters {
545 public:
546  NumberOperationParameters(NumberOperationHint hint,
547                            const FeedbackSource& feedback)
548      : hint_(hint), feedback_(feedback) {}
549
550  NumberOperationHint hint() const { return hint_; }
551  const FeedbackSource& feedback() const { return feedback_; }
552
553 private:
554  NumberOperationHint hint_;
555  FeedbackSource feedback_;
556};
557
558size_t hash_value(NumberOperationParameters const&);
559V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
560                                           const NumberOperationParameters&);
561bool operator==(NumberOperationParameters const&,
562                NumberOperationParameters const&);
563const NumberOperationParameters& NumberOperationParametersOf(const Operator* op)
564    V8_WARN_UNUSED_RESULT;
565
566class SpeculativeBigIntAsNParameters {
567 public:
568  SpeculativeBigIntAsNParameters(int bits, const FeedbackSource& feedback)
569      : bits_(bits), feedback_(feedback) {
570    DCHECK_GE(bits_, 0);
571    DCHECK_LE(bits_, 64);
572  }
573
574  int bits() const { return bits_; }
575  const FeedbackSource& feedback() const { return feedback_; }
576
577 private:
578  int bits_;
579  FeedbackSource feedback_;
580};
581
582size_t hash_value(SpeculativeBigIntAsNParameters const&);
583V8_EXPORT_PRIVATE std::ostream& operator<<(
584    std::ostream&, const SpeculativeBigIntAsNParameters&);
585bool operator==(SpeculativeBigIntAsNParameters const&,
586                SpeculativeBigIntAsNParameters const&);
587const SpeculativeBigIntAsNParameters& SpeculativeBigIntAsNParametersOf(
588    const Operator* op) V8_WARN_UNUSED_RESULT;
589
590int FormalParameterCountOf(const Operator* op) V8_WARN_UNUSED_RESULT;
591
592class AllocateParameters {
593 public:
594  AllocateParameters(
595      Type type, AllocationType allocation_type,
596      AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse)
597      : type_(type),
598        allocation_type_(allocation_type),
599        allow_large_objects_(allow_large_objects) {}
600
601  Type type() const { return type_; }
602  AllocationType allocation_type() const { return allocation_type_; }
603  AllowLargeObjects allow_large_objects() const { return allow_large_objects_; }
604
605 private:
606  Type type_;
607  AllocationType allocation_type_;
608  AllowLargeObjects allow_large_objects_;
609};
610
611bool IsCheckedWithFeedback(const Operator* op);
612
613size_t hash_value(AllocateParameters);
614
615V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, AllocateParameters);
616
617bool operator==(AllocateParameters const&, AllocateParameters const&);
618
619const AllocateParameters& AllocateParametersOf(const Operator* op)
620    V8_WARN_UNUSED_RESULT;
621
622AllocationType AllocationTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
623
624Type AllocateTypeOf(const Operator* op) V8_WARN_UNUSED_RESULT;
625
626UnicodeEncoding UnicodeEncodingOf(const Operator*) V8_WARN_UNUSED_RESULT;
627
628AbortReason AbortReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
629
630DeoptimizeReason DeoptimizeReasonOf(const Operator* op) V8_WARN_UNUSED_RESULT;
631
632class NewArgumentsElementsParameters {
633 public:
634  NewArgumentsElementsParameters(CreateArgumentsType type,
635                                 int formal_parameter_count)
636      : type_(type), formal_parameter_count_(formal_parameter_count) {}
637
638  CreateArgumentsType arguments_type() const { return type_; }
639  int formal_parameter_count() const { return formal_parameter_count_; }
640
641 private:
642  CreateArgumentsType type_;
643  int formal_parameter_count_;
644};
645
646bool operator==(const NewArgumentsElementsParameters&,
647                const NewArgumentsElementsParameters&);
648
649inline size_t hash_value(const NewArgumentsElementsParameters&);
650
651std::ostream& operator<<(std::ostream&, const NewArgumentsElementsParameters&);
652
653const NewArgumentsElementsParameters& NewArgumentsElementsParametersOf(
654    const Operator*) V8_WARN_UNUSED_RESULT;
655
656struct FastApiCallFunction {
657  Address address;
658  const CFunctionInfo* signature;
659
660  bool operator==(const FastApiCallFunction& rhs) const {
661    return address == rhs.address && signature == rhs.signature;
662  }
663};
664typedef ZoneVector<FastApiCallFunction> FastApiCallFunctionVector;
665
666class FastApiCallParameters {
667 public:
668  explicit FastApiCallParameters(const FastApiCallFunctionVector& c_functions,
669                                 FeedbackSource const& feedback,
670                                 CallDescriptor* descriptor)
671      : c_functions_(c_functions),
672        feedback_(feedback),
673        descriptor_(descriptor) {}
674
675  const FastApiCallFunctionVector& c_functions() const { return c_functions_; }
676  FeedbackSource const& feedback() const { return feedback_; }
677  CallDescriptor* descriptor() const { return descriptor_; }
678
679 private:
680  // A single FastApiCall node can represent multiple overloaded functions.
681  const FastApiCallFunctionVector c_functions_;
682
683  const FeedbackSource feedback_;
684  CallDescriptor* descriptor_;
685};
686
687FastApiCallParameters const& FastApiCallParametersOf(const Operator* op)
688    V8_WARN_UNUSED_RESULT;
689
690V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
691                                           FastApiCallParameters const&);
692
693size_t hash_value(FastApiCallParameters const&);
694
695bool operator==(FastApiCallParameters const&, FastApiCallParameters const&);
696
697// Interface for building simplified operators, which represent the
698// medium-level operations of V8, including adding numbers, allocating objects,
699// indexing into objects and arrays, etc.
700// All operators are typed but many are representation independent.
701
702// Number values from JS can be in one of these representations:
703//   - Tagged: word-sized integer that is either
704//     - a signed small integer (31 or 32 bits plus a tag)
705//     - a tagged pointer to a HeapNumber object that has a float64 field
706//   - Int32: an untagged signed 32-bit integer
707//   - Uint32: an untagged unsigned 32-bit integer
708//   - Float64: an untagged float64
709
710// Additional representations for intermediate code or non-JS code:
711//   - Int64: an untagged signed 64-bit integer
712//   - Uint64: an untagged unsigned 64-bit integer
713//   - Float32: an untagged float32
714
715// Boolean values can be:
716//   - Bool: a tagged pointer to either the canonical JS #false or
717//           the canonical JS #true object
718//   - Bit: an untagged integer 0 or 1, but word-sized
719class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
720    : public NON_EXPORTED_BASE(ZoneObject) {
721 public:
722  explicit SimplifiedOperatorBuilder(Zone* zone);
723  SimplifiedOperatorBuilder(const SimplifiedOperatorBuilder&) = delete;
724  SimplifiedOperatorBuilder& operator=(const SimplifiedOperatorBuilder&) =
725      delete;
726
727  const Operator* BooleanNot();
728
729  const Operator* NumberEqual();
730  const Operator* NumberSameValue();
731  const Operator* NumberLessThan();
732  const Operator* NumberLessThanOrEqual();
733  const Operator* NumberAdd();
734  const Operator* NumberSubtract();
735  const Operator* NumberMultiply();
736  const Operator* NumberDivide();
737  const Operator* NumberModulus();
738  const Operator* NumberBitwiseOr();
739  const Operator* NumberBitwiseXor();
740  const Operator* NumberBitwiseAnd();
741  const Operator* NumberShiftLeft();
742  const Operator* NumberShiftRight();
743  const Operator* NumberShiftRightLogical();
744  const Operator* NumberImul();
745  const Operator* NumberAbs();
746  const Operator* NumberClz32();
747  const Operator* NumberCeil();
748  const Operator* NumberFloor();
749  const Operator* NumberFround();
750  const Operator* NumberAcos();
751  const Operator* NumberAcosh();
752  const Operator* NumberAsin();
753  const Operator* NumberAsinh();
754  const Operator* NumberAtan();
755  const Operator* NumberAtan2();
756  const Operator* NumberAtanh();
757  const Operator* NumberCbrt();
758  const Operator* NumberCos();
759  const Operator* NumberCosh();
760  const Operator* NumberExp();
761  const Operator* NumberExpm1();
762  const Operator* NumberLog();
763  const Operator* NumberLog1p();
764  const Operator* NumberLog10();
765  const Operator* NumberLog2();
766  const Operator* NumberMax();
767  const Operator* NumberMin();
768  const Operator* NumberPow();
769  const Operator* NumberRound();
770  const Operator* NumberSign();
771  const Operator* NumberSin();
772  const Operator* NumberSinh();
773  const Operator* NumberSqrt();
774  const Operator* NumberTan();
775  const Operator* NumberTanh();
776  const Operator* NumberTrunc();
777  const Operator* NumberToBoolean();
778  const Operator* NumberToInt32();
779  const Operator* NumberToString();
780  const Operator* NumberToUint32();
781  const Operator* NumberToUint8Clamped();
782
783  const Operator* NumberSilenceNaN();
784
785  const Operator* BigIntAdd();
786  const Operator* BigIntSubtract();
787  const Operator* BigIntNegate();
788
789  const Operator* SpeculativeSafeIntegerAdd(NumberOperationHint hint);
790  const Operator* SpeculativeSafeIntegerSubtract(NumberOperationHint hint);
791
792  const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
793  const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
794  const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
795  const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
796  const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
797  const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
798  const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
799  const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
800  const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
801  const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
802  const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
803  const Operator* SpeculativeNumberPow(NumberOperationHint hint);
804
805  const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
806  const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
807  const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
808
809  const Operator* SpeculativeBigIntAdd(BigIntOperationHint hint);
810  const Operator* SpeculativeBigIntSubtract(BigIntOperationHint hint);
811  const Operator* SpeculativeBigIntNegate(BigIntOperationHint hint);
812  const Operator* SpeculativeBigIntAsIntN(int bits,
813                                          const FeedbackSource& feedback);
814  const Operator* SpeculativeBigIntAsUintN(int bits,
815                                           const FeedbackSource& feedback);
816
817  const Operator* ReferenceEqual();
818  const Operator* SameValue();
819  const Operator* SameValueNumbersOnly();
820
821  const Operator* TypeOf();
822
823  const Operator* ToBoolean();
824
825  const Operator* StringConcat();
826  const Operator* StringEqual();
827  const Operator* StringLessThan();
828  const Operator* StringLessThanOrEqual();
829  const Operator* StringCharCodeAt();
830  const Operator* StringCodePointAt();
831  const Operator* StringFromSingleCharCode();
832  const Operator* StringFromSingleCodePoint();
833  const Operator* StringFromCodePointAt();
834  const Operator* StringIndexOf();
835  const Operator* StringLength();
836  const Operator* StringToLowerCaseIntl();
837  const Operator* StringToUpperCaseIntl();
838  const Operator* StringSubstring();
839
840  const Operator* FindOrderedHashMapEntry();
841  const Operator* FindOrderedHashMapEntryForInt32Key();
842
843  const Operator* SpeculativeToNumber(NumberOperationHint hint,
844                                      const FeedbackSource& feedback);
845
846  const Operator* StringToNumber();
847  const Operator* PlainPrimitiveToNumber();
848  const Operator* PlainPrimitiveToWord32();
849  const Operator* PlainPrimitiveToFloat64();
850
851  const Operator* ChangeTaggedSignedToInt32();
852  const Operator* ChangeTaggedSignedToInt64();
853  const Operator* ChangeTaggedToInt32();
854  const Operator* ChangeTaggedToInt64();
855  const Operator* ChangeTaggedToUint32();
856  const Operator* ChangeTaggedToFloat64();
857  const Operator* ChangeTaggedToTaggedSigned();
858  const Operator* ChangeInt31ToTaggedSigned();
859  const Operator* ChangeInt32ToTagged();
860  const Operator* ChangeInt64ToTagged();
861  const Operator* ChangeUint32ToTagged();
862  const Operator* ChangeUint64ToTagged();
863  const Operator* ChangeFloat64ToTagged(CheckForMinusZeroMode);
864  const Operator* ChangeFloat64ToTaggedPointer();
865  const Operator* ChangeTaggedToBit();
866  const Operator* ChangeBitToTagged();
867  const Operator* TruncateBigIntToWord64();
868  const Operator* ChangeInt64ToBigInt();
869  const Operator* ChangeUint64ToBigInt();
870  const Operator* TruncateTaggedToWord32();
871  const Operator* TruncateTaggedToFloat64();
872  const Operator* TruncateTaggedToBit();
873  const Operator* TruncateTaggedPointerToBit();
874
875  const Operator* CompareMaps(ZoneHandleSet<Map>);
876  const Operator* MapGuard(ZoneHandleSet<Map> maps);
877
878  const Operator* CheckBounds(const FeedbackSource& feedback,
879                              CheckBoundsFlags flags = {});
880  const Operator* CheckedUint32Bounds(const FeedbackSource& feedback,
881                                      CheckBoundsFlags flags);
882  const Operator* CheckedUint64Bounds(const FeedbackSource& feedback,
883                                      CheckBoundsFlags flags);
884
885  const Operator* CheckClosure(const Handle<FeedbackCell>& feedback_cell);
886  const Operator* CheckEqualsInternalizedString();
887  const Operator* CheckEqualsSymbol();
888  const Operator* CheckFloat64Hole(CheckFloat64HoleMode, FeedbackSource const&);
889  const Operator* CheckHeapObject();
890  const Operator* CheckIf(DeoptimizeReason deoptimize_reason,
891                          const FeedbackSource& feedback = FeedbackSource());
892  const Operator* CheckInternalizedString();
893  const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>,
894                            const FeedbackSource& = FeedbackSource());
895  const Operator* CheckNotTaggedHole();
896  const Operator* CheckNumber(const FeedbackSource& feedback);
897  const Operator* CheckReceiver();
898  const Operator* CheckReceiverOrNullOrUndefined();
899  const Operator* CheckSmi(const FeedbackSource& feedback);
900  const Operator* CheckString(const FeedbackSource& feedback);
901  const Operator* CheckSymbol();
902
903  const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode,
904                                        const FeedbackSource& feedback);
905  const Operator* CheckedFloat64ToInt64(CheckForMinusZeroMode,
906                                        const FeedbackSource& feedback);
907  const Operator* CheckedInt32Add();
908  const Operator* CheckedInt32Div();
909  const Operator* CheckedInt32Mod();
910  const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
911  const Operator* CheckedInt32Sub();
912  const Operator* CheckedInt32ToTaggedSigned(const FeedbackSource& feedback);
913  const Operator* CheckedInt64ToInt32(const FeedbackSource& feedback);
914  const Operator* CheckedInt64ToTaggedSigned(const FeedbackSource& feedback);
915  const Operator* CheckedTaggedSignedToInt32(const FeedbackSource& feedback);
916  const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode,
917                                         const FeedbackSource& feedback);
918  const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode,
919                                       const FeedbackSource& feedback);
920  const Operator* CheckedTaggedToArrayIndex(const FeedbackSource& feedback);
921  const Operator* CheckedTaggedToInt64(CheckForMinusZeroMode,
922                                       const FeedbackSource& feedback);
923  const Operator* CheckedTaggedToTaggedPointer(const FeedbackSource& feedback);
924  const Operator* CheckedTaggedToTaggedSigned(const FeedbackSource& feedback);
925  const Operator* CheckBigInt(const FeedbackSource& feedback);
926  const Operator* CheckedTruncateTaggedToWord32(CheckTaggedInputMode,
927                                                const FeedbackSource& feedback);
928  const Operator* CheckedUint32Div();
929  const Operator* CheckedUint32Mod();
930  const Operator* CheckedUint32ToInt32(const FeedbackSource& feedback);
931  const Operator* CheckedUint32ToTaggedSigned(const FeedbackSource& feedback);
932  const Operator* CheckedUint64ToInt32(const FeedbackSource& feedback);
933  const Operator* CheckedUint64ToTaggedSigned(const FeedbackSource& feedback);
934
935  const Operator* ConvertReceiver(ConvertReceiverMode);
936
937  const Operator* ConvertTaggedHoleToUndefined();
938
939  const Operator* ObjectIsArrayBufferView();
940  const Operator* ObjectIsBigInt();
941  const Operator* ObjectIsCallable();
942  const Operator* ObjectIsConstructor();
943  const Operator* ObjectIsDetectableCallable();
944  const Operator* ObjectIsMinusZero();
945  const Operator* NumberIsMinusZero();
946  const Operator* ObjectIsNaN();
947  const Operator* NumberIsNaN();
948  const Operator* ObjectIsNonCallable();
949  const Operator* ObjectIsNumber();
950  const Operator* ObjectIsReceiver();
951  const Operator* ObjectIsSmi();
952  const Operator* ObjectIsString();
953  const Operator* ObjectIsSymbol();
954  const Operator* ObjectIsUndetectable();
955
956  const Operator* NumberIsFloat64Hole();
957  const Operator* NumberIsFinite();
958  const Operator* ObjectIsFiniteNumber();
959  const Operator* NumberIsInteger();
960  const Operator* ObjectIsSafeInteger();
961  const Operator* NumberIsSafeInteger();
962  const Operator* ObjectIsInteger();
963
964  const Operator* ArgumentsLength();
965  const Operator* RestLength(int formal_parameter_count);
966
967  const Operator* NewDoubleElements(AllocationType);
968  const Operator* NewSmiOrObjectElements(AllocationType);
969
970  // new-arguments-elements arguments-length
971  const Operator* NewArgumentsElements(CreateArgumentsType type,
972                                       int formal_parameter_count);
973
974  // new-cons-string length, first, second
975  const Operator* NewConsString();
976
977  // ensure-writable-fast-elements object, elements
978  const Operator* EnsureWritableFastElements();
979
980  // maybe-grow-fast-elements object, elements, index, length
981  const Operator* MaybeGrowFastElements(GrowFastElementsMode mode,
982                                        const FeedbackSource& feedback);
983
984  // transition-elements-kind object, from-map, to-map
985  const Operator* TransitionElementsKind(ElementsTransition transition);
986
987  const Operator* Allocate(Type type,
988                           AllocationType allocation = AllocationType::kYoung);
989  const Operator* AllocateRaw(
990      Type type, AllocationType allocation = AllocationType::kYoung,
991      AllowLargeObjects allow_large_objects = AllowLargeObjects::kFalse);
992
993  const Operator* LoadMessage();
994  const Operator* StoreMessage();
995
996  const Operator* LoadFieldByIndex();
997  const Operator* LoadField(FieldAccess const&);
998  const Operator* StoreField(FieldAccess const&,
999                             bool maybe_initializing_or_transitioning = true);
1000
1001  // load-element [base + index]
1002  const Operator* LoadElement(ElementAccess const&);
1003
1004  // load-stack-argument [base + index]
1005  const Operator* LoadStackArgument();
1006
1007  // store-element [base + index], value
1008  const Operator* StoreElement(ElementAccess const&);
1009
1010  // store-element [base + index], value, only with fast arrays.
1011  const Operator* TransitionAndStoreElement(Handle<Map> double_map,
1012                                            Handle<Map> fast_map);
1013  // store-element [base + index], smi value, only with fast arrays.
1014  const Operator* StoreSignedSmallElement();
1015
1016  // store-element [base + index], double value, only with fast arrays.
1017  const Operator* TransitionAndStoreNumberElement(Handle<Map> double_map);
1018
1019  // store-element [base + index], object value, only with fast arrays.
1020  const Operator* TransitionAndStoreNonNumberElement(Handle<Map> fast_map,
1021                                                     Type value_type);
1022
1023  // load-from-object [base + offset]
1024  // This operator comes in two flavors: LoadImmutableFromObject guarantees that
1025  // the underlying object field will be initialized at most once for the
1026  // duration of the program. This enables more optimizations in
1027  // CsaLoadElimination.
1028  // Note: LoadImmutableFromObject is unrelated to LoadImmutable and is lowered
1029  // into a regular Load.
1030  const Operator* LoadFromObject(ObjectAccess const&);
1031  const Operator* LoadImmutableFromObject(ObjectAccess const&);
1032
1033  // store-to-object [base + offset], value
1034  // This operator comes in two flavors: InitializeImmutableInObject guarantees
1035  // that the underlying object field has not and will not be initialized again
1036  // for the duration of the program. This enables more optimizations in
1037  // CsaLoadElimination.
1038  const Operator* StoreToObject(ObjectAccess const&);
1039  const Operator* InitializeImmutableInObject(ObjectAccess const&);
1040
1041  // load-typed-element buffer, [base + external + index]
1042  const Operator* LoadTypedElement(ExternalArrayType const&);
1043
1044  // load-data-view-element object, [base + index]
1045  const Operator* LoadDataViewElement(ExternalArrayType const&);
1046
1047  // store-typed-element buffer, [base + external + index], value
1048  const Operator* StoreTypedElement(ExternalArrayType const&);
1049
1050  // store-data-view-element object, [base + index], value
1051  const Operator* StoreDataViewElement(ExternalArrayType const&);
1052
1053  // Abort (for terminating execution on internal error).
1054  const Operator* RuntimeAbort(AbortReason reason);
1055
1056  // Abort if the value input does not inhabit the given type
1057  const Operator* AssertType(Type type);
1058
1059  // Abort if the value does not match the node's computed type after
1060  // SimplifiedLowering.
1061  const Operator* VerifyType();
1062
1063  const Operator* DateNow();
1064
1065  // Represents the inputs necessary to construct a fast and a slow API call.
1066  const Operator* FastApiCall(
1067      const FastApiCallFunctionVector& c_candidate_functions,
1068      FeedbackSource const& feedback, CallDescriptor* descriptor);
1069
1070 private:
1071  Zone* zone() const { return zone_; }
1072
1073  const SimplifiedOperatorGlobalCache& cache_;
1074  Zone* const zone_;
1075};
1076
1077// Node wrappers.
1078
1079// TODO(jgruber): Consider merging with JSNodeWrapperBase.
1080class SimplifiedNodeWrapperBase : public NodeWrapper {
1081 public:
1082  explicit constexpr SimplifiedNodeWrapperBase(Node* node)
1083      : NodeWrapper(node) {}
1084
1085  // Valid iff this node has a context input.
1086  TNode<Object> context() const {
1087    // Could be a Context or NoContextConstant.
1088    return TNode<Object>::UncheckedCast(
1089        NodeProperties::GetContextInput(node()));
1090  }
1091
1092  // Valid iff this node has exactly one effect input.
1093  Effect effect() const {
1094    DCHECK_EQ(node()->op()->EffectInputCount(), 1);
1095    return Effect{NodeProperties::GetEffectInput(node())};
1096  }
1097
1098  // Valid iff this node has exactly one control input.
1099  Control control() const {
1100    DCHECK_EQ(node()->op()->ControlInputCount(), 1);
1101    return Control{NodeProperties::GetControlInput(node())};
1102  }
1103
1104  // Valid iff this node has a frame state input.
1105  FrameState frame_state() const {
1106    return FrameState{NodeProperties::GetFrameStateInput(node())};
1107  }
1108};
1109
1110#define DEFINE_INPUT_ACCESSORS(Name, name, TheIndex, Type) \
1111  static constexpr int Name##Index() { return TheIndex; }  \
1112  TNode<Type> name() const {                               \
1113    return TNode<Type>::UncheckedCast(                     \
1114        NodeProperties::GetValueInput(node(), TheIndex));  \
1115  }
1116
1117class FastApiCallNode final : public SimplifiedNodeWrapperBase {
1118 public:
1119  explicit constexpr FastApiCallNode(Node* node)
1120      : SimplifiedNodeWrapperBase(node) {
1121    DCHECK_EQ(IrOpcode::kFastApiCall, node->opcode());
1122  }
1123
1124  const FastApiCallParameters& Parameters() const {
1125    return FastApiCallParametersOf(node()->op());
1126  }
1127
1128#define INPUTS(V) V(Receiver, receiver, 0, Object)
1129  INPUTS(DEFINE_INPUT_ACCESSORS)
1130#undef INPUTS
1131
1132  // Besides actual arguments, FastApiCall nodes also take:
1133  static constexpr int kSlowTargetInputCount = 1;
1134  static constexpr int kFastReceiverInputCount = 1;
1135  static constexpr int kSlowReceiverInputCount = 1;
1136  static constexpr int kExtraInputCount = kFastReceiverInputCount;
1137
1138  static constexpr int kArityInputCount = 1;
1139  static constexpr int kNewTargetInputCount = 1;
1140  static constexpr int kHolderInputCount = 1;
1141  static constexpr int kContextAndFrameStateInputCount = 2;
1142  static constexpr int kEffectAndControlInputCount = 2;
1143  int FastCallExtraInputCount() const;
1144  static constexpr int kSlowCallExtraInputCount =
1145      kSlowTargetInputCount + kArityInputCount + kNewTargetInputCount +
1146      kSlowReceiverInputCount + kHolderInputCount +
1147      kContextAndFrameStateInputCount + kEffectAndControlInputCount;
1148
1149  static constexpr int kSlowCallDataArgumentIndex = 3;
1150
1151  // This is the arity fed into FastApiCallArguments.
1152  static constexpr int ArityForArgc(int c_arg_count, int js_arg_count) {
1153    return c_arg_count + js_arg_count + kEffectAndControlInputCount;
1154  }
1155
1156  int FastCallArgumentCount() const;
1157  int SlowCallArgumentCount() const;
1158
1159  constexpr int FirstFastCallArgumentIndex() const {
1160    return ReceiverIndex() + 1;
1161  }
1162  constexpr int FastCallArgumentIndex(int i) const {
1163    return FirstFastCallArgumentIndex() + i;
1164  }
1165  TNode<Object> FastCallArgument(int i) const {
1166    DCHECK_LT(i, FastCallArgumentCount());
1167    return TNode<Object>::UncheckedCast(
1168        NodeProperties::GetValueInput(node(), FastCallArgumentIndex(i)));
1169  }
1170
1171  int FirstSlowCallArgumentIndex() const { return FastCallArgumentCount(); }
1172  int SlowCallArgumentIndex(int i) const {
1173    return FirstSlowCallArgumentIndex() + i;
1174  }
1175  TNode<Object> SlowCallArgument(int i) const {
1176    DCHECK_LT(i, SlowCallArgumentCount());
1177    return TNode<Object>::UncheckedCast(
1178        NodeProperties::GetValueInput(node(), SlowCallArgumentIndex(i)));
1179  }
1180};
1181
1182#undef DEFINE_INPUT_ACCESSORS
1183
1184}  // namespace compiler
1185}  // namespace internal
1186}  // namespace v8
1187
1188#endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
1189