v8/test/unittests/compiler/load-elimination-unittest.cc
bmeurer d70dc1ace4 [turbofan] Initial version of the new LoadElimination.
This adds a new optimization phase to the TurboFan pipeline, which walks
over the effect chain and tries to eliminate redundant loads (and even
some stores) of object fields. We currently ignore element access, but
that will probably need to be handled as well at some point. We also
don't have any special treatment to properly track object maps, which is
also on the list of things that will happen afterwards.

The implementation is pretty simple currently, and probably way to
inefficient. It's meant to be a proof-of-concept to iterate on.

R=jarin@chromium.org
BUG=v8:4930,v8:5141

Review-Url: https://codereview.chromium.org/2120253002
Cr-Commit-Position: refs/heads/master@{#37528}
2016-07-05 12:20:18 +00:00

81 lines
2.8 KiB
C++

// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/load-elimination.h"
#include "src/compiler/access-builder.h"
#include "src/compiler/node.h"
#include "src/compiler/simplified-operator.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
namespace v8 {
namespace internal {
namespace compiler {
class LoadEliminationTest : public TypedGraphTest {
public:
LoadEliminationTest() : TypedGraphTest(3), simplified_(zone()) {}
~LoadEliminationTest() override {}
protected:
void Run() {
LoadElimination load_elimination(graph(), zone());
load_elimination.Run();
}
SimplifiedOperatorBuilder* simplified() { return &simplified_; }
private:
SimplifiedOperatorBuilder simplified_;
};
TEST_F(LoadEliminationTest, LoadFieldAndLoadField) {
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* control = graph()->start();
FieldAccess access = {kTaggedBase,
kPointerSize,
MaybeHandle<Name>(),
Type::Any(),
MachineType::AnyTagged(),
kNoWriteBarrier};
Node* load1 = effect = graph()->NewNode(simplified()->LoadField(access),
object, effect, control);
Node* load2 = effect = graph()->NewNode(simplified()->LoadField(access),
object, effect, control);
control = graph()->NewNode(common()->Return(), load2, effect, control);
graph()->end()->ReplaceInput(0, control);
Run();
EXPECT_THAT(graph()->end(), IsEnd(IsReturn(load1, load1, graph()->start())));
}
TEST_F(LoadEliminationTest, StoreFieldAndLoadField) {
Node* object = Parameter(Type::Any(), 0);
Node* value = Parameter(Type::Any(), 1);
Node* effect = graph()->start();
Node* control = graph()->start();
FieldAccess access = {kTaggedBase,
kPointerSize,
MaybeHandle<Name>(),
Type::Any(),
MachineType::AnyTagged(),
kNoWriteBarrier};
Node* store = effect = graph()->NewNode(simplified()->StoreField(access),
object, value, effect, control);
Node* load = effect = graph()->NewNode(simplified()->LoadField(access),
object, effect, control);
control = graph()->NewNode(common()->Return(), load, effect, control);
graph()->end()->ReplaceInput(0, control);
Run();
EXPECT_THAT(graph()->end(), IsEnd(IsReturn(value, store, graph()->start())));
}
} // namespace compiler
} // namespace internal
} // namespace v8