[turbofan] Utilize type information for alias analysis.
If the intersection of the types of nodes a and b is empty, then there's no way that a and b could ever refer to the same object, so we can use that information for alias analysis. Drive-by-fix: Improve use of types to enable typed alias analysis to become more effective. Also fix an ASAN issue uncovered by this CL. R=jarin@chromium.org Review-Url: https://codereview.chromium.org/2237433003 Cr-Commit-Position: refs/heads/master@{#38567}
This commit is contained in:
parent
fe2b7b9ffb
commit
c0439051d6
@ -17,8 +17,8 @@ namespace compiler {
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForMap() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kMapWriteBarrier};
|
||||
kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(),
|
||||
Type::OtherInternal(), MachineType::AnyTagged(), kMapWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ FieldAccess AccessBuilder::ForJSFunctionSharedFunctionInfo() {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
JSFunction::kSharedFunctionInfoOffset,
|
||||
Handle<Name>(),
|
||||
Type::Any(),
|
||||
Type::OtherInternal(),
|
||||
MachineType::AnyTagged(),
|
||||
kPointerWriteBarrier};
|
||||
return access;
|
||||
@ -156,7 +156,7 @@ FieldAccess AccessBuilder::ForJSGeneratorObjectInputOrDebugPos() {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
JSGeneratorObject::kInputOrDebugPosOffset,
|
||||
Handle<Name>(),
|
||||
Type::Any(),
|
||||
Type::NonInternal(),
|
||||
MachineType::AnyTagged(),
|
||||
kFullWriteBarrier};
|
||||
return access;
|
||||
@ -283,8 +283,8 @@ FieldAccess AccessBuilder::ForJSDateField(JSDate::FieldIndex index) {
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForJSIteratorResultDone() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, JSIteratorResult::kDoneOffset, MaybeHandle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
kTaggedBase, JSIteratorResult::kDoneOffset, MaybeHandle<Name>(),
|
||||
Type::NonInternal(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -292,8 +292,8 @@ FieldAccess AccessBuilder::ForJSIteratorResultDone() {
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForJSIteratorResultValue() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, JSIteratorResult::kValueOffset, MaybeHandle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
kTaggedBase, JSIteratorResult::kValueOffset, MaybeHandle<Name>(),
|
||||
Type::NonInternal(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -536,8 +536,8 @@ FieldAccess AccessBuilder::ForJSGlobalObjectNativeContext() {
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForValue() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, JSValue::kValueOffset, Handle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
kTaggedBase, JSValue::kValueOffset, Handle<Name>(),
|
||||
Type::NonInternal(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -545,8 +545,8 @@ FieldAccess AccessBuilder::ForValue() {
|
||||
// static
|
||||
FieldAccess AccessBuilder::ForArgumentsLength() {
|
||||
FieldAccess access = {
|
||||
kTaggedBase, JSArgumentsObject::kLengthOffset, Handle<Name>(),
|
||||
Type::Any(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
kTaggedBase, JSArgumentsObject::kLengthOffset, Handle<Name>(),
|
||||
Type::NonInternal(), MachineType::AnyTagged(), kFullWriteBarrier};
|
||||
return access;
|
||||
}
|
||||
|
||||
@ -556,7 +556,7 @@ FieldAccess AccessBuilder::ForArgumentsCallee() {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
JSSloppyArgumentsObject::kCalleeOffset,
|
||||
Handle<Name>(),
|
||||
Type::Any(),
|
||||
Type::NonInternal(),
|
||||
MachineType::AnyTagged(),
|
||||
kPointerWriteBarrier};
|
||||
return access;
|
||||
@ -569,7 +569,7 @@ FieldAccess AccessBuilder::ForFixedArraySlot(size_t index) {
|
||||
FieldAccess access = {kTaggedBase,
|
||||
offset,
|
||||
Handle<Name>(),
|
||||
Type::Any(),
|
||||
Type::NonInternal(),
|
||||
MachineType::AnyTagged(),
|
||||
kFullWriteBarrier};
|
||||
return access;
|
||||
|
@ -93,14 +93,14 @@ PropertyAccessInfo PropertyAccessInfo::AccessorConstant(
|
||||
}
|
||||
|
||||
PropertyAccessInfo::PropertyAccessInfo()
|
||||
: kind_(kInvalid), field_type_(Type::Any()) {}
|
||||
: kind_(kInvalid), field_type_(Type::None()) {}
|
||||
|
||||
PropertyAccessInfo::PropertyAccessInfo(MaybeHandle<JSObject> holder,
|
||||
MapList const& receiver_maps)
|
||||
: kind_(kNotFound),
|
||||
receiver_maps_(receiver_maps),
|
||||
holder_(holder),
|
||||
field_type_(Type::Any()) {}
|
||||
field_type_(Type::None()) {}
|
||||
|
||||
PropertyAccessInfo::PropertyAccessInfo(Kind kind, MaybeHandle<JSObject> holder,
|
||||
Handle<Object> constant,
|
||||
|
@ -18,6 +18,9 @@ enum Aliasing { kNoAlias, kMayAlias, kMustAlias };
|
||||
|
||||
Aliasing QueryAlias(Node* a, Node* b) {
|
||||
if (a == b) return kMustAlias;
|
||||
if (!NodeProperties::GetType(a)->Maybe(NodeProperties::GetType(b))) {
|
||||
return kNoAlias;
|
||||
}
|
||||
if (b->opcode() == IrOpcode::kAllocate) {
|
||||
switch (a->opcode()) {
|
||||
case IrOpcode::kAllocate:
|
||||
@ -111,6 +114,7 @@ LoadElimination::AbstractElements::Kill(Node* object, Node* index,
|
||||
that->elements_[that->next_index_++] = element;
|
||||
}
|
||||
}
|
||||
that->next_index_ %= arraysize(elements_);
|
||||
return that;
|
||||
}
|
||||
}
|
||||
@ -164,6 +168,7 @@ LoadElimination::AbstractElements::Merge(AbstractElements const* that,
|
||||
}
|
||||
}
|
||||
}
|
||||
copy->next_index_ %= arraysize(elements_);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -294,7 +294,6 @@ class Typer::Visitor : public Reducer {
|
||||
#undef DECLARE_METHOD
|
||||
|
||||
static Type* JSTypeOfTyper(Type*, Typer*);
|
||||
static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
|
||||
static Type* JSCallFunctionTyper(Type*, Typer*);
|
||||
|
||||
static Type* ReferenceEqualTyper(Type*, Type*, Typer*);
|
||||
@ -545,8 +544,9 @@ Type* Typer::Visitor::ObjectIsUndetectable(Type* type, Typer* t) {
|
||||
|
||||
Type* Typer::Visitor::TypeStart(Node* node) { return Type::Internal(); }
|
||||
|
||||
Type* Typer::Visitor::TypeIfException(Node* node) { return Type::Any(); }
|
||||
|
||||
Type* Typer::Visitor::TypeIfException(Node* node) {
|
||||
return Type::NonInternal();
|
||||
}
|
||||
|
||||
// Common operators.
|
||||
|
||||
@ -1080,28 +1080,18 @@ Type* Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
|
||||
// TODO(rossberg): Use range types and sized array types to filter undefined.
|
||||
if (object->IsArray() && name->Is(Type::Integral32())) {
|
||||
return Type::Union(
|
||||
object->AsArray()->Element(), Type::Undefined(), t->zone());
|
||||
}
|
||||
return Type::Any();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSLoadProperty(Node* node) {
|
||||
return TypeBinaryOp(node, JSLoadPropertyTyper);
|
||||
return Type::NonInternal();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSLoadNamed(Node* node) {
|
||||
return Type::Any();
|
||||
return Type::NonInternal();
|
||||
}
|
||||
|
||||
|
||||
Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) { return Type::Any(); }
|
||||
|
||||
Type* Typer::Visitor::TypeJSLoadGlobal(Node* node) {
|
||||
return Type::NonInternal();
|
||||
}
|
||||
|
||||
// Returns a somewhat larger range if we previously assigned
|
||||
// a (smaller) range to this node. This is used to speed up
|
||||
@ -1359,7 +1349,7 @@ Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return Type::Any();
|
||||
return Type::NonInternal();
|
||||
}
|
||||
|
||||
|
||||
@ -1402,6 +1392,9 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// TODO(turbofan): This should be Type::NonInternal(), but unfortunately we
|
||||
// have a few weird runtime calls that return the hole or even FixedArrays;
|
||||
// change this once those weird runtime calls have been removed.
|
||||
return Type::Any();
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ bool FieldType::NowIs(FieldType* other) {
|
||||
bool FieldType::NowIs(Handle<FieldType> other) { return NowIs(*other); }
|
||||
|
||||
Type* FieldType::Convert(Zone* zone) {
|
||||
if (IsAny()) return Type::Any();
|
||||
if (IsAny()) return Type::NonInternal();
|
||||
if (IsNone()) return Type::None();
|
||||
DCHECK(IsClass());
|
||||
return Type::Class(AsClass(), zone);
|
||||
|
Loading…
Reference in New Issue
Block a user