Home | History | Annotate | Download | only in compiler
      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/compiler/operator.h"
     12 #include "src/compiler/types.h"
     13 #include "src/globals.h"
     14 #include "src/handles.h"
     15 #include "src/machine-type.h"
     16 #include "src/objects.h"
     17 
     18 namespace v8 {
     19 namespace internal {
     20 
     21 // Forward declarations.
     22 class Zone;
     23 
     24 namespace compiler {
     25 
     26 // Forward declarations.
     27 class Operator;
     28 struct SimplifiedOperatorGlobalCache;
     29 
     30 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
     31 
     32 size_t hash_value(BaseTaggedness);
     33 
     34 std::ostream& operator<<(std::ostream&, BaseTaggedness);
     35 
     36 
     37 // An access descriptor for loads/stores of array buffers.
     38 class BufferAccess final {
     39  public:
     40   explicit BufferAccess(ExternalArrayType external_array_type)
     41       : external_array_type_(external_array_type) {}
     42 
     43   ExternalArrayType external_array_type() const { return external_array_type_; }
     44   MachineType machine_type() const;
     45 
     46  private:
     47   ExternalArrayType const external_array_type_;
     48 };
     49 
     50 V8_EXPORT_PRIVATE bool operator==(BufferAccess, BufferAccess);
     51 bool operator!=(BufferAccess, BufferAccess);
     52 
     53 size_t hash_value(BufferAccess);
     54 
     55 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BufferAccess);
     56 
     57 V8_EXPORT_PRIVATE BufferAccess const BufferAccessOf(const Operator* op)
     58     WARN_UNUSED_RESULT;
     59 
     60 // An access descriptor for loads/stores of fixed structures like field
     61 // accesses of heap objects. Accesses from either tagged or untagged base
     62 // pointers are supported; untagging is done automatically during lowering.
     63 struct FieldAccess {
     64   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     65   int offset;                     // offset of the field, without tag.
     66   MaybeHandle<Name> name;         // debugging only.
     67   Type* type;                     // type of the field.
     68   MachineType machine_type;       // machine type of the field.
     69   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     70 
     71   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
     72 };
     73 
     74 V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
     75 bool operator!=(FieldAccess const&, FieldAccess const&);
     76 
     77 size_t hash_value(FieldAccess const&);
     78 
     79 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
     80 
     81 FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
     82 
     83 template <>
     84 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
     85                                             PrintVerbosity verbose) const;
     86 
     87 // An access descriptor for loads/stores of indexed structures like characters
     88 // in strings or off-heap backing stores. Accesses from either tagged or
     89 // untagged base pointers are supported; untagging is done automatically during
     90 // lowering.
     91 struct ElementAccess {
     92   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     93   int header_size;                // size of the header, without tag.
     94   Type* type;                     // type of the element.
     95   MachineType machine_type;       // machine type of the element.
     96   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     97 
     98   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
     99 };
    100 
    101 V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&);
    102 bool operator!=(ElementAccess const&, ElementAccess const&);
    103 
    104 size_t hash_value(ElementAccess const&);
    105 
    106 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&);
    107 
    108 V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op)
    109     WARN_UNUSED_RESULT;
    110 
    111 ExternalArrayType ExternalArrayTypeOf(const Operator* op) WARN_UNUSED_RESULT;
    112 
    113 enum class CheckFloat64HoleMode : uint8_t {
    114   kNeverReturnHole,  // Never return the hole (deoptimize instead).
    115   kAllowReturnHole   // Allow to return the hole (signaling NaN).
    116 };
    117 
    118 size_t hash_value(CheckFloat64HoleMode);
    119 
    120 std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
    121 
    122 CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator*) WARN_UNUSED_RESULT;
    123 
    124 enum class CheckTaggedInputMode : uint8_t {
    125   kNumber,
    126   kNumberOrOddball,
    127 };
    128 
    129 size_t hash_value(CheckTaggedInputMode);
    130 
    131 std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
    132 
    133 CheckTaggedInputMode CheckTaggedInputModeOf(const Operator*) WARN_UNUSED_RESULT;
    134 
    135 enum class CheckForMinusZeroMode : uint8_t {
    136   kCheckForMinusZero,
    137   kDontCheckForMinusZero,
    138 };
    139 
    140 size_t hash_value(CheckForMinusZeroMode);
    141 
    142 std::ostream& operator<<(std::ostream&, CheckForMinusZeroMode);
    143 
    144 CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) WARN_UNUSED_RESULT;
    145 
    146 // A descriptor for growing elements backing stores.
    147 enum class GrowFastElementsFlag : uint8_t {
    148   kNone = 0u,
    149   kArrayObject = 1u << 0,     // Update JSArray::length field.
    150   kHoleyElements = 1u << 1,   // Backing store is holey.
    151   kDoubleElements = 1u << 2,  // Backing store contains doubles.
    152 };
    153 typedef base::Flags<GrowFastElementsFlag> GrowFastElementsFlags;
    154 
    155 DEFINE_OPERATORS_FOR_FLAGS(GrowFastElementsFlags)
    156 
    157 std::ostream& operator<<(std::ostream&, GrowFastElementsFlags);
    158 
    159 GrowFastElementsFlags GrowFastElementsFlagsOf(const Operator*)
    160     WARN_UNUSED_RESULT;
    161 
    162 // A descriptor for elements kind transitions.
    163 enum class ElementsTransition : uint8_t {
    164   kFastTransition,  // simple transition, just updating the map.
    165   kSlowTransition   // full transition, round-trip to the runtime.
    166 };
    167 
    168 size_t hash_value(ElementsTransition);
    169 
    170 std::ostream& operator<<(std::ostream&, ElementsTransition);
    171 
    172 ElementsTransition ElementsTransitionOf(const Operator* op) WARN_UNUSED_RESULT;
    173 
    174 // A hint for speculative number operations.
    175 enum class NumberOperationHint : uint8_t {
    176   kSignedSmall,      // Inputs were always Smi so far, output was in Smi range.
    177   kSigned32,         // Inputs and output were Signed32 so far.
    178   kNumber,           // Inputs were Number, output was Number.
    179   kNumberOrOddball,  // Inputs were Number or Oddball, output was Number.
    180 };
    181 
    182 size_t hash_value(NumberOperationHint);
    183 
    184 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
    185 
    186 NumberOperationHint NumberOperationHintOf(const Operator* op)
    187     WARN_UNUSED_RESULT;
    188 
    189 PretenureFlag PretenureFlagOf(const Operator* op) WARN_UNUSED_RESULT;
    190 
    191 UnicodeEncoding UnicodeEncodingOf(const Operator*) WARN_UNUSED_RESULT;
    192 
    193 // Interface for building simplified operators, which represent the
    194 // medium-level operations of V8, including adding numbers, allocating objects,
    195 // indexing into objects and arrays, etc.
    196 // All operators are typed but many are representation independent.
    197 
    198 // Number values from JS can be in one of these representations:
    199 //   - Tagged: word-sized integer that is either
    200 //     - a signed small integer (31 or 32 bits plus a tag)
    201 //     - a tagged pointer to a HeapNumber object that has a float64 field
    202 //   - Int32: an untagged signed 32-bit integer
    203 //   - Uint32: an untagged unsigned 32-bit integer
    204 //   - Float64: an untagged float64
    205 
    206 // Additional representations for intermediate code or non-JS code:
    207 //   - Int64: an untagged signed 64-bit integer
    208 //   - Uint64: an untagged unsigned 64-bit integer
    209 //   - Float32: an untagged float32
    210 
    211 // Boolean values can be:
    212 //   - Bool: a tagged pointer to either the canonical JS #false or
    213 //           the canonical JS #true object
    214 //   - Bit: an untagged integer 0 or 1, but word-sized
    215 class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
    216     : public NON_EXPORTED_BASE(ZoneObject) {
    217  public:
    218   explicit SimplifiedOperatorBuilder(Zone* zone);
    219 
    220   const Operator* BooleanNot();
    221 
    222   const Operator* NumberEqual();
    223   const Operator* NumberLessThan();
    224   const Operator* NumberLessThanOrEqual();
    225   const Operator* NumberAdd();
    226   const Operator* NumberSubtract();
    227   const Operator* NumberMultiply();
    228   const Operator* NumberDivide();
    229   const Operator* NumberModulus();
    230   const Operator* NumberBitwiseOr();
    231   const Operator* NumberBitwiseXor();
    232   const Operator* NumberBitwiseAnd();
    233   const Operator* NumberShiftLeft();
    234   const Operator* NumberShiftRight();
    235   const Operator* NumberShiftRightLogical();
    236   const Operator* NumberImul();
    237   const Operator* NumberAbs();
    238   const Operator* NumberClz32();
    239   const Operator* NumberCeil();
    240   const Operator* NumberFloor();
    241   const Operator* NumberFround();
    242   const Operator* NumberAcos();
    243   const Operator* NumberAcosh();
    244   const Operator* NumberAsin();
    245   const Operator* NumberAsinh();
    246   const Operator* NumberAtan();
    247   const Operator* NumberAtan2();
    248   const Operator* NumberAtanh();
    249   const Operator* NumberCbrt();
    250   const Operator* NumberCos();
    251   const Operator* NumberCosh();
    252   const Operator* NumberExp();
    253   const Operator* NumberExpm1();
    254   const Operator* NumberLog();
    255   const Operator* NumberLog1p();
    256   const Operator* NumberLog10();
    257   const Operator* NumberLog2();
    258   const Operator* NumberMax();
    259   const Operator* NumberMin();
    260   const Operator* NumberPow();
    261   const Operator* NumberRound();
    262   const Operator* NumberSign();
    263   const Operator* NumberSin();
    264   const Operator* NumberSinh();
    265   const Operator* NumberSqrt();
    266   const Operator* NumberTan();
    267   const Operator* NumberTanh();
    268   const Operator* NumberTrunc();
    269   const Operator* NumberToBoolean();
    270   const Operator* NumberToInt32();
    271   const Operator* NumberToUint32();
    272   const Operator* NumberToUint8Clamped();
    273 
    274   const Operator* NumberSilenceNaN();
    275 
    276   const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
    277   const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
    278   const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
    279   const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
    280   const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
    281   const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
    282   const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
    283   const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
    284   const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
    285   const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
    286   const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
    287 
    288   const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
    289   const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
    290   const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
    291 
    292   const Operator* ReferenceEqual();
    293 
    294   const Operator* StringEqual();
    295   const Operator* StringLessThan();
    296   const Operator* StringLessThanOrEqual();
    297   const Operator* StringCharCodeAt();
    298   const Operator* StringFromCharCode();
    299   const Operator* StringFromCodePoint(UnicodeEncoding encoding);
    300 
    301   const Operator* PlainPrimitiveToNumber();
    302   const Operator* PlainPrimitiveToWord32();
    303   const Operator* PlainPrimitiveToFloat64();
    304 
    305   const Operator* ChangeTaggedSignedToInt32();
    306   const Operator* ChangeTaggedToInt32();
    307   const Operator* ChangeTaggedToUint32();
    308   const Operator* ChangeTaggedToFloat64();
    309   const Operator* ChangeInt31ToTaggedSigned();
    310   const Operator* ChangeInt32ToTagged();
    311   const Operator* ChangeUint32ToTagged();
    312   const Operator* ChangeFloat64ToTagged();
    313   const Operator* ChangeFloat64ToTaggedPointer();
    314   const Operator* ChangeTaggedToBit();
    315   const Operator* ChangeBitToTagged();
    316   const Operator* TruncateTaggedToWord32();
    317   const Operator* TruncateTaggedToFloat64();
    318   const Operator* TruncateTaggedToBit();
    319 
    320   const Operator* CheckIf();
    321   const Operator* CheckBounds();
    322   const Operator* CheckMaps(int map_input_count);
    323 
    324   const Operator* CheckHeapObject();
    325   const Operator* CheckNumber();
    326   const Operator* CheckSmi();
    327   const Operator* CheckString();
    328 
    329   const Operator* CheckedInt32Add();
    330   const Operator* CheckedInt32Sub();
    331   const Operator* CheckedInt32Div();
    332   const Operator* CheckedInt32Mod();
    333   const Operator* CheckedUint32Div();
    334   const Operator* CheckedUint32Mod();
    335   const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
    336   const Operator* CheckedInt32ToTaggedSigned();
    337   const Operator* CheckedUint32ToInt32();
    338   const Operator* CheckedUint32ToTaggedSigned();
    339   const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode);
    340   const Operator* CheckedTaggedSignedToInt32();
    341   const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
    342   const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
    343   const Operator* CheckedTaggedToTaggedSigned();
    344   const Operator* CheckedTaggedToTaggedPointer();
    345   const Operator* CheckedTruncateTaggedToWord32();
    346 
    347   const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
    348   const Operator* CheckTaggedHole();
    349   const Operator* ConvertTaggedHoleToUndefined();
    350 
    351   const Operator* ObjectIsCallable();
    352   const Operator* ObjectIsNumber();
    353   const Operator* ObjectIsReceiver();
    354   const Operator* ObjectIsSmi();
    355   const Operator* ObjectIsString();
    356   const Operator* ObjectIsUndetectable();
    357 
    358   // array-buffer-was-neutered buffer
    359   const Operator* ArrayBufferWasNeutered();
    360 
    361   // ensure-writable-fast-elements object, elements
    362   const Operator* EnsureWritableFastElements();
    363 
    364   // maybe-grow-fast-elements object, elements, index, length
    365   const Operator* MaybeGrowFastElements(GrowFastElementsFlags flags);
    366 
    367   // transition-elements-kind object, from-map, to-map
    368   const Operator* TransitionElementsKind(ElementsTransition transition);
    369 
    370   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
    371 
    372   const Operator* LoadField(FieldAccess const&);
    373   const Operator* StoreField(FieldAccess const&);
    374 
    375   // load-buffer buffer, offset, length
    376   const Operator* LoadBuffer(BufferAccess);
    377 
    378   // store-buffer buffer, offset, length, value
    379   const Operator* StoreBuffer(BufferAccess);
    380 
    381   // load-element [base + index]
    382   const Operator* LoadElement(ElementAccess const&);
    383 
    384   // store-element [base + index], value
    385   const Operator* StoreElement(ElementAccess const&);
    386 
    387   // load-typed-element buffer, [base + external + index]
    388   const Operator* LoadTypedElement(ExternalArrayType const&);
    389 
    390   // store-typed-element buffer, [base + external + index], value
    391   const Operator* StoreTypedElement(ExternalArrayType const&);
    392 
    393  private:
    394   Zone* zone() const { return zone_; }
    395 
    396   const SimplifiedOperatorGlobalCache& cache_;
    397   Zone* const zone_;
    398 
    399   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
    400 };
    401 
    402 }  // namespace compiler
    403 }  // namespace internal
    404 }  // namespace v8
    405 
    406 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
    407