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 #include "src/compiler/machine-operator.h"
      6 
      7 #include "src/base/lazy-instance.h"
      8 #include "src/compiler/opcodes.h"
      9 #include "src/compiler/operator.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace compiler {
     14 
     15 OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind) {
     16   switch (write_barrier_kind) {
     17     case kNoWriteBarrier:
     18       return os << "NoWriteBarrier";
     19     case kFullWriteBarrier:
     20       return os << "FullWriteBarrier";
     21   }
     22   UNREACHABLE();
     23   return os;
     24 }
     25 
     26 
     27 OStream& operator<<(OStream& os, const StoreRepresentation& rep) {
     28   return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
     29             << ")";
     30 }
     31 
     32 
     33 template <>
     34 struct StaticParameterTraits<StoreRepresentation> {
     35   static OStream& PrintTo(OStream& os, const StoreRepresentation& rep) {
     36     return os << rep;
     37   }
     38   static int HashCode(const StoreRepresentation& rep) {
     39     return rep.machine_type() + rep.write_barrier_kind();
     40   }
     41   static bool Equals(const StoreRepresentation& rep1,
     42                      const StoreRepresentation& rep2) {
     43     return rep1 == rep2;
     44   }
     45 };
     46 
     47 
     48 template <>
     49 struct StaticParameterTraits<LoadRepresentation> {
     50   static OStream& PrintTo(OStream& os, LoadRepresentation type) {  // NOLINT
     51     return os << type;
     52   }
     53   static int HashCode(LoadRepresentation type) { return type; }
     54   static bool Equals(LoadRepresentation lhs, LoadRepresentation rhs) {
     55     return lhs == rhs;
     56   }
     57 };
     58 
     59 
     60 #define PURE_OP_LIST(V)                                                       \
     61   V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
     62   V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     63   V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
     64   V(Word32Shl, Operator::kNoProperties, 2, 1)                                 \
     65   V(Word32Shr, Operator::kNoProperties, 2, 1)                                 \
     66   V(Word32Sar, Operator::kNoProperties, 2, 1)                                 \
     67   V(Word32Ror, Operator::kNoProperties, 2, 1)                                 \
     68   V(Word32Equal, Operator::kCommutative, 2, 1)                                \
     69   V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
     70   V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     71   V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
     72   V(Word64Shl, Operator::kNoProperties, 2, 1)                                 \
     73   V(Word64Shr, Operator::kNoProperties, 2, 1)                                 \
     74   V(Word64Sar, Operator::kNoProperties, 2, 1)                                 \
     75   V(Word64Ror, Operator::kNoProperties, 2, 1)                                 \
     76   V(Word64Equal, Operator::kCommutative, 2, 1)                                \
     77   V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     78   V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
     79     2)                                                                        \
     80   V(Int32Sub, Operator::kNoProperties, 2, 1)                                  \
     81   V(Int32SubWithOverflow, Operator::kNoProperties, 2, 2)                      \
     82   V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     83   V(Int32Div, Operator::kNoProperties, 2, 1)                                  \
     84   V(Int32UDiv, Operator::kNoProperties, 2, 1)                                 \
     85   V(Int32Mod, Operator::kNoProperties, 2, 1)                                  \
     86   V(Int32UMod, Operator::kNoProperties, 2, 1)                                 \
     87   V(Int32LessThan, Operator::kNoProperties, 2, 1)                             \
     88   V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
     89   V(Uint32LessThan, Operator::kNoProperties, 2, 1)                            \
     90   V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 1)                     \
     91   V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     92   V(Int64Sub, Operator::kNoProperties, 2, 1)                                  \
     93   V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
     94   V(Int64Div, Operator::kNoProperties, 2, 1)                                  \
     95   V(Int64UDiv, Operator::kNoProperties, 2, 1)                                 \
     96   V(Int64Mod, Operator::kNoProperties, 2, 1)                                  \
     97   V(Int64UMod, Operator::kNoProperties, 2, 1)                                 \
     98   V(Int64LessThan, Operator::kNoProperties, 2, 1)                             \
     99   V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
    100   V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 1)                    \
    101   V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 1)                      \
    102   V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 1)                     \
    103   V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 1)                      \
    104   V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 1)                        \
    105   V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 1)                     \
    106   V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 1)                      \
    107   V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 1)                  \
    108   V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 1)                    \
    109   V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 1)                      \
    110   V(Float64Add, Operator::kCommutative, 2, 1)                                 \
    111   V(Float64Sub, Operator::kNoProperties, 2, 1)                                \
    112   V(Float64Mul, Operator::kCommutative, 2, 1)                                 \
    113   V(Float64Div, Operator::kNoProperties, 2, 1)                                \
    114   V(Float64Mod, Operator::kNoProperties, 2, 1)                                \
    115   V(Float64Sqrt, Operator::kNoProperties, 1, 1)                               \
    116   V(Float64Equal, Operator::kCommutative, 2, 1)                               \
    117   V(Float64LessThan, Operator::kNoProperties, 2, 1)                           \
    118   V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 1)
    119 
    120 
    121 #define MACHINE_TYPE_LIST(V) \
    122   V(MachFloat32)             \
    123   V(MachFloat64)             \
    124   V(MachInt8)                \
    125   V(MachUint8)               \
    126   V(MachInt16)               \
    127   V(MachUint16)              \
    128   V(MachInt32)               \
    129   V(MachUint32)              \
    130   V(MachInt64)               \
    131   V(MachUint64)              \
    132   V(MachAnyTagged)           \
    133   V(RepBit)                  \
    134   V(RepWord8)                \
    135   V(RepWord16)               \
    136   V(RepWord32)               \
    137   V(RepWord64)               \
    138   V(RepFloat32)              \
    139   V(RepFloat64)              \
    140   V(RepTagged)
    141 
    142 
    143 struct MachineOperatorBuilderImpl {
    144 #define PURE(Name, properties, input_count, output_count)                 \
    145   struct Name##Operator FINAL : public SimpleOperator {                   \
    146     Name##Operator()                                                      \
    147         : SimpleOperator(IrOpcode::k##Name, Operator::kPure | properties, \
    148                          input_count, output_count, #Name) {}             \
    149   };                                                                      \
    150   Name##Operator k##Name;
    151   PURE_OP_LIST(PURE)
    152 #undef PURE
    153 
    154 #define LOAD(Type)                                                            \
    155   struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {  \
    156     Load##Type##Operator()                                                    \
    157         : Operator1<LoadRepresentation>(                                      \
    158               IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, 2, 1, \
    159               "Load", k##Type) {}                                             \
    160   };                                                                          \
    161   Load##Type##Operator k##Load##Type;
    162   MACHINE_TYPE_LIST(LOAD)
    163 #undef LOAD
    164 
    165 #define STORE(Type)                                                           \
    166   struct Store##Type##Operator : public Operator1<StoreRepresentation> {      \
    167     explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)       \
    168         : Operator1<StoreRepresentation>(                                     \
    169               IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, 3, 0, \
    170               "Store", StoreRepresentation(k##Type, write_barrier_kind)) {}   \
    171   };                                                                          \
    172   struct Store##Type##NoWriteBarrier##Operator FINAL                          \
    173       : public Store##Type##Operator {                                        \
    174     Store##Type##NoWriteBarrier##Operator()                                   \
    175         : Store##Type##Operator(kNoWriteBarrier) {}                           \
    176   };                                                                          \
    177   struct Store##Type##FullWriteBarrier##Operator FINAL                        \
    178       : public Store##Type##Operator {                                        \
    179     Store##Type##FullWriteBarrier##Operator()                                 \
    180         : Store##Type##Operator(kFullWriteBarrier) {}                         \
    181   };                                                                          \
    182   Store##Type##NoWriteBarrier##Operator k##Store##Type##NoWriteBarrier;       \
    183   Store##Type##FullWriteBarrier##Operator k##Store##Type##FullWriteBarrier;
    184   MACHINE_TYPE_LIST(STORE)
    185 #undef STORE
    186 };
    187 
    188 
    189 static base::LazyInstance<MachineOperatorBuilderImpl>::type kImpl =
    190     LAZY_INSTANCE_INITIALIZER;
    191 
    192 
    193 MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
    194     : impl_(kImpl.Get()), word_(word) {
    195   DCHECK(word == kRepWord32 || word == kRepWord64);
    196 }
    197 
    198 
    199 #define PURE(Name, properties, input_count, output_count) \
    200   const Operator* MachineOperatorBuilder::Name() { return &impl_.k##Name; }
    201 PURE_OP_LIST(PURE)
    202 #undef PURE
    203 
    204 
    205 const Operator* MachineOperatorBuilder::Load(LoadRepresentation rep) {
    206   switch (rep) {
    207 #define LOAD(Type) \
    208   case k##Type:    \
    209     return &impl_.k##Load##Type;
    210     MACHINE_TYPE_LIST(LOAD)
    211 #undef LOAD
    212 
    213     default:
    214       break;
    215   }
    216   UNREACHABLE();
    217   return NULL;
    218 }
    219 
    220 
    221 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
    222   switch (rep.machine_type()) {
    223 #define STORE(Type)                                     \
    224   case k##Type:                                         \
    225     switch (rep.write_barrier_kind()) {                 \
    226       case kNoWriteBarrier:                             \
    227         return &impl_.k##Store##Type##NoWriteBarrier;   \
    228       case kFullWriteBarrier:                           \
    229         return &impl_.k##Store##Type##FullWriteBarrier; \
    230     }                                                   \
    231     break;
    232     MACHINE_TYPE_LIST(STORE)
    233 #undef STORE
    234 
    235     default:
    236       break;
    237   }
    238   UNREACHABLE();
    239   return NULL;
    240 }
    241 
    242 }  // namespace compiler
    243 }  // namespace internal
    244 }  // namespace v8
    245