Add support for hydrogen control instructions with >2 successor blocks.

This change makes the number of successors of a control instruction
configurable with a template parameter and changes the existing instructions
to use it.

To iterate over all successors I added an iterator instead of always calling
First- and SecondSuccessor.
Review URL: http://codereview.chromium.org/7114004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8262 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 508b22c4
......@@ -111,21 +111,18 @@ void LInstruction::PrintTo(StringStream* stream) {
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
stream->Add("= ");
inputs_.PrintOperandsTo(stream);
for (int i = 0; i < inputs_.length(); i++) {
if (i > 0) stream->Add(" ");
inputs_[i]->PrintTo(stream);
}
}
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
results_.PrintOperandsTo(stream);
}
template<typename T, int N>
void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
for (int i = 0; i < N; i++) {
for (int i = 0; i < results_.length(); i++) {
if (i > 0) stream->Add(" ");
elems_[i]->PrintTo(stream);
results_[i]->PrintTo(stream);
}
}
......
......@@ -32,6 +32,7 @@
#include "lithium-allocator.h"
#include "lithium.h"
#include "safepoint-table.h"
#include "utils.h"
namespace v8 {
namespace internal {
......@@ -285,37 +286,6 @@ class LInstruction: public ZoneObject {
};
template<typename ElementType, int NumElements>
class OperandContainer {
public:
OperandContainer() {
for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
}
int length() { return NumElements; }
ElementType& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
void PrintOperandsTo(StringStream* stream);
private:
ElementType elems_[NumElements];
};
template<typename ElementType>
class OperandContainer<ElementType, 0> {
public:
int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
};
// R = number of result operands (0 or 1).
// I = number of input operands.
// T = number of temporary operands.
......@@ -338,9 +308,9 @@ class LTemplateInstruction: public LInstruction {
virtual void PrintOutputOperandTo(StringStream* stream);
protected:
OperandContainer<LOperand*, R> results_;
OperandContainer<LOperand*, I> inputs_;
OperandContainer<LOperand*, T> temps_;
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
};
......
......@@ -686,15 +686,13 @@ void HAccessArgumentsAt::PrintDataTo(StringStream* stream) {
void HControlInstruction::PrintDataTo(StringStream* stream) {
if (FirstSuccessor() != NULL) {
int first_id = FirstSuccessor()->block_id();
if (SecondSuccessor() == NULL) {
stream->Add(" B%d", first_id);
} else {
int second_id = SecondSuccessor()->block_id();
stream->Add(" goto (B%d, B%d)", first_id, second_id);
}
stream->Add(" goto (");
bool first_block = true;
for (HSuccessorIterator it(this); !it.Done(); it.Advance()) {
stream->Add(first_block ? "B%d" : ", B%d", it.Current()->block_id());
first_block = false;
}
stream->Add(")");
}
......@@ -704,6 +702,11 @@ void HUnaryControlInstruction::PrintDataTo(StringStream* stream) {
}
void HReturn::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
}
void HCompareMap::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
stream->Add(" (%p)", *map());
......
......@@ -35,6 +35,7 @@
#include "data-flow.h"
#include "small-pointer-list.h"
#include "string-stream.h"
#include "utils.h"
#include "zone.h"
namespace v8 {
......@@ -757,80 +758,69 @@ class HInstruction: public HValue {
};
class HControlInstruction: public HInstruction {
template<int V>
class HTemplateInstruction : public HInstruction {
public:
HControlInstruction(HBasicBlock* first, HBasicBlock* second)
: first_successor_(first), second_successor_(second) {
}
HBasicBlock* FirstSuccessor() const { return first_successor_; }
HBasicBlock* SecondSuccessor() const { return second_successor_; }
virtual void PrintDataTo(StringStream* stream);
int OperandCount() { return V; }
HValue* OperandAt(int i) { return inputs_[i]; }
DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
protected:
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
private:
HBasicBlock* first_successor_;
HBasicBlock* second_successor_;
EmbeddedContainer<HValue*, V> inputs_;
};
template<int NumElements>
class HOperandContainer {
class HControlInstruction: public HInstruction {
public:
HOperandContainer() : elems_() { }
int length() { return NumElements; }
HValue*& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
private:
HValue* elems_[NumElements];
};
virtual HBasicBlock* SuccessorAt(int i) = 0;
virtual int SuccessorCount() = 0;
virtual void PrintDataTo(StringStream* stream);
template<>
class HOperandContainer<0> {
public:
int length() { return 0; }
HValue*& operator[](int i) {
UNREACHABLE();
static HValue* t = 0;
return t;
HBasicBlock* FirstSuccessor() {
return SuccessorCount() > 0 ? SuccessorAt(0) : NULL;
}
HBasicBlock* SecondSuccessor() {
return SuccessorCount() > 1 ? SuccessorAt(1) : NULL;
}
DECLARE_ABSTRACT_INSTRUCTION(ControlInstruction)
};
template<int V>
class HTemplateInstruction : public HInstruction {
class HSuccessorIterator BASE_EMBEDDED {
public:
int OperandCount() { return V; }
HValue* OperandAt(int i) { return inputs_[i]; }
explicit HSuccessorIterator(HControlInstruction* instr)
: instr_(instr), current_(0) { }
protected:
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
bool Done() { return current_ >= instr_->SuccessorCount(); }
HBasicBlock* Current() { return instr_->SuccessorAt(current_); }
void Advance() { current_++; }
private:
HOperandContainer<V> inputs_;
HControlInstruction* instr_;
int current_;
};
template<int V>
class HTemplateControlInstruction : public HControlInstruction {
template<int S, int V>
class HTemplateControlInstruction: public HControlInstruction {
public:
HTemplateControlInstruction<V>(HBasicBlock* first, HBasicBlock* second)
: HControlInstruction(first, second) { }
int SuccessorCount() { return S; }
HBasicBlock* SuccessorAt(int i) { return successors_[i]; }
int OperandCount() { return V; }
HValue* OperandAt(int i) { return inputs_[i]; }
protected:
void SetSuccessorAt(int i, HBasicBlock* block) { successors_[i] = block; }
void InternalSetOperandAt(int i, HValue* value) { inputs_[i] = value; }
private:
HOperandContainer<V> inputs_;
EmbeddedContainer<HBasicBlock*, S> successors_;
EmbeddedContainer<HValue*, V> inputs_;
};
......@@ -859,9 +849,7 @@ class HSoftDeoptimize: public HTemplateInstruction<0> {
class HDeoptimize: public HControlInstruction {
public:
explicit HDeoptimize(int environment_length)
: HControlInstruction(NULL, NULL),
values_(environment_length) { }
explicit HDeoptimize(int environment_length) : values_(environment_length) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
......@@ -871,6 +859,12 @@ class HDeoptimize: public HControlInstruction {
virtual HValue* OperandAt(int index) { return values_[index]; }
virtual void PrintDataTo(StringStream* stream);
virtual int SuccessorCount() { return 0; }
virtual HBasicBlock* SuccessorAt(int i) {
UNREACHABLE();
return NULL;
}
void AddEnvironmentValue(HValue* value) {
values_.Add(NULL);
SetOperandAt(values_.length() - 1, value);
......@@ -893,11 +887,12 @@ class HDeoptimize: public HControlInstruction {
};
class HGoto: public HTemplateControlInstruction<0> {
class HGoto: public HTemplateControlInstruction<1, 0> {
public:
explicit HGoto(HBasicBlock* target)
: HTemplateControlInstruction<0>(target, NULL),
include_stack_check_(false) { }
: include_stack_check_(false) {
SetSuccessorAt(0, target);
}
void set_include_stack_check(bool include_stack_check) {
include_stack_check_ = include_stack_check;
......@@ -915,13 +910,14 @@ class HGoto: public HTemplateControlInstruction<0> {
};
class HUnaryControlInstruction: public HTemplateControlInstruction<1> {
class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
public:
explicit HUnaryControlInstruction(HValue* value,
HBasicBlock* true_target,
HBasicBlock* false_target)
: HTemplateControlInstruction<1>(true_target, false_target) {
HUnaryControlInstruction(HValue* value,
HBasicBlock* true_target,
HBasicBlock* false_target) {
SetOperandAt(0, value);
SetSuccessorAt(0, true_target);
SetSuccessorAt(1, false_target);
}
virtual void PrintDataTo(StringStream* stream);
......@@ -973,24 +969,26 @@ class HCompareMap: public HUnaryControlInstruction {
};
class HReturn: public HUnaryControlInstruction {
class HReturn: public HTemplateControlInstruction<0, 1> {
public:
explicit HReturn(HValue* value)
: HUnaryControlInstruction(value, NULL, NULL) {
explicit HReturn(HValue* value) {
SetOperandAt(0, value);
}
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::Tagged();
}
virtual void PrintDataTo(StringStream* stream);
HValue* value() { return OperandAt(0); }
DECLARE_CONCRETE_INSTRUCTION(Return)
};
class HAbnormalExit: public HTemplateControlInstruction<0> {
class HAbnormalExit: public HTemplateControlInstruction<0, 0> {
public:
HAbnormalExit() : HTemplateControlInstruction<0>(NULL, NULL) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
......
......@@ -157,11 +157,8 @@ void HBasicBlock::Finish(HControlInstruction* end) {
ASSERT(!IsFinished());
AddInstruction(end);
end_ = end;
if (end->FirstSuccessor() != NULL) {
end->FirstSuccessor()->RegisterPredecessor(this);
if (end->SecondSuccessor() != NULL) {
end->SecondSuccessor()->RegisterPredecessor(this);
}
for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
it.Current()->RegisterPredecessor(this);
}
}
......@@ -401,8 +398,9 @@ class ReachabilityAnalyzer BASE_EMBEDDED {
void Analyze() {
while (!stack_.is_empty()) {
HControlInstruction* end = stack_.RemoveLast()->end();
PushBlock(end->FirstSuccessor());
PushBlock(end->SecondSuccessor());
for (HSuccessorIterator it(end); !it.Done(); it.Advance()) {
PushBlock(it.Current());
}
}
}
......@@ -697,8 +695,9 @@ void HGraph::PostorderLoopBlocks(HLoopInformation* loop,
HBasicBlock* loop_header) {
for (int i = 0; i < loop->blocks()->length(); ++i) {
HBasicBlock* b = loop->blocks()->at(i);
Postorder(b->end()->SecondSuccessor(), visited, order, loop_header);
Postorder(b->end()->FirstSuccessor(), visited, order, loop_header);
for (HSuccessorIterator it(b->end()); !it.Done(); it.Advance()) {
Postorder(it.Current(), visited, order, loop_header);
}
if (b->IsLoopHeader() && b != loop->loop_header()) {
PostorderLoopBlocks(b->loop_information(), visited, order, loop_header);
}
......@@ -715,11 +714,13 @@ void HGraph::Postorder(HBasicBlock* block,
visited->Add(block->block_id());
if (block->IsLoopHeader()) {
PostorderLoopBlocks(block->loop_information(), visited, order, loop_header);
Postorder(block->end()->SecondSuccessor(), visited, order, block);
Postorder(block->end()->FirstSuccessor(), visited, order, block);
for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
Postorder(it.Current(), visited, order, block);
}
} else {
Postorder(block->end()->SecondSuccessor(), visited, order, loop_header);
Postorder(block->end()->FirstSuccessor(), visited, order, loop_header);
for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
Postorder(it.Current(), visited, order, loop_header);
}
}
ASSERT(block->end()->FirstSuccessor() == NULL ||
order->Contains(block->end()->FirstSuccessor()) ||
......@@ -6139,15 +6140,15 @@ void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) {
PrintEmptyProperty("predecessors");
}
if (current->end() == NULL || current->end()->FirstSuccessor() == NULL) {
if (current->end()->SuccessorCount() == 0) {
PrintEmptyProperty("successors");
} else if (current->end()->SecondSuccessor() == NULL) {
PrintBlockProperty("successors",
current->end()->FirstSuccessor()->block_id());
} else {
PrintBlockProperty("successors",
current->end()->FirstSuccessor()->block_id(),
current->end()->SecondSuccessor()->block_id());
} else {
PrintIndent();
trace_.Add("successors");
for (HSuccessorIterator it(current->end()); !it.Done(); it.Advance()) {
trace_.Add(" \"B%d\"", it.Current()->block_id());
}
trace_.Add("\n");
}
PrintEmptyProperty("xhandlers");
......
......@@ -1179,11 +1179,6 @@ class HTracer: public Malloced {
trace_.Add("%s \"B%d\"\n", name, block_id);
}
void PrintBlockProperty(const char* name, int block_id1, int block_id2) {
PrintIndent();
trace_.Add("%s \"B%d\" \"B%d\"\n", name, block_id1, block_id2);
}
void PrintIntProperty(const char* name, int value) {
PrintIndent();
trace_.Add("%s %d\n", name, value);
......
......@@ -113,21 +113,18 @@ void LInstruction::PrintTo(StringStream* stream) {
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
stream->Add("= ");
inputs_.PrintOperandsTo(stream);
for (int i = 0; i < inputs_.length(); i++) {
if (i > 0) stream->Add(" ");
inputs_[i]->PrintTo(stream);
}
}
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
results_.PrintOperandsTo(stream);
}
template<typename T, int N>
void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
for (int i = 0; i < N; i++) {
for (int i = 0; i < results_.length(); i++) {
if (i > 0) stream->Add(" ");
elems_[i]->PrintTo(stream);
results_[i]->PrintTo(stream);
}
}
......
......@@ -32,6 +32,7 @@
#include "lithium-allocator.h"
#include "lithium.h"
#include "safepoint-table.h"
#include "utils.h"
namespace v8 {
namespace internal {
......@@ -280,37 +281,6 @@ class LInstruction: public ZoneObject {
};
template<typename ElementType, int NumElements>
class OperandContainer {
public:
OperandContainer() {
for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
}
int length() { return NumElements; }
ElementType& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
void PrintOperandsTo(StringStream* stream);
private:
ElementType elems_[NumElements];
};
template<typename ElementType>
class OperandContainer<ElementType, 0> {
public:
int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
};
// R = number of result operands (0 or 1).
// I = number of input operands.
// T = number of temporary operands.
......@@ -333,9 +303,9 @@ class LTemplateInstruction: public LInstruction {
virtual void PrintOutputOperandTo(StringStream* stream);
protected:
OperandContainer<LOperand*, R> results_;
OperandContainer<LOperand*, I> inputs_;
OperandContainer<LOperand*, T> temps_;
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
};
......
......@@ -575,10 +575,10 @@ BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) {
BitVector* live_out = new BitVector(next_virtual_register_);
// Process all successor blocks.
HBasicBlock* successor = block->end()->FirstSuccessor();
while (successor != NULL) {
for (HSuccessorIterator it(block->end()); !it.Done(); it.Advance()) {
// Add values live on entry to the successor. Note the successor's
// live_in will not be computed yet for backwards edges.
HBasicBlock* successor = it.Current();
BitVector* live_in = live_in_sets_[successor->block_id()];
if (live_in != NULL) live_out->Union(*live_in);
......@@ -592,11 +592,6 @@ BitVector* LAllocator::ComputeLiveOut(HBasicBlock* block) {
live_out->Add(phi->OperandAt(index)->id());
}
}
// Check if we are done with second successor.
if (successor == block->end()->SecondSuccessor()) break;
successor = block->end()->SecondSuccessor();
}
return live_out;
......
......@@ -793,6 +793,35 @@ inline Dest BitCast(const Source& source) {
return BitCastHelper<Dest, Source>::cast(source);
}
template<typename ElementType, int NumElements>
class EmbeddedContainer {
public:
EmbeddedContainer() : elems_() { }
int length() { return NumElements; }
ElementType& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
private:
ElementType elems_[NumElements];
};
template<typename ElementType>
class EmbeddedContainer<ElementType, 0> {
public:
int length() { return 0; }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
};
} } // namespace v8::internal
#endif // V8_UTILS_H_
......@@ -113,21 +113,18 @@ void LInstruction::PrintTo(StringStream* stream) {
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
stream->Add("= ");
inputs_.PrintOperandsTo(stream);
for (int i = 0; i < inputs_.length(); i++) {
if (i > 0) stream->Add(" ");
inputs_[i]->PrintTo(stream);
}
}
template<int R, int I, int T>
void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
results_.PrintOperandsTo(stream);
}
template<typename T, int N>
void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
for (int i = 0; i < N; i++) {
for (int i = 0; i < results_.length(); i++) {
if (i > 0) stream->Add(" ");
elems_[i]->PrintTo(stream);
results_[i]->PrintTo(stream);
}
}
......
......@@ -32,6 +32,7 @@
#include "lithium-allocator.h"
#include "lithium.h"
#include "safepoint-table.h"
#include "utils.h"
namespace v8 {
namespace internal {
......@@ -286,37 +287,6 @@ class LInstruction: public ZoneObject {
};
template<typename ElementType, int NumElements>
class OperandContainer {
public:
OperandContainer() {
for (int i = 0; i < NumElements; i++) elems_[i] = NULL;
}
int length() { return NumElements; }
ElementType& operator[](int i) {
ASSERT(i < length());
return elems_[i];
}
void PrintOperandsTo(StringStream* stream);
private:
ElementType elems_[NumElements];
};
template<typename ElementType>
class OperandContainer<ElementType, 0> {
public:
int length() { return 0; }
void PrintOperandsTo(StringStream* stream) { }
ElementType& operator[](int i) {
UNREACHABLE();
static ElementType t = 0;
return t;
}
};
// R = number of result operands (0 or 1).
// I = number of input operands.
// T = number of temporary operands.
......@@ -339,9 +309,9 @@ class LTemplateInstruction: public LInstruction {
virtual void PrintOutputOperandTo(StringStream* stream);
protected:
OperandContainer<LOperand*, R> results_;
OperandContainer<LOperand*, I> inputs_;
OperandContainer<LOperand*, T> temps_;
EmbeddedContainer<LOperand*, R> results_;
EmbeddedContainer<LOperand*, I> inputs_;
EmbeddedContainer<LOperand*, T> temps_;
};
......
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