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_REPRESENTATION_CHANGE_H_
      6 #define V8_COMPILER_REPRESENTATION_CHANGE_H_
      7 
      8 #include "src/compiler/js-graph.h"
      9 #include "src/compiler/simplified-operator.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace compiler {
     14 
     15 class Truncation final {
     16  public:
     17   // Constructors.
     18   static Truncation None() { return Truncation(TruncationKind::kNone); }
     19   static Truncation Bool() { return Truncation(TruncationKind::kBool); }
     20   static Truncation Word32() { return Truncation(TruncationKind::kWord32); }
     21   static Truncation Word64() { return Truncation(TruncationKind::kWord64); }
     22   static Truncation Float32() { return Truncation(TruncationKind::kFloat32); }
     23   static Truncation Float64() { return Truncation(TruncationKind::kFloat64); }
     24   static Truncation Any() { return Truncation(TruncationKind::kAny); }
     25 
     26   static Truncation Generalize(Truncation t1, Truncation t2) {
     27     return Truncation(Generalize(t1.kind(), t2.kind()));
     28   }
     29 
     30   // Queries.
     31   bool TruncatesToWord32() const {
     32     return LessGeneral(kind_, TruncationKind::kWord32);
     33   }
     34   bool TruncatesNaNToZero() {
     35     return LessGeneral(kind_, TruncationKind::kWord32) ||
     36            LessGeneral(kind_, TruncationKind::kBool);
     37   }
     38   bool TruncatesUndefinedToZeroOrNaN() {
     39     return LessGeneral(kind_, TruncationKind::kFloat64) ||
     40            LessGeneral(kind_, TruncationKind::kWord64);
     41   }
     42 
     43   // Operators.
     44   bool operator==(Truncation other) const { return kind() == other.kind(); }
     45   bool operator!=(Truncation other) const { return !(*this == other); }
     46 
     47   // Debug utilities.
     48   const char* description() const;
     49   bool IsLessGeneralThan(Truncation other) {
     50     return LessGeneral(kind(), other.kind());
     51   }
     52 
     53  private:
     54   enum class TruncationKind : uint8_t {
     55     kNone,
     56     kBool,
     57     kWord32,
     58     kWord64,
     59     kFloat32,
     60     kFloat64,
     61     kAny
     62   };
     63 
     64   explicit Truncation(TruncationKind kind) : kind_(kind) {}
     65   TruncationKind kind() const { return kind_; }
     66 
     67   TruncationKind kind_;
     68 
     69   static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
     70   static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
     71 };
     72 
     73 
     74 // Contains logic related to changing the representation of values for constants
     75 // and other nodes, as well as lowering Simplified->Machine operators.
     76 // Eagerly folds any representation changes for constants.
     77 class RepresentationChanger final {
     78  public:
     79   RepresentationChanger(JSGraph* jsgraph, Isolate* isolate)
     80       : jsgraph_(jsgraph),
     81         isolate_(isolate),
     82         testing_type_errors_(false),
     83         type_error_(false) {}
     84 
     85   // Changes representation from {output_type} to {use_rep}. The {truncation}
     86   // parameter is only used for sanity checking - if the changer cannot figure
     87   // out signedness for the word32->float64 conversion, then we check that the
     88   // uses truncate to word32 (so they do not care about signedness).
     89   Node* GetRepresentationFor(Node* node, MachineRepresentation output_rep,
     90                              Type* output_type, MachineRepresentation use_rep,
     91                              Truncation truncation = Truncation::None());
     92   const Operator* Int32OperatorFor(IrOpcode::Value opcode);
     93   const Operator* Uint32OperatorFor(IrOpcode::Value opcode);
     94   const Operator* Float64OperatorFor(IrOpcode::Value opcode);
     95 
     96   MachineType TypeForBasePointer(const FieldAccess& access) {
     97     return access.tag() != 0 ? MachineType::AnyTagged()
     98                              : MachineType::Pointer();
     99   }
    100 
    101   MachineType TypeForBasePointer(const ElementAccess& access) {
    102     return access.tag() != 0 ? MachineType::AnyTagged()
    103                              : MachineType::Pointer();
    104   }
    105 
    106  private:
    107   JSGraph* jsgraph_;
    108   Isolate* isolate_;
    109 
    110   friend class RepresentationChangerTester;  // accesses the below fields.
    111 
    112   bool testing_type_errors_;  // If {true}, don't abort on a type error.
    113   bool type_error_;           // Set when a type error is detected.
    114 
    115   Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
    116                                    Type* output_type);
    117   Node* GetFloat32RepresentationFor(Node* node,
    118                                     MachineRepresentation output_rep,
    119                                     Type* output_type, Truncation truncation);
    120   Node* GetFloat64RepresentationFor(Node* node,
    121                                     MachineRepresentation output_rep,
    122                                     Type* output_type, Truncation truncation);
    123   Node* GetWord32RepresentationFor(Node* node, MachineRepresentation output_rep,
    124                                    Type* output_type);
    125   Node* GetBitRepresentationFor(Node* node, MachineRepresentation output_rep,
    126                                 Type* output_type);
    127   Node* GetWord64RepresentationFor(Node* node, MachineRepresentation output_rep,
    128                                    Type* output_type);
    129   Node* TypeError(Node* node, MachineRepresentation output_rep,
    130                   Type* output_type, MachineRepresentation use);
    131   Node* MakeTruncatedInt32Constant(double value);
    132   Node* InsertChangeFloat32ToFloat64(Node* node);
    133   Node* InsertChangeTaggedToFloat64(Node* node);
    134 
    135   JSGraph* jsgraph() const { return jsgraph_; }
    136   Isolate* isolate() const { return isolate_; }
    137   Factory* factory() const { return isolate()->factory(); }
    138   SimplifiedOperatorBuilder* simplified() { return jsgraph()->simplified(); }
    139   MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
    140 };
    141 
    142 }  // namespace compiler
    143 }  // namespace internal
    144 }  // namespace v8
    145 
    146 #endif  // V8_COMPILER_REPRESENTATION_CHANGE_H_
    147