Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Unified Diff: src/compiler/simplified-lowering.cc

Issue 691513002: [turbofan] Introduce new Select operator to improve bounds checking. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index 35707f287b95a9135cb3067190058942bb84a0ab..43a0d5257f9e4e3400e7e2edad0c42e712adbd67 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -299,6 +299,85 @@ class RepresentationSelector {
void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
+ // Helper for handling selects.
+ // TODO(turbofan): Share some code with VisitPhi() below?
+ void VisitSelect(Node* node, MachineTypeUnion use,
+ SimplifiedLowering* lowering) {
+ ProcessInput(node, 0, kRepBit);
+
+ // Selects adapt to the output representation their uses demand, pushing
+ // representation changes to their inputs.
+ Type* upper = NodeProperties::GetBounds(node).upper;
+ MachineType output = kMachNone;
+ MachineType propagate = kMachNone;
+
+ if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
+ // legal = kRepTagged | kRepFloat64 | kRepWord32;
+ if ((use & kRepMask) == kRepTagged) {
+ // only tagged uses.
+ output = kRepTagged;
+ propagate = kRepTagged;
+ } else if ((use & kRepMask) == kRepFloat64) {
+ // only float64 uses.
+ output = kRepFloat64;
+ propagate = kRepFloat64;
+ } else {
+ // multiple uses.
+ output = kRepWord32;
+ propagate = kRepWord32;
+ }
+ } else if (upper->Is(Type::Boolean())) {
+ // legal = kRepTagged | kRepBit;
+ if ((use & kRepMask) == kRepTagged) {
+ // only tagged uses.
+ output = kRepTagged;
+ propagate = kRepTagged;
+ } else {
+ // multiple uses.
+ output = kRepBit;
+ propagate = kRepBit;
+ }
+ } else if (upper->Is(Type::Number())) {
+ // legal = kRepTagged | kRepFloat64;
+ if ((use & kRepMask) == kRepTagged) {
+ // only tagged uses.
+ output = kRepTagged;
+ propagate = kRepTagged;
+ } else {
+ // multiple uses.
+ output = kRepFloat64;
+ propagate = kRepFloat64;
+ }
+ } else {
+ // legal = kRepTagged;
+ output = kRepTagged;
+ propagate = kRepTagged;
+ }
+
+ MachineType output_type =
+ static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
+ SetOutput(node, output_type);
+
+ if (lower()) {
+ // Update the select operator.
+ SelectParameters p = SelectParametersOf(node->op());
+ MachineType type = static_cast<MachineType>(output_type);
+ if (type != p.type()) {
+ node->set_op(lowering->common()->Select(type, p.hint()));
+ }
+
+ // Convert inputs to the output representation of this select.
+ ProcessInput(node, 1, output_type);
+ ProcessInput(node, 2, output_type);
+ } else {
+ // Propagate {use} of the select to value inputs.
+ MachineType use_type =
+ static_cast<MachineType>((use & kTypeMask) | propagate);
+ ProcessInput(node, 1, use_type);
+ ProcessInput(node, 2, use_type);
+ }
+ }
+
// Helper for handling phis.
void VisitPhi(Node* node, MachineTypeUnion use,
SimplifiedLowering* lowering) {
@@ -481,6 +560,8 @@ class RepresentationSelector {
ProcessInput(node, 0, kRepBit);
Enqueue(NodeProperties::GetControlInput(node, 0));
break;
+ case IrOpcode::kSelect:
+ return VisitSelect(node, use, lowering);
case IrOpcode::kPhi:
return VisitPhi(node, use, lowering);
@@ -1057,25 +1138,67 @@ void SimplifiedLowering::DoStoreField(Node* node) {
Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
- Node* index) {
- int element_size = ElementSizeOf(access.machine_type);
+ Node* const key) {
+ Node* index = key;
+ const int element_size = ElementSizeOf(access.machine_type);
if (element_size != 1) {
- index = graph()->NewNode(machine()->Int32Mul(),
- jsgraph()->Int32Constant(element_size), index);
+ index = graph()->NewNode(machine()->Int32Mul(), index,
+ jsgraph()->Int32Constant(element_size));
+ }
+ const int fixed_offset = access.header_size - access.tag();
+ if (fixed_offset != 0) {
+ index = graph()->NewNode(machine()->Int32Add(), index,
+ jsgraph()->Int32Constant(fixed_offset));
+ }
+ // TODO(bmeurer): 64-Bit
+ // if (machine()->Is64()) {
+ // index = graph()->NewNode(machine()->ChangeInt32ToInt64(), index);
+ // }
+ return index;
+}
+
+
+namespace {
+
+intptr_t AddressForOutOfBoundsLoad(MachineType type) {
+ switch (RepresentationOf(type)) {
+ case kRepFloat32: {
+ static const float dummy = std::numeric_limits<float>::quiet_NaN();
+ return bit_cast<intptr_t>(&dummy);
+ }
+ case kRepFloat64: {
+ static const double dummy = std::numeric_limits<double>::quiet_NaN();
+ return bit_cast<intptr_t>(&dummy);
+ }
+ case kRepBit:
+ case kRepWord8:
+ case kRepWord16:
+ case kRepWord32: {
+ static const int32_t dummy = 0;
+ return bit_cast<intptr_t>(&dummy);
+ }
+ default:
+ break;
}
- int fixed_offset = access.header_size - access.tag();
- if (fixed_offset == 0) return index;
- return graph()->NewNode(machine()->Int32Add(), index,
- jsgraph()->Int32Constant(fixed_offset));
+ UNREACHABLE();
+ return 0;
}
+intptr_t AddressForOutOfBoundsStore() {
+ static volatile double dummy = 0;
+ return bit_cast<intptr_t>(&dummy);
+}
+
+} // namespace
+
+
void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) {
const ElementAccess& access = ElementAccessOf(node->op());
const Operator* op = machine()->Load(access.machine_type);
Node* key = node->InputAt(1);
- Node* effect = node->InputAt(3);
Node* index = ComputeIndex(access, key);
+ Node* effect = node->InputAt(3);
if (access.bounds_check == kNoBoundsCheck) {
DCHECK_EQ(access.machine_type, output_type);
node->set_op(op);
@@ -1087,54 +1210,68 @@ void SimplifiedLowering::DoLoadElement(Node* node, MachineType output_type) {
Node* base = node->InputAt(0);
Node* length = node->InputAt(2);
-
Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length);
- Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check,
- graph()->start());
-
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* load = graph()->NewNode(op, base, index, effect, if_true);
- Node* result = load;
- if (output_type & kRepTagged) {
- // TODO(turbofan): This is ugly as hell!
- SimplifiedOperatorBuilder simplified(graph()->zone());
- RepresentationChanger changer(jsgraph(), &simplified,
- graph()->zone()->isolate());
- result = changer.GetTaggedRepresentationFor(result, access.machine_type);
- }
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
- Node* undefined;
- if (output_type & kRepTagged) {
- DCHECK(!(access.machine_type & kRepTagged));
- undefined = jsgraph()->UndefinedConstant();
- } else if (output_type & kRepFloat32) {
- undefined =
- jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
- } else if (output_type & kRepFloat64) {
- undefined =
- jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
+ IntPtrMatcher mbase(base);
+ if (mbase.HasValue() && (output_type & kRepTagged) == 0) {
+ Node* select = graph()->NewNode(
+ common()->Select(kMachIntPtr, BranchHint::kTrue), check, index,
+ jsgraph()->IntPtrConstant(AddressForOutOfBoundsLoad(output_type) -
+ mbase.Value()));
+
+ node->set_op(op);
+ node->ReplaceInput(1, select);
+ node->ReplaceInput(2, effect);
+ node->ReplaceInput(3, graph()->start());
} else {
- undefined = jsgraph()->Int32Constant(0);
- }
-
- Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
- Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge);
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+ check, graph()->start());
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* load = graph()->NewNode(op, base, index, effect, if_true);
+ Node* result = load;
+ if (output_type & kRepTagged) {
+ // TODO(turbofan): This is ugly as hell!
+ SimplifiedOperatorBuilder simplified(graph()->zone());
+ RepresentationChanger changer(jsgraph(), &simplified,
+ graph()->zone()->isolate());
+ result =
+ changer.GetTaggedRepresentationFor(result, access.machine_type);
+ }
- // Replace effect uses of node with the effect phi.
- for (UseIter i = node->uses().begin(); i != node->uses().end();) {
- if (NodeProperties::IsEffectEdge(i.edge())) {
- i = i.UpdateToAndIncrement(phi);
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* undefined;
+ if (output_type & kRepTagged) {
+ DCHECK_EQ(0, access.machine_type & kRepTagged);
+ undefined = jsgraph()->UndefinedConstant();
+ } else if (output_type & kRepFloat32) {
+ undefined =
+ jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
+ } else if (output_type & kRepFloat64) {
+ undefined = jsgraph()->Float64Constant(
+ std::numeric_limits<double>::quiet_NaN());
} else {
- ++i;
+ undefined = jsgraph()->Int32Constant(0);
}
- }
- node->set_op(common()->Phi(output_type, 2));
- node->ReplaceInput(0, result);
- node->ReplaceInput(1, undefined);
- node->ReplaceInput(2, merge);
- node->TrimInputCount(3);
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* phi = graph()->NewNode(common()->EffectPhi(2), load, effect, merge);
+
+ // Replace effect uses of node with the effect phi.
+ for (UseIter i = node->uses().begin(); i != node->uses().end();) {
+ if (NodeProperties::IsEffectEdge(i.edge())) {
+ i = i.UpdateToAndIncrement(phi);
+ } else {
+ ++i;
+ }
+ }
+
+ node->set_op(common()->Phi(output_type, 2));
+ node->ReplaceInput(0, result);
+ node->ReplaceInput(1, undefined);
+ node->ReplaceInput(2, merge);
+ node->TrimInputCount(3);
+ }
}
}
@@ -1159,23 +1296,35 @@ void SimplifiedLowering::DoStoreElement(Node* node) {
Node* value = node->InputAt(3);
Node* effect = node->InputAt(4);
Node* control = node->InputAt(5);
-
Node* check = graph()->NewNode(machine()->Uint32LessThan(), key, length);
- Node* branch =
- graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
- Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* store = graph()->NewNode(op, base, index, value, effect, if_true);
+ IntPtrMatcher mbase(base);
+ if (mbase.HasValue()) {
+ Node* select = graph()->NewNode(
+ common()->Select(kMachIntPtr, BranchHint::kTrue), check, index,
+ jsgraph()->IntPtrConstant(AddressForOutOfBoundsStore() -
+ mbase.Value()));
+
+ node->set_op(op);
+ node->ReplaceInput(1, select);
+ node->RemoveInput(2);
+ } else {
+ Node* branch =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* store = graph()->NewNode(op, base, index, value, effect, if_true);
- Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
- Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
- node->set_op(common()->EffectPhi(2));
- node->ReplaceInput(0, store);
- node->ReplaceInput(1, effect);
- node->ReplaceInput(2, merge);
- node->TrimInputCount(3);
+ node->set_op(common()->EffectPhi(2));
+ node->ReplaceInput(0, store);
+ node->ReplaceInput(1, effect);
+ node->ReplaceInput(2, merge);
+ node->TrimInputCount(3);
+ }
}
}
@@ -1375,7 +1524,6 @@ void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
}
-
} // namespace compiler
} // namespace internal
} // namespace v8
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/typer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698