HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Nougat 7.0
|
7.0.0_r31
下载
查看原文件
收藏
根目录
external
v8
test
unittests
compiler
node-test-utils.cc
// Copyright 2014 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "test/unittests/compiler/node-test-utils.h" #include
#include "src/assembler.h" #include "src/compiler/common-operator.h" #include "src/compiler/js-operator.h" #include "src/compiler/node-properties.h" #include "src/compiler/simplified-operator.h" #include "src/handles-inl.h" #include "src/objects.h" using testing::_; using testing::MakeMatcher; using testing::MatcherInterface; using testing::MatchResultListener; using testing::StringMatchResultListener; namespace v8 { namespace internal { bool operator==(Handle
const& lhs, Handle
const& rhs) { return lhs.is_identical_to(rhs); } namespace compiler { namespace { template
bool PrintMatchAndExplain(const T& value, const std::string& value_name, const Matcher
& value_matcher, MatchResultListener* listener) { StringMatchResultListener value_listener; if (!value_matcher.MatchAndExplain(value, &value_listener)) { *listener << "whose " << value_name << " " << value << " doesn't match"; if (value_listener.str() != "") { *listener << ", " << value_listener.str(); } return false; } return true; } class NodeMatcher : public MatcherInterface
{ public: explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {} void DescribeTo(std::ostream* os) const override { *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const override { if (node == NULL) { *listener << "which is NULL"; return false; } if (node->opcode() != opcode_) { *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode()) << " but should have been " << IrOpcode::Mnemonic(opcode_); return false; } return true; } private: const IrOpcode::Value opcode_; }; class IsBranchMatcher final : public NodeMatcher { public: IsBranchMatcher(const Matcher
& value_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kBranch), value_matcher_(value_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
value_matcher_; const Matcher
control_matcher_; }; class IsSwitchMatcher final : public NodeMatcher { public: IsSwitchMatcher(const Matcher
& value_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kSwitch), value_matcher_(value_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
value_matcher_; const Matcher
control_matcher_; }; class IsIfValueMatcher final : public NodeMatcher { public: IsIfValueMatcher(const Matcher
& value_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kIfValue), value_matcher_(value_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node->op()), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
value_matcher_; const Matcher
control_matcher_; }; class IsControl1Matcher final : public NodeMatcher { public: IsControl1Matcher(IrOpcode::Value opcode, const Matcher
& control_matcher) : NodeMatcher(opcode), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
control_matcher_; }; class IsControl2Matcher final : public NodeMatcher { public: IsControl2Matcher(IrOpcode::Value opcode, const Matcher
& control0_matcher, const Matcher
& control1_matcher) : NodeMatcher(opcode), control0_matcher_(control0_matcher), control1_matcher_(control1_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose control0 ("; control0_matcher_.DescribeTo(os); *os << ") and control1 ("; control1_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), "control0", control0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), "control1", control1_matcher_, listener)); } private: const Matcher
control0_matcher_; const Matcher
control1_matcher_; }; class IsControl3Matcher final : public NodeMatcher { public: IsControl3Matcher(IrOpcode::Value opcode, const Matcher
& control0_matcher, const Matcher
& control1_matcher, const Matcher
& control2_matcher) : NodeMatcher(opcode), control0_matcher_(control0_matcher), control1_matcher_(control1_matcher), control2_matcher_(control2_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose control0 ("; control0_matcher_.DescribeTo(os); *os << ") and control1 ("; control1_matcher_.DescribeTo(os); *os << ") and control2 ("; control2_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0), "control0", control0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1), "control1", control1_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node, 2), "control2", control2_matcher_, listener)); } private: const Matcher
control0_matcher_; const Matcher
control1_matcher_; const Matcher
control2_matcher_; }; class IsBeginRegionMatcher final : public NodeMatcher { public: explicit IsBeginRegionMatcher(const Matcher
& effect_matcher) : NodeMatcher(IrOpcode::kBeginRegion), effect_matcher_(effect_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose effect ("; effect_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener)); } private: const Matcher
effect_matcher_; }; class IsFinishRegionMatcher final : public NodeMatcher { public: IsFinishRegionMatcher(const Matcher
& value_matcher, const Matcher
& effect_matcher) : NodeMatcher(IrOpcode::kFinishRegion), value_matcher_(value_matcher), effect_matcher_(effect_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ") and effect ("; effect_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener)); } private: const Matcher
value_matcher_; const Matcher
effect_matcher_; }; class IsReturnMatcher final : public NodeMatcher { public: IsReturnMatcher(const Matcher
& value_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kReturn), value_matcher_(value_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ") and effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
value_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsTerminateMatcher final : public NodeMatcher { public: IsTerminateMatcher(const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kTerminate), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
effect_matcher_; const Matcher
control_matcher_; }; template
class IsConstantMatcher final : public NodeMatcher { public: IsConstantMatcher(IrOpcode::Value opcode, const Matcher
& value_matcher) : NodeMatcher(opcode), value_matcher_(value_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose value ("; value_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "value", value_matcher_, listener)); } private: const Matcher
value_matcher_; }; class IsSelectMatcher final : public NodeMatcher { public: IsSelectMatcher(const Matcher
& type_matcher, const Matcher
& value0_matcher, const Matcher
& value1_matcher, const Matcher
& value2_matcher) : NodeMatcher(IrOpcode::kSelect), type_matcher_(type_matcher), value0_matcher_(value0_matcher), value1_matcher_(value1_matcher), value2_matcher_(value2_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose representation ("; type_matcher_.DescribeTo(os); *os << "), value0 ("; value0_matcher_.DescribeTo(os); *os << "), value1 ("; value1_matcher_.DescribeTo(os); *os << ") and value2 ("; value2_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return ( NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(SelectParametersOf(node->op()).representation(), "representation", type_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0", value0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1", value1_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value2", value2_matcher_, listener)); } private: const Matcher
type_matcher_; const Matcher
value0_matcher_; const Matcher
value1_matcher_; const Matcher
value2_matcher_; }; class IsPhiMatcher final : public NodeMatcher { public: IsPhiMatcher(const Matcher
& type_matcher, const Matcher
& value0_matcher, const Matcher
& value1_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kPhi), type_matcher_(type_matcher), value0_matcher_(value0_matcher), value1_matcher_(value1_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose representation ("; type_matcher_.DescribeTo(os); *os << "), value0 ("; value0_matcher_.DescribeTo(os); *os << "), value1 ("; value1_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(PhiRepresentationOf(node->op()), "representation", type_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0", value0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1", value1_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
type_matcher_; const Matcher
value0_matcher_; const Matcher
value1_matcher_; const Matcher
control_matcher_; }; class IsPhi2Matcher final : public NodeMatcher { public: IsPhi2Matcher(const Matcher
& type_matcher, const Matcher
& value0_matcher, const Matcher
& value1_matcher, const Matcher
& value2_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kPhi), type_matcher_(type_matcher), value0_matcher_(value0_matcher), value1_matcher_(value1_matcher), value2_matcher_(value2_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose representation ("; type_matcher_.DescribeTo(os); *os << "), value0 ("; value0_matcher_.DescribeTo(os); *os << "), value1 ("; value1_matcher_.DescribeTo(os); *os << "), value2 ("; value2_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(PhiRepresentationOf(node->op()), "representation", type_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "value0", value0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value1", value1_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value2", value2_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
type_matcher_; const Matcher
value0_matcher_; const Matcher
value1_matcher_; const Matcher
value2_matcher_; const Matcher
control_matcher_; }; class IsEffectPhiMatcher final : public NodeMatcher { public: IsEffectPhiMatcher(const Matcher
& effect0_matcher, const Matcher
& effect1_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kEffectPhi), effect0_matcher_(effect0_matcher), effect1_matcher_(effect1_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << "), effect0 ("; effect0_matcher_.DescribeTo(os); *os << "), effect1 ("; effect1_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0), "effect0", effect0_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1), "effect1", effect1_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
effect0_matcher_; const Matcher
effect1_matcher_; const Matcher
control_matcher_; }; class IsEffectSetMatcher final : public NodeMatcher { public: IsEffectSetMatcher(const Matcher
& effect0_matcher, const Matcher
& effect1_matcher) : NodeMatcher(IrOpcode::kEffectSet), effect0_matcher_(effect0_matcher), effect1_matcher_(effect1_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << "), effect0 ("; effect0_matcher_.DescribeTo(os); *os << ") and effect1 ("; effect1_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { if (!NodeMatcher::MatchAndExplain(node, listener)) return false; Node* effect0 = NodeProperties::GetEffectInput(node, 0); Node* effect1 = NodeProperties::GetEffectInput(node, 1); { // Try matching in the reverse order first. StringMatchResultListener value_listener; if (effect0_matcher_.MatchAndExplain(effect1, &value_listener) && effect1_matcher_.MatchAndExplain(effect0, &value_listener)) { return true; } } return PrintMatchAndExplain(effect0, "effect0", effect0_matcher_, listener) && PrintMatchAndExplain(effect1, "effect1", effect1_matcher_, listener); } private: const Matcher
effect0_matcher_; const Matcher
effect1_matcher_; }; class IsProjectionMatcher final : public NodeMatcher { public: IsProjectionMatcher(const Matcher
& index_matcher, const Matcher
& base_matcher) : NodeMatcher(IrOpcode::kProjection), index_matcher_(index_matcher), base_matcher_(base_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose index ("; index_matcher_.DescribeTo(os); *os << ") and base ("; base_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "index", index_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener)); } private: const Matcher
index_matcher_; const Matcher
base_matcher_; }; class IsCallMatcher final : public NodeMatcher { public: IsCallMatcher(const Matcher
& descriptor_matcher, const std::vector
>& value_matchers, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kCall), descriptor_matcher_(descriptor_matcher), value_matchers_(value_matchers), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); for (size_t i = 0; i < value_matchers_.size(); ++i) { if (i == 0) { *os << " whose value0 ("; } else { *os << "), value" << i << " ("; } value_matchers_[i].DescribeTo(os); } *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { if (!NodeMatcher::MatchAndExplain(node, listener) || !PrintMatchAndExplain(OpParameter
(node), "descriptor", descriptor_matcher_, listener)) { return false; } for (size_t i = 0; i < value_matchers_.size(); ++i) { std::ostringstream ost; ost << "value" << i; if (!PrintMatchAndExplain( NodeProperties::GetValueInput(node, static_cast
(i)), ost.str(), value_matchers_[i], listener)) { return false; } } Node* effect_node = nullptr; Node* control_node = nullptr; if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { effect_node = NodeProperties::GetEffectInput(node); } if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { control_node = NodeProperties::GetControlInput(node); } return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, listener) && PrintMatchAndExplain(control_node, "control", control_matcher_, listener)); } private: const Matcher
descriptor_matcher_; const std::vector
> value_matchers_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsTailCallMatcher final : public NodeMatcher { public: IsTailCallMatcher(const Matcher
& descriptor_matcher, const std::vector
>& value_matchers, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kTailCall), descriptor_matcher_(descriptor_matcher), value_matchers_(value_matchers), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); for (size_t i = 0; i < value_matchers_.size(); ++i) { if (i == 0) { *os << " whose value0 ("; } else { *os << "), value" << i << " ("; } value_matchers_[i].DescribeTo(os); } *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { if (!NodeMatcher::MatchAndExplain(node, listener) || !PrintMatchAndExplain(OpParameter
(node), "descriptor", descriptor_matcher_, listener)) { return false; } for (size_t i = 0; i < value_matchers_.size(); ++i) { std::ostringstream ost; ost << "value" << i; if (!PrintMatchAndExplain( NodeProperties::GetValueInput(node, static_cast
(i)), ost.str(), value_matchers_[i], listener)) { return false; } } Node* effect_node = nullptr; Node* control_node = nullptr; if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { effect_node = NodeProperties::GetEffectInput(node); } if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { control_node = NodeProperties::GetControlInput(node); } return (PrintMatchAndExplain(effect_node, "effect", effect_matcher_, listener) && PrintMatchAndExplain(control_node, "control", control_matcher_, listener)); } private: const Matcher
descriptor_matcher_; const std::vector
> value_matchers_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsReferenceEqualMatcher final : public NodeMatcher { public: IsReferenceEqualMatcher(const Matcher
& type_matcher, const Matcher
& lhs_matcher, const Matcher
& rhs_matcher) : NodeMatcher(IrOpcode::kReferenceEqual), type_matcher_(type_matcher), lhs_matcher_(lhs_matcher), rhs_matcher_(rhs_matcher) {} bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && // TODO(bmeurer): The type parameter is currently ignored. PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", lhs_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", rhs_matcher_, listener)); } private: const Matcher
type_matcher_; const Matcher
lhs_matcher_; const Matcher
rhs_matcher_; }; class IsAllocateMatcher final : public NodeMatcher { public: IsAllocateMatcher(const Matcher
& size_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kAllocate), size_matcher_(size_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "size", size_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
size_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsLoadFieldMatcher final : public NodeMatcher { public: IsLoadFieldMatcher(const Matcher
& access_matcher, const Matcher
& base_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kLoadField), access_matcher_(access_matcher), base_matcher_(base_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
base_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsStoreFieldMatcher final : public NodeMatcher { public: IsStoreFieldMatcher(const Matcher
& access_matcher, const Matcher
& base_matcher, const Matcher
& value_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kStoreField), access_matcher_(access_matcher), base_matcher_(base_matcher), value_matcher_(value_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), value ("; value_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
base_matcher_; const Matcher
value_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsLoadBufferMatcher final : public NodeMatcher { public: IsLoadBufferMatcher(const Matcher
& access_matcher, const Matcher
& buffer_matcher, const Matcher
& offset_matcher, const Matcher
& length_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kLoadBuffer), access_matcher_(access_matcher), buffer_matcher_(buffer_matcher), offset_matcher_(offset_matcher), length_matcher_(length_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), buffer ("; buffer_matcher_.DescribeTo(os); *os << "), offset ("; offset_matcher_.DescribeTo(os); *os << "), length ("; length_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(BufferAccessOf(node->op()), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "buffer", buffer_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "offset", offset_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "length", length_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
buffer_matcher_; const Matcher
offset_matcher_; const Matcher
length_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsStoreBufferMatcher final : public NodeMatcher { public: IsStoreBufferMatcher(const Matcher
& access_matcher, const Matcher
& buffer_matcher, const Matcher
& offset_matcher, const Matcher
& length_matcher, const Matcher
& value_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kStoreBuffer), access_matcher_(access_matcher), buffer_matcher_(buffer_matcher), offset_matcher_(offset_matcher), length_matcher_(length_matcher), value_matcher_(value_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), buffer ("; buffer_matcher_.DescribeTo(os); *os << "), offset ("; offset_matcher_.DescribeTo(os); *os << "), length ("; length_matcher_.DescribeTo(os); *os << "), value ("; value_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(BufferAccessOf(node->op()), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "buffer", buffer_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "offset", offset_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "length", length_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
buffer_matcher_; const Matcher
offset_matcher_; const Matcher
length_matcher_; const Matcher
value_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsLoadElementMatcher final : public NodeMatcher { public: IsLoadElementMatcher(const Matcher
& access_matcher, const Matcher
& base_matcher, const Matcher
& index_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kLoadElement), access_matcher_(access_matcher), base_matcher_(base_matcher), index_matcher_(index_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), index ("; index_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "index", index_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
base_matcher_; const Matcher
index_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsStoreElementMatcher final : public NodeMatcher { public: IsStoreElementMatcher(const Matcher
& access_matcher, const Matcher
& base_matcher, const Matcher
& index_matcher, const Matcher
& value_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kStoreElement), access_matcher_(access_matcher), base_matcher_(base_matcher), index_matcher_(index_matcher), value_matcher_(value_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), index ("; index_matcher_.DescribeTo(os); *os << "), value ("; value_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "index", index_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value", value_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
base_matcher_; const Matcher
index_matcher_; const Matcher
value_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsLoadMatcher final : public NodeMatcher { public: IsLoadMatcher(const Matcher
& rep_matcher, const Matcher
& base_matcher, const Matcher
& index_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kLoad), rep_matcher_(rep_matcher), base_matcher_(base_matcher), index_matcher_(index_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose rep ("; rep_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), index ("; index_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { Node* effect_node = nullptr; Node* control_node = nullptr; if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { effect_node = NodeProperties::GetEffectInput(node); } if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { control_node = NodeProperties::GetControlInput(node); } return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "rep", rep_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "index", index_matcher_, listener) && PrintMatchAndExplain(effect_node, "effect", effect_matcher_, listener) && PrintMatchAndExplain(control_node, "control", control_matcher_, listener)); } private: const Matcher
rep_matcher_; const Matcher
base_matcher_; const Matcher
index_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsStoreMatcher final : public NodeMatcher { public: IsStoreMatcher(const Matcher
& rep_matcher, const Matcher
& base_matcher, const Matcher
& index_matcher, const Matcher
& value_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kStore), rep_matcher_(rep_matcher), base_matcher_(base_matcher), index_matcher_(index_matcher), value_matcher_(value_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose rep ("; rep_matcher_.DescribeTo(os); *os << "), base ("; base_matcher_.DescribeTo(os); *os << "), index ("; index_matcher_.DescribeTo(os); *os << "), value ("; value_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { Node* effect_node = nullptr; Node* control_node = nullptr; if (NodeProperties::FirstEffectIndex(node) < node->InputCount()) { effect_node = NodeProperties::GetEffectInput(node); } if (NodeProperties::FirstControlIndex(node) < node->InputCount()) { control_node = NodeProperties::GetControlInput(node); } return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "rep", rep_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "index", index_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2), "value", value_matcher_, listener) && PrintMatchAndExplain(effect_node, "effect", effect_matcher_, listener) && PrintMatchAndExplain(control_node, "control", control_matcher_, listener)); } private: const Matcher
rep_matcher_; const Matcher
base_matcher_; const Matcher
index_matcher_; const Matcher
value_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsToNumberMatcher final : public NodeMatcher { public: IsToNumberMatcher(const Matcher
& base_matcher, const Matcher
& context_matcher, const Matcher
& effect_matcher, const Matcher
& control_matcher) : NodeMatcher(IrOpcode::kJSToNumber), base_matcher_(base_matcher), context_matcher_(context_matcher), effect_matcher_(effect_matcher), control_matcher_(control_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose base ("; base_matcher_.DescribeTo(os); *os << "), context ("; context_matcher_.DescribeTo(os); *os << "), effect ("; effect_matcher_.DescribeTo(os); *os << ") and control ("; control_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base", base_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetContextInput(node), "context", context_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect", effect_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetControlInput(node), "control", control_matcher_, listener)); } private: const Matcher
base_matcher_; const Matcher
context_matcher_; const Matcher
effect_matcher_; const Matcher
control_matcher_; }; class IsLoadContextMatcher final : public NodeMatcher { public: IsLoadContextMatcher(const Matcher
& access_matcher, const Matcher
& context_matcher) : NodeMatcher(IrOpcode::kJSLoadContext), access_matcher_(access_matcher), context_matcher_(context_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose access ("; access_matcher_.DescribeTo(os); *os << ") and context ("; context_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(OpParameter
(node), "access", access_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetContextInput(node), "context", context_matcher_, listener)); } private: const Matcher
access_matcher_; const Matcher
context_matcher_; }; class IsBinopMatcher final : public NodeMatcher { public: IsBinopMatcher(IrOpcode::Value opcode, const Matcher
& lhs_matcher, const Matcher
& rhs_matcher) : NodeMatcher(opcode), lhs_matcher_(lhs_matcher), rhs_matcher_(rhs_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose lhs ("; lhs_matcher_.DescribeTo(os); *os << ") and rhs ("; rhs_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs", lhs_matcher_, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs", rhs_matcher_, listener)); } private: const Matcher
lhs_matcher_; const Matcher
rhs_matcher_; }; class IsUnopMatcher final : public NodeMatcher { public: IsUnopMatcher(IrOpcode::Value opcode, const Matcher
& input_matcher) : NodeMatcher(opcode), input_matcher_(input_matcher) {} void DescribeTo(std::ostream* os) const final { NodeMatcher::DescribeTo(os); *os << " whose input ("; input_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "input", input_matcher_, listener)); } private: const Matcher
input_matcher_; }; class IsParameterMatcher final : public NodeMatcher { public: explicit IsParameterMatcher(const Matcher
& index_matcher) : NodeMatcher(IrOpcode::kParameter), index_matcher_(index_matcher) {} void DescribeTo(std::ostream* os) const override { *os << "is a Parameter node with index("; index_matcher_.DescribeTo(os); *os << ")"; } bool MatchAndExplain(Node* node, MatchResultListener* listener) const final { return (NodeMatcher::MatchAndExplain(node, listener) && PrintMatchAndExplain(ParameterIndexOf(node->op()), "index", index_matcher_, listener)); } private: const Matcher
index_matcher_; }; } // namespace Matcher
IsDead() { return MakeMatcher(new NodeMatcher(IrOpcode::kDead)); } Matcher
IsEnd(const Matcher
& control0_matcher) { return MakeMatcher(new IsControl1Matcher(IrOpcode::kEnd, control0_matcher)); } Matcher
IsEnd(const Matcher
& control0_matcher, const Matcher
& control1_matcher) { return MakeMatcher(new IsControl2Matcher(IrOpcode::kEnd, control0_matcher, control1_matcher)); } Matcher
IsEnd(const Matcher
& control0_matcher, const Matcher
& control1_matcher, const Matcher
& control2_matcher) { return MakeMatcher(new IsControl3Matcher(IrOpcode::kEnd, control0_matcher, control1_matcher, control2_matcher)); } Matcher
IsBranch(const Matcher
& value_matcher, const Matcher
& control_matcher) { return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher)); } Matcher
IsMerge(const Matcher