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