Chromium Code Reviews| Index: src/compiler/common-operator.cc |
| diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc |
| index c9dea87acca2a6a0706a5904801606f6de49afe9..2880ea011baa50daa1148fd07d1a3f3979079288 100644 |
| --- a/src/compiler/common-operator.cc |
| +++ b/src/compiler/common-operator.cc |
| @@ -14,22 +14,6 @@ namespace v8 { |
| namespace internal { |
| namespace compiler { |
| -namespace { |
| - |
| -// TODO(turbofan): Use size_t instead of int here. |
| -class ControlOperator : public Operator1<int> { |
| - public: |
| - ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs, |
| - int outputs, int controls, const char* mnemonic) |
| - : Operator1<int>(opcode, properties, inputs, outputs, mnemonic, |
| - controls) {} |
| - |
| - virtual void PrintParameter(std::ostream& os) const FINAL {} |
| -}; |
| - |
| -} // namespace |
| - |
| - |
| std::ostream& operator<<(std::ostream& os, BranchHint hint) { |
| switch (hint) { |
| case BranchHint::kNone: |
| @@ -91,188 +75,235 @@ std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) { |
| } |
| -#define SHARED_OP_LIST(V) \ |
| - V(Dead, Operator::kFoldable, 0, 0) \ |
| - V(End, Operator::kFoldable, 0, 1) \ |
| - V(IfTrue, Operator::kFoldable, 0, 1) \ |
| - V(IfFalse, Operator::kFoldable, 0, 1) \ |
| - V(Throw, Operator::kFoldable, 1, 1) \ |
| - V(Return, Operator::kNoProperties, 1, 1) |
| - |
| - |
| -struct CommonOperatorBuilderImpl FINAL { |
| -#define SHARED(Name, properties, value_input_count, control_input_count) \ |
| - struct Name##Operator FINAL : public ControlOperator { \ |
| - Name##Operator() \ |
| - : ControlOperator(IrOpcode::k##Name, properties, value_input_count, 0, \ |
| - control_input_count, #Name) {} \ |
| - }; \ |
| +#define CACHED_OP_LIST(V) \ |
| + V(Dead, Operator::kFoldable, 0, 0, 0, 1) \ |
| + V(End, Operator::kFoldable, 0, 0, 1, 0) \ |
| + V(IfTrue, Operator::kFoldable, 0, 0, 1, 1) \ |
| + V(IfFalse, Operator::kFoldable, 0, 0, 1, 1) \ |
| + V(Throw, Operator::kFoldable, 1, 1, 1, 1) \ |
| + V(Return, Operator::kNoProperties, 1, 1, 1, 1) |
| + |
| + |
| +struct CommonOperatorGlobalCache FINAL { |
| +#define CACHED(Name, properties, value_input_count, effect_input_count, \ |
| + control_input_count, control_output_count) \ |
| + struct Name##Operator FINAL : public Operator { \ |
| + Name##Operator() \ |
| + : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \ |
| + effect_input_count, control_input_count, 0, 0, \ |
| + control_output_count) {} \ |
| + }; \ |
| Name##Operator k##Name##Operator; |
| - SHARED_OP_LIST(SHARED) |
| -#undef SHARED |
| + CACHED_OP_LIST(CACHED) |
| +#undef CACHED |
| }; |
| -static base::LazyInstance<CommonOperatorBuilderImpl>::type kImpl = |
| +static base::LazyInstance<CommonOperatorGlobalCache>::type kCache = |
| LAZY_INSTANCE_INITIALIZER; |
| CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone) |
| - : impl_(kImpl.Get()), zone_(zone) {} |
| + : cache_(kCache.Get()), zone_(zone) {} |
| -#define SHARED(Name, properties, value_input_count, control_input_count) \ |
| - const Operator* CommonOperatorBuilder::Name() { \ |
| - return &impl_.k##Name##Operator; \ |
| +#define CACHED(Name, properties, value_input_count, effect_input_count, \ |
| + control_input_count, control_output_count) \ |
| + const Operator* CommonOperatorBuilder::Name() { \ |
| + return &cache_.k##Name##Operator; \ |
| } |
| -SHARED_OP_LIST(SHARED) |
| -#undef SHARED |
| +CACHED_OP_LIST(CACHED) |
| +#undef CACHED |
| const Operator* CommonOperatorBuilder::Branch(BranchHint hint) { |
| return new (zone()) Operator1<BranchHint>( |
| - IrOpcode::kBranch, Operator::kFoldable, 1, 0, "Branch", hint); |
| + IrOpcode::kBranch, Operator::kFoldable, "Branch", 1, 0, 1, 0, 0, 2, hint); |
| } |
| const Operator* CommonOperatorBuilder::Start(int num_formal_parameters) { |
| // Outputs are formal parameters, plus context, receiver, and JSFunction. |
| const int value_output_count = num_formal_parameters + 3; |
| - return new (zone()) ControlOperator(IrOpcode::kStart, Operator::kFoldable, 0, |
| - value_output_count, 0, "Start"); |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kStart, Operator::kFoldable, // opcode |
| + "Start", // name |
| + 0, 0, 0, value_output_count, 1, 1); // counts |
| } |
| const Operator* CommonOperatorBuilder::Merge(int controls) { |
| - return new (zone()) ControlOperator(IrOpcode::kMerge, Operator::kFoldable, 0, |
| - 0, controls, "Merge"); |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kMerge, Operator::kFoldable, // opcode |
| + "Merge", // name |
| + 0, 0, controls, 0, 0, 1); // counts |
| } |
| const Operator* CommonOperatorBuilder::Loop(int controls) { |
| - return new (zone()) ControlOperator(IrOpcode::kLoop, Operator::kFoldable, 0, |
| - 0, controls, "Loop"); |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kLoop, Operator::kFoldable, // opcode |
| + "Loop", // name |
| + 0, 0, controls, 0, 0, 1); // counts |
| } |
| const Operator* CommonOperatorBuilder::Terminate(int effects) { |
| - return new (zone()) Operator1<int>(IrOpcode::kTerminate, |
| - Operator::kNoRead | Operator::kNoWrite, 0, |
| - 0, "Terminate", effects); |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kTerminate, Operator::kPure, // opcode |
| + "Terminate", // name |
| + 0, effects, 1, 0, 0, 1); // counts |
| } |
| const Operator* CommonOperatorBuilder::Parameter(int index) { |
| - return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1, |
| - 1, "Parameter", index); |
| + return new (zone()) Operator1<int>( // -- |
| + IrOpcode::kParameter, Operator::kPure, // opcode |
| + "Parameter", // name |
| + 1, 0, 0, 1, 0, 0, // counts |
| + index); // parameter |
| } |
| const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) { |
| - return new (zone()) Operator1<int32_t>( |
| - IrOpcode::kInt32Constant, Operator::kPure, 0, 1, "Int32Constant", value); |
| + return new (zone()) Operator1<int32_t>( // -- |
| + IrOpcode::kInt32Constant, Operator::kPure, // opcode |
| + "Int32Constant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) { |
| - return new (zone()) Operator1<int64_t>( |
| - IrOpcode::kInt64Constant, Operator::kPure, 0, 1, "Int64Constant", value); |
| + return new (zone()) Operator1<int64_t>( // -- |
| + IrOpcode::kInt64Constant, Operator::kPure, // opcode |
| + "Int64Constant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) { |
| return new (zone()) |
| - Operator1<float, base::bit_equal_to<float>, base::bit_hash<float>>( |
| - IrOpcode::kFloat32Constant, Operator::kPure, 0, 1, "Float32Constant", |
| - value); |
| + Operator1<float, base::bit_equal_to<float>, base::bit_hash<float>>( // -- |
| + IrOpcode::kFloat32Constant, Operator::kPure, // opcode |
| + "Float32Constant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) { |
| - return new (zone()) |
| - Operator1<double, base::bit_equal_to<double>, base::bit_hash<double>>( |
| - IrOpcode::kFloat64Constant, Operator::kPure, 0, 1, "Float64Constant", |
| - value); |
| + return new (zone()) Operator1<double, base::bit_equal_to<double>, |
| + base::bit_hash<double>>( // -- |
| + IrOpcode::kFloat64Constant, Operator::kPure, // opcode |
| + "Float64Constant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::ExternalConstant( |
| const ExternalReference& value) { |
| - return new (zone()) |
| - Operator1<ExternalReference>(IrOpcode::kExternalConstant, Operator::kPure, |
| - 0, 1, "ExternalConstant", value); |
| + return new (zone()) Operator1<ExternalReference>( // -- |
| + IrOpcode::kExternalConstant, Operator::kPure, // opcode |
| + "ExternalConstant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) { |
| - return new (zone()) |
| - Operator1<double, base::bit_equal_to<double>, base::bit_hash<double>>( |
| - IrOpcode::kNumberConstant, Operator::kPure, 0, 1, "NumberConstant", |
| - value); |
| + return new (zone()) Operator1<double, base::bit_equal_to<double>, |
| + base::bit_hash<double>>( // -- |
| + IrOpcode::kNumberConstant, Operator::kPure, // opcode |
| + "NumberConstant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::HeapConstant( |
| const Unique<HeapObject>& value) { |
| - return new (zone()) Operator1<Unique<HeapObject>>( |
| - IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value); |
| + return new (zone()) Operator1<Unique<HeapObject>>( // -- |
| + IrOpcode::kHeapConstant, Operator::kPure, // opcode |
| + "HeapConstant", // name |
| + 0, 0, 0, 1, 0, 0, // counts |
| + value); // parameter |
| } |
| const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) { |
| - DCHECK(arguments > 0); // Disallow empty phis. |
| - return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure, |
| - arguments, 1, "Phi", type); |
| + DCHECK(arguments > 0); // Disallow empty phis. |
| + return new (zone()) Operator1<MachineType>( // -- |
| + IrOpcode::kPhi, Operator::kPure, // opcode |
| + "Phi", // name |
| + arguments, 0, 1, 1, 0, 0, // counts |
| + type); // parameter |
| } |
| const Operator* CommonOperatorBuilder::EffectPhi(int arguments) { |
| - DCHECK(arguments > 0); // Disallow empty phis. |
| - return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0, |
| - 0, "EffectPhi", arguments); |
| + DCHECK(arguments > 0); // Disallow empty phis. |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kEffectPhi, Operator::kPure, // opcode |
| + "EffectPhi", // name |
| + 0, arguments, 1, 0, 1, 0); // counts |
| } |
| const Operator* CommonOperatorBuilder::ValueEffect(int arguments) { |
| - DCHECK(arguments > 0); // Disallow empty value effects. |
| - return new (zone()) Operator1<int>(IrOpcode::kValueEffect, Operator::kPure, |
| - arguments, 0, "ValueEffect", arguments); |
| + DCHECK(arguments > 0); // Disallow empty value effects. |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kValueEffect, Operator::kPure, // opcode |
| + "ValueEffect", // name |
| + arguments, 0, 0, 0, 1, 0); // counts |
| } |
| const Operator* CommonOperatorBuilder::Finish(int arguments) { |
| - DCHECK(arguments > 0); // Disallow empty finishes. |
| - return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1, |
| - "Finish", arguments); |
| + DCHECK(arguments > 0); // Disallow empty finishes. |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kFinish, Operator::kPure, // opcode |
| + "Finish", // name |
| + 1, arguments, 0, 1, 0, 0); // counts |
| } |
| const Operator* CommonOperatorBuilder::StateValues(int arguments) { |
| - return new (zone()) Operator1<int>(IrOpcode::kStateValues, Operator::kPure, |
| - arguments, 1, "StateValues", arguments); |
| + return new (zone()) Operator( // -- |
| + IrOpcode::kStateValues, Operator::kPure, // opcode |
| + "StateValues", // name |
| + arguments, 0, 0, 1, 0, 0); // counts |
| } |
| const Operator* CommonOperatorBuilder::FrameState( |
| FrameStateType type, BailoutId bailout_id, |
| OutputFrameStateCombine state_combine, MaybeHandle<JSFunction> jsfunction) { |
| - return new (zone()) Operator1<FrameStateCallInfo>( |
| - IrOpcode::kFrameState, Operator::kPure, 4, 1, "FrameState", |
| + return new (zone()) Operator1<FrameStateCallInfo>( // -- |
| + IrOpcode::kFrameState, Operator::kPure, // opcode |
| + "FrameState", // name |
| + 4, 0, 0, 1, 0, 0, // counts |
| FrameStateCallInfo(type, bailout_id, state_combine, jsfunction)); |
| } |
| +static inline size_t CE(Operator::Properties properties) { |
|
rossberg
2014/10/29 09:43:21
Nit: Make this a static private method of class Ca
titzer
2014/10/29 11:59:26
Added Operator::ZeroIfPure(Operator::Properties)
|
| + // TODO(titzer): this is ugly. |
| + return (properties & Operator::kPure) == Operator::kPure ? 0 : 1; |
| +} |
| + |
| + |
| const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) { |
| class CallOperator FINAL : public Operator1<const CallDescriptor*> { |
| public: |
| - // TODO(titzer): Operator still uses int, whereas CallDescriptor uses |
| - // size_t. |
| CallOperator(const CallDescriptor* descriptor, const char* mnemonic) |
| : Operator1<const CallDescriptor*>( |
| - IrOpcode::kCall, descriptor->properties(), |
| - static_cast<int>(descriptor->InputCount() + |
| - descriptor->FrameStateCount()), |
| - static_cast<int>(descriptor->ReturnCount()), mnemonic, |
| + IrOpcode::kCall, descriptor->properties(), mnemonic, |
| + descriptor->InputCount() + descriptor->FrameStateCount(), |
| + CE(descriptor->properties()), CE(descriptor->properties()), |
| + descriptor->ReturnCount(), CE(descriptor->properties()), 0, |
| descriptor) {} |
| virtual void PrintParameter(std::ostream& os) const OVERRIDE { |
| @@ -284,8 +315,11 @@ const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) { |
| const Operator* CommonOperatorBuilder::Projection(size_t index) { |
| - return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure, |
| - 1, 1, "Projection", index); |
| + return new (zone()) Operator1<size_t>( // -- |
| + IrOpcode::kProjection, Operator::kPure, // opcode |
| + "Projection", // name |
| + 1, 0, 0, 1, 0, 0, // counts |
| + index); // parameter |
| } |
| } // namespace compiler |