[interpreter] Simplify BytecodeBranchAnalysis to minimum.

This simplifies the branch analysis we perform on the bytecode stream
down to the bare minimum that we need to build graphs. Note that we
still record all branch targets, even though only the backwards ones
would be needed, but this is essentially for free and might be useful
eventually.

R=oth@chromium.org

Review URL: https://codereview.chromium.org/1646873004

Cr-Commit-Position: refs/heads/master@{#33635}
This commit is contained in:
mstarzinger 2016-02-01 02:46:57 -08:00 committed by Commit bot
parent 83a2c8ed7f
commit c207f10b09
2 changed files with 16 additions and 86 deletions

View File

@ -11,47 +11,13 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
// The class contains all of the sites that contain
// branches to a particular target (bytecode offset).
class BytecodeBranchInfo final : public ZoneObject {
public:
explicit BytecodeBranchInfo(Zone* zone)
: back_edge_offsets_(zone), fore_edge_offsets_(zone) {}
void AddBranch(int source_offset, int target_offset);
// The offsets of bytecodes that refer to this bytecode as
// a back-edge predecessor.
const ZoneVector<int>* back_edge_offsets() { return &back_edge_offsets_; }
// The offsets of bytecodes that refer to this bytecode as
// a forwards-edge predecessor.
const ZoneVector<int>* fore_edge_offsets() { return &fore_edge_offsets_; }
private:
ZoneVector<int> back_edge_offsets_;
ZoneVector<int> fore_edge_offsets_;
DISALLOW_COPY_AND_ASSIGN(BytecodeBranchInfo);
};
void BytecodeBranchInfo::AddBranch(int source_offset, int target_offset) {
if (source_offset < target_offset) {
fore_edge_offsets_.push_back(source_offset);
} else {
back_edge_offsets_.push_back(source_offset);
}
}
BytecodeBranchAnalysis::BytecodeBranchAnalysis( BytecodeBranchAnalysis::BytecodeBranchAnalysis(
Handle<BytecodeArray> bytecode_array, Zone* zone) Handle<BytecodeArray> bytecode_array, Zone* zone)
: branch_infos_(zone), : bytecode_array_(bytecode_array),
bytecode_array_(bytecode_array), is_backward_target_(bytecode_array->length(), zone),
is_forward_target_(bytecode_array->length(), zone),
zone_(zone) {} zone_(zone) {}
void BytecodeBranchAnalysis::Analyze() { void BytecodeBranchAnalysis::Analyze() {
interpreter::BytecodeArrayIterator iterator(bytecode_array()); interpreter::BytecodeArrayIterator iterator(bytecode_array());
while (!iterator.done()) { while (!iterator.done()) {
@ -64,38 +30,12 @@ void BytecodeBranchAnalysis::Analyze() {
} }
} }
const ZoneVector<int>* BytecodeBranchAnalysis::BackwardBranchesTargetting(
int offset) const {
auto iterator = branch_infos_.find(offset);
if (branch_infos_.end() != iterator) {
return iterator->second->back_edge_offsets();
} else {
return nullptr;
}
}
const ZoneVector<int>* BytecodeBranchAnalysis::ForwardBranchesTargetting(
int offset) const {
auto iterator = branch_infos_.find(offset);
if (branch_infos_.end() != iterator) {
return iterator->second->fore_edge_offsets();
} else {
return nullptr;
}
}
void BytecodeBranchAnalysis::AddBranch(int source_offset, int target_offset) { void BytecodeBranchAnalysis::AddBranch(int source_offset, int target_offset) {
BytecodeBranchInfo* branch_info = nullptr; if (source_offset < target_offset) {
auto iterator = branch_infos_.find(target_offset); is_forward_target_.Add(target_offset);
if (branch_infos_.end() == iterator) {
branch_info = new (zone()) BytecodeBranchInfo(zone());
branch_infos_.insert(std::make_pair(target_offset, branch_info));
} else { } else {
branch_info = iterator->second; is_backward_target_.Add(target_offset);
} }
branch_info->AddBranch(source_offset, target_offset);
} }
} // namespace compiler } // namespace compiler

View File

@ -7,7 +7,6 @@
#include "src/bit-vector.h" #include "src/bit-vector.h"
#include "src/handles.h" #include "src/handles.h"
#include "src/zone-containers.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
@ -16,15 +15,13 @@ class BytecodeArray;
namespace compiler { namespace compiler {
class BytecodeBranchInfo; // A class for identifying branch targets within a bytecode array.
// This information can be used to construct the local control flow
// A class for identifying the branch targets and their branch sites // logic for high-level IR graphs built from bytecode.
// within a bytecode array. This information can be used to construct
// the local control flow logic for high-level IR graphs built from
// bytecode.
// //
// NB This class relies on the only backwards branches in bytecode // N.B. If this class is used to determine loop headers, then such a
// being jumps back to loop headers. // usage relies on the only backwards branches in bytecode being jumps
// back to loop headers.
class BytecodeBranchAnalysis BASE_EMBEDDED { class BytecodeBranchAnalysis BASE_EMBEDDED {
public: public:
BytecodeBranchAnalysis(Handle<BytecodeArray> bytecode_array, Zone* zone); BytecodeBranchAnalysis(Handle<BytecodeArray> bytecode_array, Zone* zone);
@ -37,31 +34,24 @@ class BytecodeBranchAnalysis BASE_EMBEDDED {
// Returns true if there are any forward branches to the bytecode at // Returns true if there are any forward branches to the bytecode at
// |offset|. // |offset|.
bool forward_branches_target(int offset) const { bool forward_branches_target(int offset) const {
const ZoneVector<int>* sites = ForwardBranchesTargetting(offset); return is_forward_target_.Contains(offset);
return sites != nullptr && sites->size() > 0;
} }
// Returns true if there are any backward branches to the bytecode // Returns true if there are any backward branches to the bytecode
// at |offset|. // at |offset|.
bool backward_branches_target(int offset) const { bool backward_branches_target(int offset) const {
const ZoneVector<int>* sites = BackwardBranchesTargetting(offset); return is_backward_target_.Contains(offset);
return sites != nullptr && sites->size() > 0;
} }
private: private:
void AddBranch(int origin_offset, int target_offset); void AddBranch(int origin_offset, int target_offset);
// Offsets of bytecodes having a backward branch to the bytecode at |offset|.
const ZoneVector<int>* BackwardBranchesTargetting(int offset) const;
// Offsets of bytecodes having a forward branch to the bytecode at |offset|.
const ZoneVector<int>* ForwardBranchesTargetting(int offset) const;
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; } Handle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
ZoneMap<int, BytecodeBranchInfo*> branch_infos_;
Handle<BytecodeArray> bytecode_array_; Handle<BytecodeArray> bytecode_array_;
BitVector is_backward_target_;
BitVector is_forward_target_;
Zone* zone_; Zone* zone_;
DISALLOW_COPY_AND_ASSIGN(BytecodeBranchAnalysis); DISALLOW_COPY_AND_ASSIGN(BytecodeBranchAnalysis);