[turbofan] add BranchHint to switch cases, maintain CSA deferred info through re-scheduling

Change-Id: I9c927567e43e269a9b8ed81edfc8786a879e9573
Reviewed-on: https://chromium-review.googlesource.com/c/1350120
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57967}
This commit is contained in:
Tobias Tebbi 2018-11-26 11:01:25 +01:00 committed by Commit Bot
parent 7a491d0320
commit 5aa43bdc62
4 changed files with 57 additions and 17 deletions

View File

@ -70,7 +70,16 @@ const BranchOperatorInfo& BranchOperatorInfoOf(const Operator* const op) {
}
BranchHint BranchHintOf(const Operator* const op) {
return BranchOperatorInfoOf(op).hint;
switch (op->opcode()) {
case IrOpcode::kBranch:
return BranchOperatorInfoOf(op).hint;
case IrOpcode::kIfValue:
return IfValueParametersOf(op).hint();
case IrOpcode::kIfDefault:
return OpParameter<BranchHint>(op);
default:
UNREACHABLE();
}
}
int ValueInputCountOfReturn(Operator const* const op) {
@ -420,16 +429,18 @@ ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
V8_EXPORT_PRIVATE bool operator==(IfValueParameters const& l,
IfValueParameters const& r) {
return l.value() == r.value() && r.comparison_order() == r.comparison_order();
return l.value() == r.value() &&
r.comparison_order() == r.comparison_order() && l.hint() == r.hint();
}
size_t hash_value(IfValueParameters const& p) {
return base::hash_combine(p.value(), p.comparison_order());
return base::hash_combine(p.value(), p.comparison_order(), p.hint());
}
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& out,
IfValueParameters const& p) {
out << p.value() << " (order " << p.comparison_order() << ")";
out << p.value() << " (order " << p.comparison_order() << ", hint "
<< p.hint() << ")";
return out;
}
@ -445,7 +456,6 @@ IfValueParameters const& IfValueParametersOf(const Operator* op) {
V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \
V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
@ -1043,14 +1053,22 @@ const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
}
const Operator* CommonOperatorBuilder::IfValue(int32_t index,
int32_t comparison_order) {
return new (zone()) Operator1<IfValueParameters>( // --
IrOpcode::kIfValue, Operator::kKontrol, // opcode
"IfValue", // name
0, 0, 1, 0, 0, 1, // counts
IfValueParameters(index, comparison_order)); // parameter
int32_t comparison_order,
BranchHint hint) {
return new (zone()) Operator1<IfValueParameters>( // --
IrOpcode::kIfValue, Operator::kKontrol, // opcode
"IfValue", // name
0, 0, 1, 0, 0, 1, // counts
IfValueParameters(index, comparison_order, hint)); // parameter
}
const Operator* CommonOperatorBuilder::IfDefault(BranchHint hint) {
return new (zone()) Operator1<BranchHint>( // --
IrOpcode::kIfDefault, Operator::kKontrol, // opcode
"IfDefault", // name
0, 0, 1, 0, 0, 1, // counts
hint); // parameter
}
const Operator* CommonOperatorBuilder::Start(int value_output_count) {
return new (zone()) Operator( // --

View File

@ -410,15 +410,18 @@ MachineRepresentation DeadValueRepresentationOf(Operator const*)
class IfValueParameters final {
public:
IfValueParameters(int32_t value, int32_t comparison_order)
: value_(value), comparison_order_(comparison_order) {}
IfValueParameters(int32_t value, int32_t comparison_order,
BranchHint hint = BranchHint::kNone)
: value_(value), comparison_order_(comparison_order), hint_(hint) {}
int32_t value() const { return value_; }
int32_t comparison_order() const { return comparison_order_; }
BranchHint hint() const { return hint_; }
private:
int32_t value_;
int32_t comparison_order_;
BranchHint hint_;
};
V8_EXPORT_PRIVATE bool operator==(IfValueParameters const&,
@ -458,8 +461,9 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const Operator* IfSuccess();
const Operator* IfException();
const Operator* Switch(size_t control_output_count);
const Operator* IfValue(int32_t value, int32_t order = 0);
const Operator* IfDefault();
const Operator* IfValue(int32_t value, int32_t order = 0,
BranchHint hint = BranchHint::kNone);
const Operator* IfDefault(BranchHint hint = BranchHint::kNone);
const Operator* Throw();
const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason,
VectorSlotPair const& feedback);

View File

@ -326,9 +326,21 @@ void RawMachineAssembler::MarkControlDeferred(Node* control_node) {
case IrOpcode::kIfSuccess:
control_node = NodeProperties::GetControlInput(control_node);
continue;
case IrOpcode::kIfValue:
case IrOpcode::kIfValue: {
IfValueParameters parameters = IfValueParametersOf(control_node->op());
if (parameters.hint() != BranchHint::kFalse) {
NodeProperties::ChangeOp(
control_node, common()->IfValue(parameters.value(),
parameters.comparison_order(),
BranchHint::kFalse));
}
return;
}
case IrOpcode::kIfDefault:
// Marking switch cases as deferred is currently impossible.
if (BranchHintOf(control_node->op()) != BranchHint::kFalse) {
NodeProperties::ChangeOp(control_node,
common()->IfDefault(BranchHint::kFalse));
}
return;
case IrOpcode::kIfTrue: {
Node* branch = NodeProperties::GetControlInput(control_node);

View File

@ -517,6 +517,12 @@ class CFGBuilder : public ZoneObject {
}
schedule_->AddSwitch(switch_block, sw, successor_blocks, successor_count);
}
for (size_t index = 0; index < successor_count; ++index) {
if (BranchHintOf(successor_blocks[index]->front()->op()) ==
BranchHint::kFalse) {
successor_blocks[index]->set_deferred(true);
}
}
}
void ConnectMerge(Node* merge) {