| Index: src/compiler/common-operator.cc
|
| diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc
|
| index c9dea87acca2a6a0706a5904801606f6de49afe9..9d1aa609527b1a9c96dfe8bac5c7b2e299f3797c 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,173 +75,216 @@ 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));
|
| }
|
|
|
| @@ -265,15 +292,14 @@ const Operator* CommonOperatorBuilder::FrameState(
|
| 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,
|
| - descriptor) {}
|
| + IrOpcode::kCall, descriptor->properties(), mnemonic,
|
| + descriptor->InputCount() + descriptor->FrameStateCount(),
|
| + Operator::ZeroIfPure(descriptor->properties()),
|
| + Operator::ZeroIfPure(descriptor->properties()),
|
| + descriptor->ReturnCount(),
|
| + Operator::ZeroIfPure(descriptor->properties()), 0, descriptor) {}
|
|
|
| virtual void PrintParameter(std::ostream& os) const OVERRIDE {
|
| os << "[" << *parameter() << "]";
|
| @@ -284,8 +310,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
|
|
|