Simplify DeoptimizeKind usage in compiler/
With kLazy deopts gone, we can remove the stored DeoptimizeKind from Deoptimize nodes and all related spots - all Deoptimize nodes are eager deopts. Bug: v8:12765 Change-Id: I8e727e046c498198e50d9b7dba25442fb54f5da9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3568456 Auto-Submit: Jakob Linke <jgruber@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/main@{#79830}
This commit is contained in:
parent
b24896c6d7
commit
e36e6a8844
@ -870,23 +870,10 @@ Instruction* InstructionSelector::EmitWithContinuation(
|
||||
continuation_inputs_.push_back(g.Label(cont->false_block()));
|
||||
} else if (cont->IsDeoptimize()) {
|
||||
int immediate_args_count = 0;
|
||||
if (cont->has_extra_args()) {
|
||||
for (int i = 0; i < cont->extra_args_count(); i++) {
|
||||
InstructionOperand op = cont->extra_args()[i];
|
||||
continuation_inputs_.push_back(op);
|
||||
input_count++;
|
||||
if (op.IsImmediate()) {
|
||||
immediate_args_count++;
|
||||
} else {
|
||||
// All immediate args should be added last.
|
||||
DCHECK_EQ(immediate_args_count, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
opcode |= DeoptImmedArgsCountField::encode(immediate_args_count) |
|
||||
DeoptFrameStateOffsetField::encode(static_cast<int>(input_count));
|
||||
AppendDeoptimizeArguments(&continuation_inputs_, cont->kind(),
|
||||
cont->reason(), cont->node_id(), cont->feedback(),
|
||||
AppendDeoptimizeArguments(&continuation_inputs_, cont->reason(),
|
||||
cont->node_id(), cont->feedback(),
|
||||
FrameState{cont->frame_state()});
|
||||
} else if (cont->IsSet()) {
|
||||
continuation_outputs_.push_back(g.DefineAsRegister(cont->result()));
|
||||
@ -918,14 +905,12 @@ Instruction* InstructionSelector::EmitWithContinuation(
|
||||
}
|
||||
|
||||
void InstructionSelector::AppendDeoptimizeArguments(
|
||||
InstructionOperandVector* args, DeoptimizeKind kind,
|
||||
DeoptimizeReason reason, NodeId node_id, FeedbackSource const& feedback,
|
||||
FrameState frame_state) {
|
||||
InstructionOperandVector* args, DeoptimizeReason reason, NodeId node_id,
|
||||
FeedbackSource const& feedback, FrameState frame_state) {
|
||||
OperandGenerator g(this);
|
||||
FrameStateDescriptor* const descriptor = GetFrameStateDescriptor(frame_state);
|
||||
DCHECK_NE(DeoptimizeKind::kLazy, kind);
|
||||
int const state_id = sequence()->AddDeoptimizationEntry(
|
||||
descriptor, kind, reason, node_id, feedback);
|
||||
descriptor, DeoptimizeKind::kEager, reason, node_id, feedback);
|
||||
args->push_back(g.TempImmediate(state_id));
|
||||
StateObjectDeduplicator deduplicator(instruction_zone());
|
||||
AddInputsToFrameStateDescriptor(descriptor, frame_state, &g, &deduplicator,
|
||||
@ -1355,7 +1340,7 @@ void InstructionSelector::VisitControl(BasicBlock* block) {
|
||||
case BasicBlock::kDeoptimize: {
|
||||
DeoptimizeParameters p = DeoptimizeParametersOf(input->op());
|
||||
FrameState value{input->InputAt(0)};
|
||||
VisitDeoptimize(p.kind(), p.reason(), input->id(), p.feedback(), value);
|
||||
VisitDeoptimize(p.reason(), input->id(), p.feedback(), value);
|
||||
break;
|
||||
}
|
||||
case BasicBlock::kThrow:
|
||||
@ -3144,15 +3129,16 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
|
||||
void InstructionSelector::VisitDeoptimizeIf(Node* node) {
|
||||
DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
|
||||
FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
|
||||
kNotEqual, p.kind(), p.reason(), node->id(), p.feedback(),
|
||||
node->InputAt(1));
|
||||
kNotEqual, p.reason(), node->id(), p.feedback(),
|
||||
FrameState{node->InputAt(1)});
|
||||
VisitWordCompareZero(node, node->InputAt(0), &cont);
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
|
||||
DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
|
||||
FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
|
||||
kEqual, p.kind(), p.reason(), node->id(), p.feedback(), node->InputAt(1));
|
||||
kEqual, p.reason(), node->id(), p.feedback(),
|
||||
FrameState{node->InputAt(1)});
|
||||
VisitWordCompareZero(node, node->InputAt(0), &cont);
|
||||
}
|
||||
|
||||
@ -3180,14 +3166,12 @@ void InstructionSelector::EmitIdentity(Node* node) {
|
||||
SetRename(node, node->InputAt(0));
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitDeoptimize(DeoptimizeKind kind,
|
||||
DeoptimizeReason reason,
|
||||
void InstructionSelector::VisitDeoptimize(DeoptimizeReason reason,
|
||||
NodeId node_id,
|
||||
FeedbackSource const& feedback,
|
||||
FrameState frame_state) {
|
||||
InstructionOperandVector args(instruction_zone());
|
||||
AppendDeoptimizeArguments(&args, kind, reason, node_id, feedback,
|
||||
frame_state);
|
||||
AppendDeoptimizeArguments(&args, reason, node_id, feedback, frame_state);
|
||||
Emit(kArchDeoptimize, 0, nullptr, args.size(), &args.front(), 0, nullptr);
|
||||
}
|
||||
|
||||
|
@ -55,13 +55,21 @@ class FlagsContinuation final {
|
||||
}
|
||||
|
||||
// Creates a new flags continuation for an eager deoptimization exit.
|
||||
static FlagsContinuation ForDeoptimize(
|
||||
FlagsCondition condition, DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
NodeId node_id, FeedbackSource const& feedback, Node* frame_state,
|
||||
InstructionOperand* extra_args = nullptr, int extra_args_count = 0) {
|
||||
return FlagsContinuation(kFlags_deoptimize, condition, kind, reason,
|
||||
node_id, feedback, frame_state, extra_args,
|
||||
extra_args_count);
|
||||
static FlagsContinuation ForDeoptimize(FlagsCondition condition,
|
||||
DeoptimizeReason reason,
|
||||
NodeId node_id,
|
||||
FeedbackSource const& feedback,
|
||||
FrameState frame_state) {
|
||||
return FlagsContinuation(kFlags_deoptimize, condition, reason, node_id,
|
||||
feedback, frame_state);
|
||||
}
|
||||
static FlagsContinuation ForDeoptimizeForTesting(
|
||||
FlagsCondition condition, DeoptimizeReason reason, NodeId node_id,
|
||||
FeedbackSource const& feedback, Node* frame_state) {
|
||||
// test-instruction-scheduler.cc passes a dummy Node* as frame_state.
|
||||
// Contents don't matter as long as it's not nullptr.
|
||||
return FlagsContinuation(kFlags_deoptimize, condition, reason, node_id,
|
||||
feedback, frame_state);
|
||||
}
|
||||
|
||||
// Creates a new flags continuation for a boolean value.
|
||||
@ -90,10 +98,6 @@ class FlagsContinuation final {
|
||||
DCHECK(!IsNone());
|
||||
return condition_;
|
||||
}
|
||||
DeoptimizeKind kind() const {
|
||||
DCHECK(IsDeoptimize());
|
||||
return kind_;
|
||||
}
|
||||
DeoptimizeReason reason() const {
|
||||
DCHECK(IsDeoptimize());
|
||||
return reason_;
|
||||
@ -110,18 +114,6 @@ class FlagsContinuation final {
|
||||
DCHECK(IsDeoptimize());
|
||||
return frame_state_or_result_;
|
||||
}
|
||||
bool has_extra_args() const {
|
||||
DCHECK(IsDeoptimize());
|
||||
return extra_args_ != nullptr;
|
||||
}
|
||||
const InstructionOperand* extra_args() const {
|
||||
DCHECK(has_extra_args());
|
||||
return extra_args_;
|
||||
}
|
||||
int extra_args_count() const {
|
||||
DCHECK(has_extra_args());
|
||||
return extra_args_count_;
|
||||
}
|
||||
Node* result() const {
|
||||
DCHECK(IsSet() || IsSelect());
|
||||
return frame_state_or_result_;
|
||||
@ -207,19 +199,14 @@ class FlagsContinuation final {
|
||||
}
|
||||
|
||||
FlagsContinuation(FlagsMode mode, FlagsCondition condition,
|
||||
DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
NodeId node_id, FeedbackSource const& feedback,
|
||||
Node* frame_state, InstructionOperand* extra_args,
|
||||
int extra_args_count)
|
||||
DeoptimizeReason reason, NodeId node_id,
|
||||
FeedbackSource const& feedback, Node* frame_state)
|
||||
: mode_(mode),
|
||||
condition_(condition),
|
||||
kind_(kind),
|
||||
reason_(reason),
|
||||
node_id_(node_id),
|
||||
feedback_(feedback),
|
||||
frame_state_or_result_(frame_state),
|
||||
extra_args_(extra_args),
|
||||
extra_args_count_(extra_args_count) {
|
||||
frame_state_or_result_(frame_state) {
|
||||
DCHECK(mode == kFlags_deoptimize);
|
||||
DCHECK_NOT_NULL(frame_state);
|
||||
}
|
||||
@ -253,14 +240,11 @@ class FlagsContinuation final {
|
||||
|
||||
FlagsMode const mode_;
|
||||
FlagsCondition condition_;
|
||||
DeoptimizeKind kind_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
DeoptimizeReason reason_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
NodeId node_id_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
FeedbackSource feedback_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
Node* frame_state_or_result_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
// or mode_ == kFlags_set.
|
||||
InstructionOperand* extra_args_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
int extra_args_count_; // Only valid if mode_ == kFlags_deoptimize*
|
||||
BasicBlock* true_block_; // Only valid if mode_ == kFlags_branch*.
|
||||
BasicBlock* false_block_; // Only valid if mode_ == kFlags_branch*.
|
||||
TrapId trap_id_; // Only valid if mode_ == kFlags_trap.
|
||||
@ -501,8 +485,8 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
|
||||
}
|
||||
|
||||
void AppendDeoptimizeArguments(InstructionOperandVector* args,
|
||||
DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
NodeId node_id, FeedbackSource const& feedback,
|
||||
DeoptimizeReason reason, NodeId node_id,
|
||||
FeedbackSource const& feedback,
|
||||
FrameState frame_state);
|
||||
|
||||
void EmitTableSwitch(const SwitchInfo& sw,
|
||||
@ -637,9 +621,8 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
|
||||
void VisitGoto(BasicBlock* target);
|
||||
void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
|
||||
void VisitSwitch(Node* node, const SwitchInfo& sw);
|
||||
void VisitDeoptimize(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
NodeId node_id, FeedbackSource const& feedback,
|
||||
FrameState frame_state);
|
||||
void VisitDeoptimize(DeoptimizeReason reason, NodeId node_id,
|
||||
FeedbackSource const& feedback, FrameState frame_state);
|
||||
void VisitSelect(Node* node);
|
||||
void VisitReturn(Node* ret);
|
||||
void VisitThrow(Node* node);
|
||||
|
@ -333,9 +333,8 @@ Reduction BranchElimination::ReduceDeoptimizeConditional(Node* node) {
|
||||
// with the {control} node that already contains the right information.
|
||||
ReplaceWithValue(node, dead(), effect, control);
|
||||
} else {
|
||||
control = graph()->NewNode(
|
||||
common()->Deoptimize(p.kind(), p.reason(), p.feedback()), frame_state,
|
||||
effect, control);
|
||||
control = graph()->NewNode(common()->Deoptimize(p.reason(), p.feedback()),
|
||||
frame_state, effect, control);
|
||||
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), control);
|
||||
Revisit(graph()->end());
|
||||
|
@ -156,10 +156,9 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) {
|
||||
if (condition->opcode() == IrOpcode::kBooleanNot) {
|
||||
NodeProperties::ReplaceValueInput(node, condition->InputAt(0), 0);
|
||||
NodeProperties::ChangeOp(
|
||||
node,
|
||||
condition_is_true
|
||||
? common()->DeoptimizeIf(p.kind(), p.reason(), p.feedback())
|
||||
: common()->DeoptimizeUnless(p.kind(), p.reason(), p.feedback()));
|
||||
node, condition_is_true
|
||||
? common()->DeoptimizeIf(p.reason(), p.feedback())
|
||||
: common()->DeoptimizeUnless(p.reason(), p.feedback()));
|
||||
return Changed(node);
|
||||
}
|
||||
Decision const decision = DecideCondition(condition);
|
||||
@ -167,9 +166,8 @@ Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) {
|
||||
if (condition_is_true == (decision == Decision::kTrue)) {
|
||||
ReplaceWithValue(node, dead(), effect, control);
|
||||
} else {
|
||||
control = graph()->NewNode(
|
||||
common()->Deoptimize(p.kind(), p.reason(), p.feedback()), frame_state,
|
||||
effect, control);
|
||||
control = graph()->NewNode(common()->Deoptimize(p.reason(), p.feedback()),
|
||||
frame_state, effect, control);
|
||||
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), control);
|
||||
Revisit(graph()->end());
|
||||
|
@ -67,8 +67,7 @@ int ValueInputCountOfReturn(Operator const* const op) {
|
||||
}
|
||||
|
||||
bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
|
||||
return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason() &&
|
||||
lhs.feedback() == rhs.feedback();
|
||||
return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
|
||||
}
|
||||
|
||||
bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
|
||||
@ -77,11 +76,11 @@ bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
|
||||
|
||||
size_t hash_value(DeoptimizeParameters p) {
|
||||
FeedbackSource::Hash feebdack_hash;
|
||||
return base::hash_combine(p.kind(), p.reason(), feebdack_hash(p.feedback()));
|
||||
return base::hash_combine(p.reason(), feebdack_hash(p.feedback()));
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
|
||||
return os << p.kind() << ", " << p.reason() << ", " << p.feedback();
|
||||
return os << p.reason() << ", " << p.feedback();
|
||||
}
|
||||
|
||||
DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) {
|
||||
@ -713,7 +712,7 @@ struct CommonOperatorGlobalCache final {
|
||||
CACHED_LOOP_EXIT_VALUE_LIST(CACHED_LOOP_EXIT_VALUE)
|
||||
#undef CACHED_LOOP_EXIT_VALUE
|
||||
|
||||
template <DeoptimizeKind kKind, DeoptimizeReason kReason>
|
||||
template <DeoptimizeReason kReason>
|
||||
struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> {
|
||||
DeoptimizeOperator()
|
||||
: Operator1<DeoptimizeParameters>( // --
|
||||
@ -721,15 +720,14 @@ struct CommonOperatorGlobalCache final {
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
"Deoptimize", // name
|
||||
1, 1, 1, 0, 0, 1, // counts
|
||||
DeoptimizeParameters(kKind, kReason, FeedbackSource())) {}
|
||||
DeoptimizeParameters(kReason, FeedbackSource())) {}
|
||||
};
|
||||
#define CACHED_DEOPTIMIZE(Reason) \
|
||||
DeoptimizeOperator<DeoptimizeKind::kEager, DeoptimizeReason::k##Reason> \
|
||||
kDeoptimizeEager##Reason##Operator;
|
||||
#define CACHED_DEOPTIMIZE(Reason) \
|
||||
DeoptimizeOperator<DeoptimizeReason::k##Reason> kDeoptimize##Reason##Operator;
|
||||
CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
|
||||
#undef CACHED_DEOPTIMIZE
|
||||
|
||||
template <DeoptimizeKind kKind, DeoptimizeReason kReason>
|
||||
template <DeoptimizeReason kReason>
|
||||
struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> {
|
||||
DeoptimizeIfOperator()
|
||||
: Operator1<DeoptimizeParameters>( // --
|
||||
@ -737,15 +735,15 @@ struct CommonOperatorGlobalCache final {
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
"DeoptimizeIf", // name
|
||||
2, 1, 1, 0, 1, 1, // counts
|
||||
DeoptimizeParameters(kKind, kReason, FeedbackSource())) {}
|
||||
DeoptimizeParameters(kReason, FeedbackSource())) {}
|
||||
};
|
||||
#define CACHED_DEOPTIMIZE_IF(Reason) \
|
||||
DeoptimizeIfOperator<DeoptimizeKind::kEager, DeoptimizeReason::k##Reason> \
|
||||
kDeoptimizeIfEager##Reason##Operator;
|
||||
#define CACHED_DEOPTIMIZE_IF(Reason) \
|
||||
DeoptimizeIfOperator<DeoptimizeReason::k##Reason> \
|
||||
kDeoptimizeIf##Reason##Operator;
|
||||
CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
|
||||
#undef CACHED_DEOPTIMIZE_IF
|
||||
|
||||
template <DeoptimizeKind kKind, DeoptimizeReason kReason>
|
||||
template <DeoptimizeReason kReason>
|
||||
struct DeoptimizeUnlessOperator final
|
||||
: public Operator1<DeoptimizeParameters> {
|
||||
DeoptimizeUnlessOperator()
|
||||
@ -754,12 +752,11 @@ struct CommonOperatorGlobalCache final {
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
"DeoptimizeUnless", // name
|
||||
2, 1, 1, 0, 1, 1, // counts
|
||||
DeoptimizeParameters(kKind, kReason, FeedbackSource())) {}
|
||||
DeoptimizeParameters(kReason, FeedbackSource())) {}
|
||||
};
|
||||
#define CACHED_DEOPTIMIZE_UNLESS(Reason) \
|
||||
DeoptimizeUnlessOperator<DeoptimizeKind::kEager, \
|
||||
DeoptimizeReason::k##Reason> \
|
||||
kDeoptimizeUnlessEager##Reason##Operator;
|
||||
DeoptimizeUnlessOperator<DeoptimizeReason::k##Reason> \
|
||||
kDeoptimizeUnless##Reason##Operator;
|
||||
CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
|
||||
#undef CACHED_DEOPTIMIZE_UNLESS
|
||||
|
||||
@ -944,17 +941,15 @@ const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::Deoptimize(
|
||||
DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback) {
|
||||
DeoptimizeReason reason, FeedbackSource const& feedback) {
|
||||
#define CACHED_DEOPTIMIZE(Reason) \
|
||||
if (kind == DeoptimizeKind::kEager && \
|
||||
reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimizeEager##Reason##Operator; \
|
||||
if (reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimize##Reason##Operator; \
|
||||
}
|
||||
CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
|
||||
#undef CACHED_DEOPTIMIZE
|
||||
// Uncached
|
||||
DeoptimizeParameters parameter(kind, reason, feedback);
|
||||
DeoptimizeParameters parameter(reason, feedback);
|
||||
return zone()->New<Operator1<DeoptimizeParameters>>( // --
|
||||
IrOpcode::kDeoptimize, // opcodes
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
@ -964,17 +959,15 @@ const Operator* CommonOperatorBuilder::Deoptimize(
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::DeoptimizeIf(
|
||||
DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback) {
|
||||
DeoptimizeReason reason, FeedbackSource const& feedback) {
|
||||
#define CACHED_DEOPTIMIZE_IF(Reason) \
|
||||
if (kind == DeoptimizeKind::kEager && \
|
||||
reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimizeIfEager##Reason##Operator; \
|
||||
if (reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimizeIf##Reason##Operator; \
|
||||
}
|
||||
CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
|
||||
#undef CACHED_DEOPTIMIZE_IF
|
||||
// Uncached
|
||||
DeoptimizeParameters parameter(kind, reason, feedback);
|
||||
DeoptimizeParameters parameter(reason, feedback);
|
||||
return zone()->New<Operator1<DeoptimizeParameters>>( // --
|
||||
IrOpcode::kDeoptimizeIf, // opcode
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
@ -984,17 +977,15 @@ const Operator* CommonOperatorBuilder::DeoptimizeIf(
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::DeoptimizeUnless(
|
||||
DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback) {
|
||||
DeoptimizeReason reason, FeedbackSource const& feedback) {
|
||||
#define CACHED_DEOPTIMIZE_UNLESS(Reason) \
|
||||
if (kind == DeoptimizeKind::kEager && \
|
||||
reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimizeUnlessEager##Reason##Operator; \
|
||||
if (reason == DeoptimizeReason::k##Reason && !feedback.IsValid()) { \
|
||||
return &cache_.kDeoptimizeUnless##Reason##Operator; \
|
||||
}
|
||||
CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
|
||||
#undef CACHED_DEOPTIMIZE_UNLESS
|
||||
// Uncached
|
||||
DeoptimizeParameters parameter(kind, reason, feedback);
|
||||
DeoptimizeParameters parameter(reason, feedback);
|
||||
return zone()->New<Operator1<DeoptimizeParameters>>( // --
|
||||
IrOpcode::kDeoptimizeUnless, // opcode
|
||||
Operator::kFoldable | Operator::kNoThrow, // properties
|
||||
|
@ -80,16 +80,13 @@ int ValueInputCountOfReturn(Operator const* const op);
|
||||
// Parameters for the {Deoptimize} operator.
|
||||
class DeoptimizeParameters final {
|
||||
public:
|
||||
DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback)
|
||||
: kind_(kind), reason_(reason), feedback_(feedback) {}
|
||||
DeoptimizeParameters(DeoptimizeReason reason, FeedbackSource const& feedback)
|
||||
: reason_(reason), feedback_(feedback) {}
|
||||
|
||||
DeoptimizeKind kind() const { return kind_; }
|
||||
DeoptimizeReason reason() const { return reason_; }
|
||||
const FeedbackSource& feedback() const { return feedback_; }
|
||||
|
||||
private:
|
||||
DeoptimizeKind const kind_;
|
||||
DeoptimizeReason const reason_;
|
||||
FeedbackSource const feedback_;
|
||||
};
|
||||
@ -489,11 +486,11 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
|
||||
BranchHint hint = BranchHint::kNone);
|
||||
const Operator* IfDefault(BranchHint hint = BranchHint::kNone);
|
||||
const Operator* Throw();
|
||||
const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
const Operator* Deoptimize(DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback);
|
||||
const Operator* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
const Operator* DeoptimizeIf(DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback);
|
||||
const Operator* DeoptimizeUnless(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
const Operator* DeoptimizeUnless(DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback);
|
||||
const Operator* TrapIf(TrapId trap_id);
|
||||
const Operator* TrapUnless(TrapId trap_id);
|
||||
|
@ -512,33 +512,15 @@ Node* GraphAssembler::BitcastMaybeObjectToWord(Node* value) {
|
||||
Node* GraphAssembler::DeoptimizeIf(DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state) {
|
||||
return AddNode(graph()->NewNode(
|
||||
common()->DeoptimizeIf(DeoptimizeKind::kEager, reason, feedback),
|
||||
condition, frame_state, effect(), control()));
|
||||
}
|
||||
|
||||
Node* GraphAssembler::DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state) {
|
||||
return AddNode(
|
||||
graph()->NewNode(common()->DeoptimizeIf(kind, reason, feedback),
|
||||
condition, frame_state, effect(), control()));
|
||||
}
|
||||
|
||||
Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeKind kind,
|
||||
DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state) {
|
||||
return AddNode(
|
||||
graph()->NewNode(common()->DeoptimizeUnless(kind, reason, feedback),
|
||||
condition, frame_state, effect(), control()));
|
||||
return AddNode(graph()->NewNode(common()->DeoptimizeIf(reason, feedback),
|
||||
condition, frame_state, effect(), control()));
|
||||
}
|
||||
|
||||
Node* GraphAssembler::DeoptimizeIfNot(DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state) {
|
||||
return DeoptimizeIfNot(DeoptimizeKind::kEager, reason, feedback, condition,
|
||||
frame_state);
|
||||
return AddNode(graph()->NewNode(common()->DeoptimizeUnless(reason, feedback),
|
||||
condition, frame_state, effect(), control()));
|
||||
}
|
||||
|
||||
TNode<Object> GraphAssembler::Call(const CallDescriptor* call_descriptor,
|
||||
|
@ -325,12 +325,6 @@ class V8_EXPORT_PRIVATE GraphAssembler {
|
||||
|
||||
Node* DeoptimizeIf(DeoptimizeReason reason, FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state);
|
||||
Node* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback, Node* condition,
|
||||
Node* frame_state);
|
||||
Node* DeoptimizeIfNot(DeoptimizeKind kind, DeoptimizeReason reason,
|
||||
FeedbackSource const& feedback, Node* condition,
|
||||
Node* frame_state);
|
||||
Node* DeoptimizeIfNot(DeoptimizeReason reason, FeedbackSource const& feedback,
|
||||
Node* condition, Node* frame_state);
|
||||
TNode<Object> Call(const CallDescriptor* call_descriptor, int inputs_size,
|
||||
|
@ -5479,9 +5479,9 @@ Reduction JSCallReducer::ReduceForInsufficientFeedback(
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
Node* frame_state =
|
||||
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead());
|
||||
Node* deoptimize = graph()->NewNode(
|
||||
common()->Deoptimize(DeoptimizeKind::kEager, reason, FeedbackSource()),
|
||||
frame_state, effect, control);
|
||||
Node* deoptimize =
|
||||
graph()->NewNode(common()->Deoptimize(reason, FeedbackSource()),
|
||||
frame_state, effect, control);
|
||||
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
|
||||
Revisit(graph()->end());
|
||||
|
@ -126,8 +126,7 @@ Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
|
||||
|
||||
// TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
|
||||
Node* deoptimize = graph()->NewNode(
|
||||
common()->Deoptimize(DeoptimizeKind::kEager,
|
||||
DeoptimizeReason::kDeoptimizeNow, FeedbackSource()),
|
||||
common()->Deoptimize(DeoptimizeReason::kDeoptimizeNow, FeedbackSource()),
|
||||
frame_state, effect, control);
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
|
||||
Revisit(graph()->end());
|
||||
|
@ -1982,9 +1982,9 @@ Reduction JSNativeContextSpecialization::ReduceEagerDeoptimize(
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
Node* frame_state =
|
||||
NodeProperties::FindFrameStateBefore(node, jsgraph()->Dead());
|
||||
Node* deoptimize = graph()->NewNode(
|
||||
common()->Deoptimize(DeoptimizeKind::kEager, reason, FeedbackSource()),
|
||||
frame_state, effect, control);
|
||||
Node* deoptimize =
|
||||
graph()->NewNode(common()->Deoptimize(reason, FeedbackSource()),
|
||||
frame_state, effect, control);
|
||||
// TODO(bmeurer): This should be on the AdvancedReducer somehow.
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
|
||||
Revisit(graph()->end());
|
||||
|
@ -569,8 +569,7 @@ Node* JSTypeHintLowering::BuildDeoptIfFeedbackIsInsufficient(
|
||||
if (!broker()->FeedbackIsInsufficient(source)) return nullptr;
|
||||
|
||||
Node* deoptimize = jsgraph()->graph()->NewNode(
|
||||
jsgraph()->common()->Deoptimize(DeoptimizeKind::kEager, reason,
|
||||
FeedbackSource()),
|
||||
jsgraph()->common()->Deoptimize(reason, FeedbackSource()),
|
||||
jsgraph()->Dead(), effect, control);
|
||||
Node* frame_state =
|
||||
NodeProperties::FindFrameStateBefore(deoptimize, jsgraph()->Dead());
|
||||
|
@ -2289,14 +2289,13 @@ Reduction MachineOperatorReducer::SimplifyBranch(Node* node) {
|
||||
case IrOpcode::kDeoptimizeIf: {
|
||||
DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
|
||||
NodeProperties::ChangeOp(
|
||||
node,
|
||||
common()->DeoptimizeUnless(p.kind(), p.reason(), p.feedback()));
|
||||
node, common()->DeoptimizeUnless(p.reason(), p.feedback()));
|
||||
break;
|
||||
}
|
||||
case IrOpcode::kDeoptimizeUnless: {
|
||||
DeoptimizeParameters p = DeoptimizeParametersOf(node->op());
|
||||
NodeProperties::ChangeOp(
|
||||
node, common()->DeoptimizeIf(p.kind(), p.reason(), p.feedback()));
|
||||
node, common()->DeoptimizeIf(p.reason(), p.feedback()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -72,13 +72,10 @@ TEST(DeoptInMiddleOfBasicBlock) {
|
||||
|
||||
tester.StartBlock();
|
||||
InstructionCode jmp_opcode = kArchJmp;
|
||||
// Dummy node for FlagsContinuation::ForDeoptimize (which won't accept
|
||||
// nullptr).
|
||||
Node* node = Node::New(zone, 0, nullptr, 0, nullptr, false);
|
||||
FeedbackSource feedback;
|
||||
FlagsContinuation cont = FlagsContinuation::ForDeoptimize(
|
||||
kEqual, DeoptimizeKind::kEager, DeoptimizeReason::kUnknown, node->id(),
|
||||
feedback, node);
|
||||
Node* dummy_frame_state = Node::New(zone, 0, nullptr, 0, nullptr, false);
|
||||
FlagsContinuation cont = FlagsContinuation::ForDeoptimizeForTesting(
|
||||
kEqual, DeoptimizeReason::kUnknown, dummy_frame_state->id(),
|
||||
FeedbackSource{}, dummy_frame_state);
|
||||
jmp_opcode = cont.Encode(jmp_opcode);
|
||||
Instruction* jmp_inst = Instruction::New(zone, jmp_opcode);
|
||||
tester.CheckIsDeopt(jmp_inst);
|
||||
|
Loading…
Reference in New Issue
Block a user