Commit 288a2fab authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[turbofan] classify branch nodes if they are safety checks

Bug: 
Change-Id: Ia5df528e7e2129a4c6e029b75279015836147c95
Reviewed-on: https://chromium-review.googlesource.com/881145
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50824}
parent 9569b052
......@@ -2982,7 +2982,7 @@ void BytecodeGraphBuilder::BuildJump() {
}
void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
NewBranch(condition);
NewBranch(condition, BranchHint::kNone, BranchKind::kNoSafetyCheck);
{
SubEnvironment sub_environment(this);
NewIfTrue();
......@@ -2992,7 +2992,7 @@ void BytecodeGraphBuilder::BuildJumpIf(Node* condition) {
}
void BytecodeGraphBuilder::BuildJumpIfNot(Node* condition) {
NewBranch(condition);
NewBranch(condition, BranchHint::kNone, BranchKind::kNoSafetyCheck);
{
SubEnvironment sub_environment(this);
NewIfFalse();
......@@ -3016,7 +3016,8 @@ void BytecodeGraphBuilder::BuildJumpIfNotEqual(Node* comperand) {
}
void BytecodeGraphBuilder::BuildJumpIfFalse() {
NewBranch(environment()->LookupAccumulator());
NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
BranchKind::kNoSafetyCheck);
{
SubEnvironment sub_environment(this);
NewIfFalse();
......@@ -3028,7 +3029,8 @@ void BytecodeGraphBuilder::BuildJumpIfFalse() {
}
void BytecodeGraphBuilder::BuildJumpIfTrue() {
NewBranch(environment()->LookupAccumulator());
NewBranch(environment()->LookupAccumulator(), BranchHint::kNone,
BranchKind::kNoSafetyCheck);
{
SubEnvironment sub_environment(this);
NewIfTrue();
......
......@@ -100,8 +100,9 @@ class BytecodeGraphBuilder {
Node* NewIfDefault() { return NewNode(common()->IfDefault()); }
Node* NewMerge() { return NewNode(common()->Merge(1), true); }
Node* NewLoop() { return NewNode(common()->Loop(1), true); }
Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
return NewNode(common()->Branch(hint), condition);
Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone,
BranchKind kind = BranchKind::kSafetyCheck) {
return NewNode(common()->Branch(hint, kind), condition);
}
Node* NewSwitch(Node* condition, int control_output_count) {
return NewNode(common()->Switch(control_output_count), condition);
......
......@@ -29,10 +29,24 @@ std::ostream& operator<<(std::ostream& os, BranchHint hint) {
UNREACHABLE();
}
std::ostream& operator<<(std::ostream& os, BranchOperatorInfo info) {
os << info.hint;
switch (info.kind) {
case BranchKind::kSafetyCheck:
return os << "|SafetyCheck";
case BranchKind::kNoSafetyCheck:
return os << "|NoSafetyCheck";
}
UNREACHABLE();
}
BranchHint BranchHintOf(const Operator* const op) {
const BranchOperatorInfo& BranchOperatorInfoOf(const Operator* const op) {
DCHECK_EQ(IrOpcode::kBranch, op->opcode());
return OpParameter<BranchHint>(op);
return OpParameter<BranchOperatorInfo>(op);
}
BranchHint BranchHintOf(const Operator* const op) {
return BranchOperatorInfoOf(op).hint;
}
int ValueInputCountOfReturn(Operator const* const op) {
......@@ -365,6 +379,14 @@ ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
#define CACHED_BRANCH_LIST(V) \
V(None, SafetyCheck) \
V(True, SafetyCheck) \
V(False, SafetyCheck) \
V(None, NoSafetyCheck) \
V(True, NoSafetyCheck) \
V(False, NoSafetyCheck)
#define CACHED_RETURN_LIST(V) \
V(1) \
V(2) \
......@@ -534,18 +556,20 @@ struct CommonOperatorGlobalCache final {
CACHED_RETURN_LIST(CACHED_RETURN)
#undef CACHED_RETURN
template <BranchHint kBranchHint>
struct BranchOperator final : public Operator1<BranchHint> {
template <BranchHint hint, BranchKind kind>
struct BranchOperator final : public Operator1<BranchOperatorInfo> {
BranchOperator()
: Operator1<BranchHint>( // --
: Operator1<BranchOperatorInfo>( // --
IrOpcode::kBranch, Operator::kKontrol, // opcode
"Branch", // name
1, 0, 1, 0, 0, 2, // counts
kBranchHint) {} // parameter
BranchOperatorInfo{hint, kind}) {} // parameter
};
BranchOperator<BranchHint::kNone> kBranchNoneOperator;
BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
#define CACHED_BRANCH(Hint, Kind) \
BranchOperator<BranchHint::k##Hint, BranchKind::k##Kind> \
kBranch##Hint##Kind##Operator;
CACHED_BRANCH_LIST(CACHED_BRANCH)
#undef CACHED_BRANCH
template <int kEffectInputCount>
struct EffectPhiOperator final : public Operator {
......@@ -806,16 +830,14 @@ const Operator* CommonOperatorBuilder::Return(int value_input_count) {
value_input_count + 1, 1, 1, 0, 0, 1); // counts
}
const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
switch (hint) {
case BranchHint::kNone:
return &cache_.kBranchNoneOperator;
case BranchHint::kTrue:
return &cache_.kBranchTrueOperator;
case BranchHint::kFalse:
return &cache_.kBranchFalseOperator;
const Operator* CommonOperatorBuilder::Branch(BranchHint hint,
BranchKind kind) {
#define CACHED_BRANCH(Hint, Kind) \
if (hint == BranchHint::k##Hint && kind == BranchKind::k##Kind) { \
return &cache_.kBranch##Hint##Kind##Operator; \
}
CACHED_BRANCH_LIST(CACHED_BRANCH)
#undef CACHED_BRANCH
UNREACHABLE();
}
......@@ -1412,6 +1434,7 @@ const Operator* CommonOperatorBuilder::DeadValue(MachineRepresentation rep) {
}
#undef COMMON_CACHED_OP_LIST
#undef CACHED_BRANCH_LIST
#undef CACHED_RETURN_LIST
#undef CACHED_END_LIST
#undef CACHED_EFFECT_PHI_LIST
......
......@@ -28,6 +28,12 @@ class Node;
// Prediction hint for branches.
enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
enum class BranchKind : uint8_t { kSafetyCheck, kNoSafetyCheck };
struct BranchOperatorInfo {
BranchHint hint;
BranchKind kind;
};
inline BranchHint NegateBranchHint(BranchHint hint) {
switch (hint) {
......@@ -45,6 +51,19 @@ inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchHint);
inline size_t hash_value(const BranchOperatorInfo& info) {
return base::hash_combine(info.hint, static_cast<size_t>(info.kind));
}
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchOperatorInfo);
inline bool operator==(const BranchOperatorInfo& a,
const BranchOperatorInfo& b) {
return a.hint == b.hint && a.kind == b.kind;
}
V8_EXPORT_PRIVATE const BranchOperatorInfo& BranchOperatorInfoOf(
const Operator* const);
V8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const);
// Helper function for return nodes, because returns have a hidden value input.
......@@ -355,7 +374,8 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const Operator* DeadValue(MachineRepresentation rep);
const Operator* Unreachable();
const Operator* End(size_t control_input_count);
const Operator* Branch(BranchHint = BranchHint::kNone);
const Operator* Branch(BranchHint = BranchHint::kNone,
BranchKind kind = BranchKind::kSafetyCheck);
const Operator* IfTrue();
const Operator* IfFalse();
const Operator* IfSuccess();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment