Commit 7b64e8d1 authored by leszeks's avatar leszeks Committed by Commit bot

[ignition/turbofan] Wrap bytecode liveness bitvectors

Wrap the liveness bitvectors from the bytecode liveness analysis with a
helper class, which makes the register/accumulator bits explicit.

Review-Url: https://codereview.chromium.org/2552723004
Cr-Commit-Position: refs/heads/master@{#41589}
parent 98b563eb
......@@ -166,7 +166,7 @@ class BitVector : public ZoneObject {
return true;
}
bool Equals(const BitVector& other) {
bool Equals(const BitVector& other) const {
for (int i = 0; i < data_length_; i++) {
if (data_[i] != other.data_[i]) return false;
}
......
This diff is collapsed.
......@@ -36,17 +36,11 @@ class V8_EXPORT_PRIVATE BytecodeAnalysis BASE_EMBEDDED {
// at {header_offset}, or -1 for outer-most loops.
int GetParentLoopFor(int header_offset) const;
// Gets the in-liveness for the bytecode at {offset}. The liveness bit vector
// represents the liveness of the registers and the accumulator, with the last
// bit being the accumulator liveness bit, and so is (register count + 1) bits
// long.
const BitVector* GetInLivenessFor(int offset) const;
// Gets the out-liveness for the bytecode at {offset}. The liveness bit vector
// represents the liveness of the registers and the accumulator, with the last
// bit being the accumulator liveness bit, and so is (register count + 1) bits
// long.
const BitVector* GetOutLivenessFor(int offset) const;
// Gets the in-liveness for the bytecode at {offset}.
const BytecodeLivenessState* GetInLivenessFor(int offset) const;
// Gets the out-liveness for the bytecode at {offset}.
const BytecodeLivenessState* GetOutLivenessFor(int offset) const;
std::ostream& PrintLivenessTo(std::ostream& os) const;
......
......@@ -56,7 +56,8 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
// Preserve a checkpoint of the environment for the IR graph. Any
// further mutation of the environment will not affect checkpoints.
Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
bool owner_has_exception, const BitVector* liveness);
bool owner_has_exception,
const BytecodeLivenessState* liveness);
// Control dependency tracked by this environment.
Node* GetControlDependency() const { return control_dependency_; }
......@@ -410,7 +411,7 @@ void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache(
Node* BytecodeGraphBuilder::Environment::Checkpoint(
BailoutId bailout_id, OutputFrameStateCombine combine,
bool owner_has_exception, const BitVector* liveness) {
bool owner_has_exception, const BytecodeLivenessState* liveness) {
UpdateStateValues(&parameters_state_values_, &values()->at(0),
parameter_count());
......@@ -418,12 +419,12 @@ Node* BytecodeGraphBuilder::Environment::Checkpoint(
Node* optimized_out = builder()->jsgraph()->OptimizedOutConstant();
for (int i = 0; i < register_count(); ++i) {
state_value_working_area_[i] = liveness->Contains(i)
state_value_working_area_[i] = liveness->RegisterIsLive(i)
? values()->at(register_base() + i)
: optimized_out;
}
Node* accumulator_value = liveness->Contains(register_count())
Node* accumulator_value = liveness->AccumulatorIsLive()
? values()->at(accumulator_base())
: optimized_out;
......@@ -570,8 +571,9 @@ void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
NodeProperties::GetFrameStateInput(node)->opcode());
BailoutId bailout_id(bytecode_iterator().current_offset());
const BitVector* liveness_before = bytecode_analysis()->GetInLivenessFor(
bytecode_iterator().current_offset());
const BytecodeLivenessState* liveness_before =
bytecode_analysis()->GetInLivenessFor(
bytecode_iterator().current_offset());
Node* frame_state_before = environment()->Checkpoint(
bailout_id, OutputFrameStateCombine::Ignore(), false, liveness_before);
......@@ -590,8 +592,9 @@ void BytecodeGraphBuilder::PrepareFrameState(Node* node,
BailoutId bailout_id(bytecode_iterator().current_offset());
bool has_exception = NodeProperties::IsExceptionalCall(node);
const BitVector* liveness_after = bytecode_analysis()->GetOutLivenessFor(
bytecode_iterator().current_offset());
const BytecodeLivenessState* liveness_after =
bytecode_analysis()->GetOutLivenessFor(
bytecode_iterator().current_offset());
Node* frame_state_after = environment()->Checkpoint(
bailout_id, combine, has_exception, liveness_after);
......
......@@ -8,9 +8,9 @@ namespace v8 {
namespace internal {
namespace compiler {
Liveness::Liveness(int size, Zone* zone)
: in(new (zone) BitVector(size, zone)),
out(new (zone) BitVector(size, zone)) {}
BytecodeLiveness::BytecodeLiveness(int register_count, Zone* zone)
: in(new (zone) BytecodeLivenessState(register_count, zone)),
out(new (zone) BytecodeLivenessState(register_count, zone)) {}
BytecodeLivenessMap::BytecodeLivenessMap(int bytecode_size, Zone* zone)
: liveness_map_(base::bits::RoundUpToPowerOfTwo32(bytecode_size / 4 + 1),
......@@ -19,20 +19,21 @@ BytecodeLivenessMap::BytecodeLivenessMap(int bytecode_size, Zone* zone)
uint32_t OffsetHash(int offset) { return offset; }
Liveness& BytecodeLivenessMap::InitializeLiveness(int offset, int size,
Zone* zone) {
BytecodeLiveness& BytecodeLivenessMap::InitializeLiveness(int offset,
int register_count,
Zone* zone) {
return liveness_map_
.LookupOrInsert(offset, OffsetHash(offset),
[&]() { return Liveness(size, zone); },
[&]() { return BytecodeLiveness(register_count, zone); },
ZoneAllocationPolicy(zone))
->value;
}
Liveness& BytecodeLivenessMap::GetLiveness(int offset) {
BytecodeLiveness& BytecodeLivenessMap::GetLiveness(int offset) {
return liveness_map_.Lookup(offset, OffsetHash(offset))->value;
}
const Liveness& BytecodeLivenessMap::GetLiveness(int offset) const {
const BytecodeLiveness& BytecodeLivenessMap::GetLiveness(int offset) const {
return liveness_map_.Lookup(offset, OffsetHash(offset))->value;
}
......
......@@ -16,35 +16,99 @@ class Zone;
namespace compiler {
struct Liveness {
BitVector* in;
BitVector* out;
class BytecodeLivenessState : public ZoneObject {
public:
BytecodeLivenessState(int register_count, Zone* zone)
: bit_vector_(register_count + 1, zone) {}
const BitVector& bit_vector() const { return bit_vector_; }
BitVector& bit_vector() { return bit_vector_; }
bool RegisterIsLive(int index) const {
DCHECK_GE(index, 0);
DCHECK_LT(index, bit_vector_.length() - 1);
return bit_vector_.Contains(index);
}
bool AccumulatorIsLive() const {
return bit_vector_.Contains(bit_vector_.length() - 1);
}
bool Equals(const BytecodeLivenessState& other) const {
return bit_vector_.Equals(other.bit_vector_);
}
void MarkRegisterLive(int index) {
DCHECK_GE(index, 0);
DCHECK_LT(index, bit_vector_.length() - 1);
bit_vector_.Add(index);
}
void MarkRegisterDead(int index) {
DCHECK_GE(index, 0);
DCHECK_LT(index, bit_vector_.length() - 1);
bit_vector_.Remove(index);
}
void MarkAccumulatorLive() { bit_vector_.Add(bit_vector_.length() - 1); }
void MarkAccumulatorDead() { bit_vector_.Remove(bit_vector_.length() - 1); }
void MarkAllLive() { bit_vector_.AddAll(); }
Liveness(int size, Zone* zone);
void Union(const BytecodeLivenessState& other) {
bit_vector_.Union(other.bit_vector_);
}
bool UnionIsChanged(const BytecodeLivenessState& other) {
return bit_vector_.UnionIsChanged(other.bit_vector_);
}
void CopyFrom(const BytecodeLivenessState& other) {
bit_vector_.CopyFrom(other.bit_vector_);
}
private:
BitVector bit_vector_;
DISALLOW_COPY_AND_ASSIGN(BytecodeLivenessState);
};
struct BytecodeLiveness {
BytecodeLivenessState* in;
BytecodeLivenessState* out;
BytecodeLiveness(int register_count, Zone* zone);
};
class V8_EXPORT_PRIVATE BytecodeLivenessMap {
public:
BytecodeLivenessMap(int size, Zone* zone);
Liveness& InitializeLiveness(int offset, int size, Zone* zone);
BytecodeLiveness& InitializeLiveness(int offset, int register_count,
Zone* zone);
Liveness& GetLiveness(int offset);
const Liveness& GetLiveness(int offset) const;
BytecodeLiveness& GetLiveness(int offset);
const BytecodeLiveness& GetLiveness(int offset) const;
BitVector* GetInLiveness(int offset) { return GetLiveness(offset).in; }
const BitVector* GetInLiveness(int offset) const {
BytecodeLivenessState* GetInLiveness(int offset) {
return GetLiveness(offset).in;
}
const BytecodeLivenessState* GetInLiveness(int offset) const {
return GetLiveness(offset).in;
}
BitVector* GetOutLiveness(int offset) { return GetLiveness(offset).out; }
const BitVector* GetOutLiveness(int offset) const {
BytecodeLivenessState* GetOutLiveness(int offset) {
return GetLiveness(offset).out;
}
const BytecodeLivenessState* GetOutLiveness(int offset) const {
return GetLiveness(offset).out;
}
private:
base::TemplateHashMapImpl<int, Liveness, base::KeyEqualityMatcher<int>,
ZoneAllocationPolicy>
base::TemplateHashMapImpl<int, BytecodeLiveness,
base::KeyEqualityMatcher<int>, ZoneAllocationPolicy>
liveness_map_;
};
......
......@@ -37,11 +37,13 @@ class BytecodeAnalysisTest : public TestWithIsolateAndZone {
i::FLAG_ignition_reo = old_FLAG_ignition_reo_;
}
std::string ToLivenessString(const BitVector* liveness) const {
std::string ToLivenessString(const BytecodeLivenessState* liveness) const {
const BitVector& bit_vector = liveness->bit_vector();
std::string out;
out.resize(liveness->length());
for (int i = 0; i < liveness->length(); ++i) {
if (liveness->Contains(i)) {
out.resize(bit_vector.length());
for (int i = 0; i < bit_vector.length(); ++i) {
if (bit_vector.Contains(i)) {
out[i] = 'L';
} else {
out[i] = '.';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment