diff options
Diffstat (limited to 'deps/v8/test/unittests/compiler/escape-analysis-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/compiler/escape-analysis-unittest.cc | 164 |
1 files changed, 140 insertions, 24 deletions
diff --git a/deps/v8/test/unittests/compiler/escape-analysis-unittest.cc b/deps/v8/test/unittests/compiler/escape-analysis-unittest.cc index b088367a58..d5e12ba0db 100644 --- a/deps/v8/test/unittests/compiler/escape-analysis-unittest.cc +++ b/deps/v8/test/unittests/compiler/escape-analysis-unittest.cc @@ -9,7 +9,7 @@ #include "src/compiler/js-graph.h" #include "src/compiler/node-properties.h" #include "src/compiler/simplified-operator.h" -#include "src/types-inl.h" +#include "src/types.h" #include "src/zone-containers.h" #include "test/unittests/compiler/graph-unittest.h" @@ -85,6 +85,20 @@ class EscapeAnalysisTest : public GraphTest { allocation, value, effect, control); } + Node* StoreElement(const ElementAccess& access, Node* allocation, Node* index, + Node* value, Node* effect = nullptr, + Node* control = nullptr) { + if (!effect) { + effect = effect_; + } + if (!control) { + control = control_; + } + return effect_ = + graph()->NewNode(simplified()->StoreElement(access), allocation, + index, value, effect, control); + } + Node* Load(const FieldAccess& access, Node* from, Node* effect = nullptr, Node* control = nullptr) { if (!effect) { @@ -131,12 +145,18 @@ class EscapeAnalysisTest : public GraphTest { return control_ = graph()->NewNode(common()->Merge(2), control1, control2); } - FieldAccess AccessAtIndex(int offset) { + FieldAccess FieldAccessAtIndex(int offset) { FieldAccess access = {kTaggedBase, offset, MaybeHandle<Name>(), Type::Any(), MachineType::AnyTagged()}; return access; } + ElementAccess MakeElementAccess(int header_size) { + ElementAccess access = {kTaggedBase, header_size, Type::Any(), + MachineType::AnyTagged()}; + return access; + } + // ---------------------------------Assertion Helper-------------------------- void ExpectReplacement(Node* node, Node* rep) { @@ -166,6 +186,7 @@ class EscapeAnalysisTest : public GraphTest { SimplifiedOperatorBuilder* simplified() { return &simplified_; } Node* effect() { return effect_; } + Node* control() { return control_; } private: SimplifiedOperatorBuilder simplified_; @@ -185,9 +206,9 @@ TEST_F(EscapeAnalysisTest, StraightNonEscape) { Node* object1 = Constant(1); BeginRegion(); Node* allocation = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation, object1); + Store(FieldAccessAtIndex(0), allocation, object1); Node* finish = FinishRegion(allocation); - Node* load = Load(AccessAtIndex(0), finish); + Node* load = Load(FieldAccessAtIndex(0), finish); Node* result = Return(load); EndGraph(); @@ -202,13 +223,39 @@ TEST_F(EscapeAnalysisTest, StraightNonEscape) { } +TEST_F(EscapeAnalysisTest, StraightNonEscapeNonConstStore) { + Node* object1 = Constant(1); + Node* object2 = Constant(2); + BeginRegion(); + Node* allocation = Allocate(Constant(kPointerSize)); + Store(FieldAccessAtIndex(0), allocation, object1); + Node* index = + graph()->NewNode(common()->Select(MachineRepresentation::kTagged), + object1, object2, control()); + StoreElement(MakeElementAccess(0), allocation, index, object1); + Node* finish = FinishRegion(allocation); + Node* load = Load(FieldAccessAtIndex(0), finish); + Node* result = Return(load); + EndGraph(); + + Analysis(); + + ExpectEscaped(allocation); + ExpectReplacement(load, nullptr); + + Transformation(); + + ASSERT_EQ(load, NodeProperties::GetValueInput(result, 0)); +} + + TEST_F(EscapeAnalysisTest, StraightEscape) { Node* object1 = Constant(1); BeginRegion(); Node* allocation = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation, object1); + Store(FieldAccessAtIndex(0), allocation, object1); Node* finish = FinishRegion(allocation); - Node* load = Load(AccessAtIndex(0), finish); + Node* load = Load(FieldAccessAtIndex(0), finish); Node* result = Return(allocation); EndGraph(); graph()->end()->AppendInput(zone(), load); @@ -229,15 +276,15 @@ TEST_F(EscapeAnalysisTest, StoreLoadEscape) { BeginRegion(); Node* allocation1 = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation1, object1); + Store(FieldAccessAtIndex(0), allocation1, object1); Node* finish1 = FinishRegion(allocation1); BeginRegion(); Node* allocation2 = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation2, finish1); + Store(FieldAccessAtIndex(0), allocation2, finish1); Node* finish2 = FinishRegion(allocation2); - Node* load = Load(AccessAtIndex(0), finish2); + Node* load = Load(FieldAccessAtIndex(0), finish2); Node* result = Return(load); EndGraph(); Analysis(); @@ -257,16 +304,18 @@ TEST_F(EscapeAnalysisTest, BranchNonEscape) { Node* object2 = Constant(2); BeginRegion(); Node* allocation = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation, object1); + Store(FieldAccessAtIndex(0), allocation, object1); Node* finish = FinishRegion(allocation); Branch(); Node* ifFalse = IfFalse(); Node* ifTrue = IfTrue(); - Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish, ifFalse); - Node* effect2 = Store(AccessAtIndex(0), allocation, object2, finish, ifTrue); + Node* effect1 = + Store(FieldAccessAtIndex(0), allocation, object1, finish, ifFalse); + Node* effect2 = + Store(FieldAccessAtIndex(0), allocation, object2, finish, ifTrue); Node* merge = Merge2(ifFalse, ifTrue); Node* phi = graph()->NewNode(common()->EffectPhi(2), effect1, effect2, merge); - Node* load = Load(AccessAtIndex(0), finish, phi, merge); + Node* load = Load(FieldAccessAtIndex(0), finish, phi, merge); Node* result = Return(load, phi); EndGraph(); graph()->end()->AppendInput(zone(), result); @@ -283,14 +332,81 @@ TEST_F(EscapeAnalysisTest, BranchNonEscape) { } +TEST_F(EscapeAnalysisTest, BranchEscapeOne) { + Node* object1 = Constant(1); + Node* object2 = Constant(2); + Node* index = graph()->NewNode(common()->Parameter(0), start()); + BeginRegion(); + Node* allocation = Allocate(Constant(kPointerSize)); + Store(FieldAccessAtIndex(0), allocation, object1); + Node* finish = FinishRegion(allocation); + Branch(); + Node* ifFalse = IfFalse(); + Node* ifTrue = IfTrue(); + Node* effect1 = + Store(FieldAccessAtIndex(0), allocation, object1, finish, ifFalse); + Node* effect2 = StoreElement(MakeElementAccess(0), allocation, index, object2, + finish, ifTrue); + Node* merge = Merge2(ifFalse, ifTrue); + Node* phi = graph()->NewNode(common()->EffectPhi(2), effect1, effect2, merge); + Node* load = Load(FieldAccessAtIndex(0), finish, phi, merge); + Node* result = Return(load, phi); + EndGraph(); + + Analysis(); + + ExpectEscaped(allocation); + ExpectReplacement(load, nullptr); + + Transformation(); + + ASSERT_EQ(load, NodeProperties::GetValueInput(result, 0)); +} + + +TEST_F(EscapeAnalysisTest, BranchEscapeThroughStore) { + Node* object1 = Constant(1); + Node* object2 = Constant(2); + BeginRegion(); + Node* allocation = Allocate(Constant(kPointerSize)); + Store(FieldAccessAtIndex(0), allocation, object1); + FinishRegion(allocation); + BeginRegion(); + Node* allocation2 = Allocate(Constant(kPointerSize)); + Store(FieldAccessAtIndex(0), allocation, object2); + Node* finish2 = FinishRegion(allocation2); + Branch(); + Node* ifFalse = IfFalse(); + Node* ifTrue = IfTrue(); + Node* effect1 = + Store(FieldAccessAtIndex(0), allocation, allocation2, finish2, ifFalse); + Node* merge = Merge2(ifFalse, ifTrue); + Node* phi = graph()->NewNode(common()->EffectPhi(2), effect1, finish2, merge); + Node* load = Load(FieldAccessAtIndex(0), finish2, phi, merge); + Node* result = Return(allocation, phi); + EndGraph(); + graph()->end()->AppendInput(zone(), load); + + Analysis(); + + ExpectEscaped(allocation); + ExpectEscaped(allocation2); + ExpectReplacement(load, nullptr); + + Transformation(); + + ASSERT_EQ(allocation, NodeProperties::GetValueInput(result, 0)); +} + + TEST_F(EscapeAnalysisTest, DanglingLoadOrder) { Node* object1 = Constant(1); Node* object2 = Constant(2); Node* allocation = Allocate(Constant(kPointerSize)); - Node* store1 = Store(AccessAtIndex(0), allocation, object1); - Node* load1 = Load(AccessAtIndex(0), allocation); - Node* store2 = Store(AccessAtIndex(0), allocation, object2); - Node* load2 = Load(AccessAtIndex(0), allocation, store1); + Node* store1 = Store(FieldAccessAtIndex(0), allocation, object1); + Node* load1 = Load(FieldAccessAtIndex(0), allocation); + Node* store2 = Store(FieldAccessAtIndex(0), allocation, object2); + Node* load2 = Load(FieldAccessAtIndex(0), allocation, store1); Node* result = Return(load2); EndGraph(); graph()->end()->AppendInput(zone(), store2); @@ -312,9 +428,9 @@ TEST_F(EscapeAnalysisTest, DeoptReplacement) { Node* object1 = Constant(1); BeginRegion(); Node* allocation = Allocate(Constant(kPointerSize)); - Store(AccessAtIndex(0), allocation, object1); + Store(FieldAccessAtIndex(0), allocation, object1); Node* finish = FinishRegion(allocation); - Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish); + Node* effect1 = Store(FieldAccessAtIndex(0), allocation, object1, finish); Branch(); Node* ifFalse = IfFalse(); Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); @@ -328,7 +444,7 @@ TEST_F(EscapeAnalysisTest, DeoptReplacement) { Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), frame_state, effect1, ifFalse); Node* ifTrue = IfTrue(); - Node* load = Load(AccessAtIndex(0), finish, effect1, ifTrue); + Node* load = Load(FieldAccessAtIndex(0), finish, effect1, ifTrue); Node* result = Return(load, effect1, ifTrue); EndGraph(); graph()->end()->AppendInput(zone(), deopt); @@ -351,10 +467,10 @@ TEST_F(EscapeAnalysisTest, DeoptReplacementIdentity) { Node* object1 = Constant(1); BeginRegion(); Node* allocation = Allocate(Constant(kPointerSize * 2)); - Store(AccessAtIndex(0), allocation, object1); - Store(AccessAtIndex(kPointerSize), allocation, allocation); + Store(FieldAccessAtIndex(0), allocation, object1); + Store(FieldAccessAtIndex(kPointerSize), allocation, allocation); Node* finish = FinishRegion(allocation); - Node* effect1 = Store(AccessAtIndex(0), allocation, object1, finish); + Node* effect1 = Store(FieldAccessAtIndex(0), allocation, object1, finish); Branch(); Node* ifFalse = IfFalse(); Node* state_values1 = graph()->NewNode(common()->StateValues(1), finish); @@ -368,7 +484,7 @@ TEST_F(EscapeAnalysisTest, DeoptReplacementIdentity) { Node* deopt = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), frame_state, effect1, ifFalse); Node* ifTrue = IfTrue(); - Node* load = Load(AccessAtIndex(0), finish, effect1, ifTrue); + Node* load = Load(FieldAccessAtIndex(0), finish, effect1, ifTrue); Node* result = Return(load, effect1, ifTrue); EndGraph(); graph()->end()->AppendInput(zone(), deopt); |