| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 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/common-operator.h" | 
|  | 6 | 
|  | 7 #include "src/assembler.h" | 
|  | 8 #include "src/base/lazy-instance.h" | 
|  | 9 #include "src/compiler/linkage.h" | 
|  | 10 #include "src/unique.h" | 
|  | 11 #include "src/zone.h" | 
|  | 12 | 
|  | 13 namespace v8 { | 
|  | 14 namespace internal { | 
|  | 15 namespace compiler { | 
|  | 16 | 
|  | 17 namespace { | 
|  | 18 | 
|  | 19 // TODO(turbofan): Use size_t instead of int here. | 
|  | 20 class ControlOperator : public Operator1<int> { | 
|  | 21  public: | 
|  | 22   ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, | 
|  | 23                   int outputs, int controls, const char* mnemonic) | 
|  | 24       : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, | 
|  | 25                        controls) {} | 
|  | 26 | 
|  | 27   virtual OStream& PrintParameter(OStream& os) const FINAL { return os; } | 
|  | 28 }; | 
|  | 29 | 
|  | 30 }  // namespace | 
|  | 31 | 
|  | 32 | 
|  | 33 // Specialization for static parameters of type {ExternalReference}. | 
|  | 34 template <> | 
|  | 35 struct StaticParameterTraits<ExternalReference> { | 
|  | 36   static OStream& PrintTo(OStream& os, ExternalReference reference) { | 
|  | 37     os << reference.address(); | 
|  | 38     // TODO(bmeurer): Move to operator<<(os, ExternalReference) | 
|  | 39     const Runtime::Function* function = | 
|  | 40         Runtime::FunctionForEntry(reference.address()); | 
|  | 41     if (function) { | 
|  | 42       os << " <" << function->name << ".entry>"; | 
|  | 43     } | 
|  | 44     return os; | 
|  | 45   } | 
|  | 46   static int HashCode(ExternalReference reference) { | 
|  | 47     return bit_cast<int>(static_cast<uint32_t>( | 
|  | 48         reinterpret_cast<uintptr_t>(reference.address()))); | 
|  | 49   } | 
|  | 50   static bool Equals(ExternalReference lhs, ExternalReference rhs) { | 
|  | 51     return lhs == rhs; | 
|  | 52   } | 
|  | 53 }; | 
|  | 54 | 
|  | 55 | 
|  | 56 #define SHARED_OP_LIST(V)               \ | 
|  | 57   V(Dead, Operator::kFoldable, 0, 0)    \ | 
|  | 58   V(End, Operator::kFoldable, 0, 1)     \ | 
|  | 59   V(Branch, Operator::kFoldable, 1, 1)  \ | 
|  | 60   V(IfTrue, Operator::kFoldable, 0, 1)  \ | 
|  | 61   V(IfFalse, Operator::kFoldable, 0, 1) \ | 
|  | 62   V(Throw, Operator::kFoldable, 1, 1)   \ | 
|  | 63   V(Return, Operator::kNoProperties, 1, 1) | 
|  | 64 | 
|  | 65 | 
|  | 66 struct CommonOperatorBuilderImpl FINAL { | 
|  | 67 #define SHARED(Name, properties, value_input_count, control_input_count)       \ | 
|  | 68   struct Name##Operator FINAL : public ControlOperator {                       \ | 
|  | 69     Name##Operator()                                                           \ | 
|  | 70         : ControlOperator(IrOpcode::k##Name, properties, value_input_count, 0, \ | 
|  | 71                           control_input_count, #Name) {}                       \ | 
|  | 72   };                                                                           \ | 
|  | 73   Name##Operator k##Name##Operator; | 
|  | 74   SHARED_OP_LIST(SHARED) | 
|  | 75 #undef SHARED | 
|  | 76 | 
|  | 77   struct ControlEffectOperator FINAL : public SimpleOperator { | 
|  | 78     ControlEffectOperator() | 
|  | 79         : SimpleOperator(IrOpcode::kControlEffect, Operator::kPure, 0, 0, | 
|  | 80                          "ControlEffect") {} | 
|  | 81   }; | 
|  | 82   ControlEffectOperator kControlEffectOperator; | 
|  | 83 }; | 
|  | 84 | 
|  | 85 | 
|  | 86 static base::LazyInstance<CommonOperatorBuilderImpl>::type kImpl = | 
|  | 87     LAZY_INSTANCE_INITIALIZER; | 
|  | 88 | 
|  | 89 | 
|  | 90 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone) | 
|  | 91     : impl_(kImpl.Get()), zone_(zone) {} | 
|  | 92 | 
|  | 93 | 
|  | 94 #define SHARED(Name, properties, value_input_count, control_input_count) \ | 
|  | 95   const Operator* CommonOperatorBuilder::Name() {                        \ | 
|  | 96     return &impl_.k##Name##Operator;                                     \ | 
|  | 97   } | 
|  | 98 SHARED_OP_LIST(SHARED) | 
|  | 99 #undef SHARED | 
|  | 100 | 
|  | 101 | 
|  | 102 const Operator* CommonOperatorBuilder::Start(int num_formal_parameters) { | 
|  | 103   // Outputs are formal parameters, plus context, receiver, and JSFunction. | 
|  | 104   const int value_output_count = num_formal_parameters + 3; | 
|  | 105   return new (zone()) ControlOperator(IrOpcode::kStart, Operator::kFoldable, 0, | 
|  | 106                                       value_output_count, 0, "Start"); | 
|  | 107 } | 
|  | 108 | 
|  | 109 | 
|  | 110 const Operator* CommonOperatorBuilder::Merge(int controls) { | 
|  | 111   return new (zone()) ControlOperator(IrOpcode::kMerge, Operator::kFoldable, 0, | 
|  | 112                                       0, controls, "Merge"); | 
|  | 113 } | 
|  | 114 | 
|  | 115 | 
|  | 116 const Operator* CommonOperatorBuilder::Loop(int controls) { | 
|  | 117   return new (zone()) ControlOperator(IrOpcode::kLoop, Operator::kFoldable, 0, | 
|  | 118                                       0, controls, "Loop"); | 
|  | 119 } | 
|  | 120 | 
|  | 121 | 
|  | 122 const Operator* CommonOperatorBuilder::Parameter(int index) { | 
|  | 123   return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1, | 
|  | 124                                      1, "Parameter", index); | 
|  | 125 } | 
|  | 126 | 
|  | 127 | 
|  | 128 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) { | 
|  | 129   return new (zone()) Operator1<int32_t>( | 
|  | 130       IrOpcode::kInt32Constant, Operator::kPure, 0, 1, "Int32Constant", value); | 
|  | 131 } | 
|  | 132 | 
|  | 133 | 
|  | 134 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) { | 
|  | 135   return new (zone()) Operator1<int64_t>( | 
|  | 136       IrOpcode::kInt64Constant, Operator::kPure, 0, 1, "Int64Constant", value); | 
|  | 137 } | 
|  | 138 | 
|  | 139 | 
|  | 140 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) { | 
|  | 141   return new (zone()) | 
|  | 142       Operator1<double>(IrOpcode::kFloat64Constant, Operator::kPure, 0, 1, | 
|  | 143                         "Float64Constant", value); | 
|  | 144 } | 
|  | 145 | 
|  | 146 | 
|  | 147 const Operator* CommonOperatorBuilder::ExternalConstant( | 
|  | 148     const ExternalReference& value) { | 
|  | 149   return new (zone()) | 
|  | 150       Operator1<ExternalReference>(IrOpcode::kExternalConstant, Operator::kPure, | 
|  | 151                                    0, 1, "ExternalConstant", value); | 
|  | 152 } | 
|  | 153 | 
|  | 154 | 
|  | 155 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { | 
|  | 156   return new (zone()) | 
|  | 157       Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1, | 
|  | 158                         "NumberConstant", value); | 
|  | 159 } | 
|  | 160 | 
|  | 161 | 
|  | 162 const Operator* CommonOperatorBuilder::HeapConstant( | 
|  | 163     const Unique<Object>& value) { | 
|  | 164   return new (zone()) Operator1<Unique<Object> >( | 
|  | 165       IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); | 
|  | 166 } | 
|  | 167 | 
|  | 168 | 
|  | 169 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { | 
|  | 170   DCHECK(arguments > 0);  // Disallow empty phis. | 
|  | 171   return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, | 
|  | 172                                              arguments, 1, "Phi", type); | 
|  | 173 } | 
|  | 174 | 
|  | 175 | 
|  | 176 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { | 
|  | 177   DCHECK(arguments > 0);  // Disallow empty phis. | 
|  | 178   return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, | 
|  | 179                                      0, "EffectPhi", arguments); | 
|  | 180 } | 
|  | 181 | 
|  | 182 | 
|  | 183 const Operator* CommonOperatorBuilder::ControlEffect() { | 
|  | 184   return &impl_.kControlEffectOperator; | 
|  | 185 } | 
|  | 186 | 
|  | 187 | 
|  | 188 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { | 
|  | 189   DCHECK(arguments > 0);  // Disallow empty value effects. | 
|  | 190   return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure, | 
|  | 191                                      arguments, 0, "ValueEffect"); | 
|  | 192 } | 
|  | 193 | 
|  | 194 | 
|  | 195 const Operator* CommonOperatorBuilder::Finish(int arguments) { | 
|  | 196   DCHECK(arguments > 0);  // Disallow empty finishes. | 
|  | 197   return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, | 
|  | 198                                      "Finish", arguments); | 
|  | 199 } | 
|  | 200 | 
|  | 201 | 
|  | 202 const Operator* CommonOperatorBuilder::StateValues(int arguments) { | 
|  | 203   return new (zone()) Operator1<int>(IrOpcode::kStateValues, Operator::kPure, | 
|  | 204                                      arguments, 1, "StateValues", arguments); | 
|  | 205 } | 
|  | 206 | 
|  | 207 | 
|  | 208 const Operator* CommonOperatorBuilder::FrameState( | 
|  | 209     BailoutId bailout_id, OutputFrameStateCombine combine) { | 
|  | 210   return new (zone()) Operator1<FrameStateCallInfo>( | 
|  | 211       IrOpcode::kFrameState, Operator::kPure, 4, 1, "FrameState", | 
|  | 212       FrameStateCallInfo(bailout_id, combine)); | 
|  | 213 } | 
|  | 214 | 
|  | 215 | 
|  | 216 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) { | 
|  | 217   class CallOperator FINAL : public Operator1<const CallDescriptor*> { | 
|  | 218    public: | 
|  | 219     // TODO(titzer): Operator still uses int, whereas CallDescriptor uses | 
|  | 220     // size_t. | 
|  | 221     CallOperator(const CallDescriptor* descriptor, const char* mnemonic) | 
|  | 222         : Operator1<const CallDescriptor*>( | 
|  | 223               IrOpcode::kCall, descriptor->properties(), | 
|  | 224               static_cast<int>(descriptor->InputCount() + | 
|  | 225                                descriptor->FrameStateCount()), | 
|  | 226               static_cast<int>(descriptor->ReturnCount()), mnemonic, | 
|  | 227               descriptor) {} | 
|  | 228 | 
|  | 229     virtual OStream& PrintParameter(OStream& os) const OVERRIDE { | 
|  | 230       return os << "[" << *parameter() << "]"; | 
|  | 231     } | 
|  | 232   }; | 
|  | 233   return new (zone()) CallOperator(descriptor, "Call"); | 
|  | 234 } | 
|  | 235 | 
|  | 236 | 
|  | 237 const Operator* CommonOperatorBuilder::Projection(size_t index) { | 
|  | 238   return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, | 
|  | 239                                         1, 1, "Projection", index); | 
|  | 240 } | 
|  | 241 | 
|  | 242 }  // namespace compiler | 
|  | 243 }  // namespace internal | 
|  | 244 }  // namespace v8 | 
| OLD | NEW | 
|---|