Commit 951b64d5 authored by sanjoy@chromium.org's avatar sanjoy@chromium.org

Remove duplicated LChunk code.

Divide the LChunk class into an arch-independent LChunkBase and an
arch-dependent LChunk which inherits from LChunkBase.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10701141

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12045 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ef701cb7
...@@ -407,16 +407,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) { ...@@ -407,16 +407,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
} }
LChunk::LChunk(CompilationInfo* info, HGraph* graph)
: spill_slot_count_(0),
info_(info),
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
inlined_closures_(1, graph->zone()) {
}
int LChunk::GetNextSpillIndex(bool is_double) { int LChunk::GetNextSpillIndex(bool is_double) {
// Skip a slot if for a double-width slot. // Skip a slot if for a double-width slot.
if (is_double) spill_slot_count_++; if (is_double) spill_slot_count_++;
...@@ -434,117 +424,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) { ...@@ -434,117 +424,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
} }
void LChunk::MarkEmptyBlocks() {
HPhase phase("L_Mark empty blocks", this);
for (int i = 0; i < graph()->blocks()->length(); ++i) {
HBasicBlock* block = graph()->blocks()->at(i);
int first = block->first_instruction_index();
int last = block->last_instruction_index();
LInstruction* first_instr = instructions()->at(first);
LInstruction* last_instr = instructions()->at(last);
LLabel* label = LLabel::cast(first_instr);
if (last_instr->IsGoto()) {
LGoto* goto_instr = LGoto::cast(last_instr);
if (label->IsRedundant() &&
!label->is_loop_header()) {
bool can_eliminate = true;
for (int i = first + 1; i < last && can_eliminate; ++i) {
LInstruction* cur = instructions()->at(i);
if (cur->IsGap()) {
LGap* gap = LGap::cast(cur);
if (!gap->IsRedundant()) {
can_eliminate = false;
}
} else {
can_eliminate = false;
}
}
if (can_eliminate) {
label->set_replacement(GetLabel(goto_instr->block_id()));
}
}
}
}
}
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap, zone());
index = instructions_.length();
instructions_.Add(instr, zone());
} else {
index = instructions_.length();
instructions_.Add(instr, zone());
instructions_.Add(gap, zone());
}
if (instr->HasPointerMap()) {
pointer_maps_.Add(instr->pointer_map(), zone());
instr->pointer_map()->set_lithium_position(index);
}
}
LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
int LChunk::GetParameterStackSlot(int index) const {
// The receiver is at index 0, the first parameter at index 1, so we
// shift all parameter indexes down by the number of parameters, and
// make sure they end up negative so they are distinguishable from
// spill slots.
int result = index - info()->scope()->num_parameters() - 1;
ASSERT(result < 0);
return result;
}
// A parameter relative to ebp in the arguments stub.
int LChunk::ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver.
return (1 + info()->scope()->num_parameters() - index) *
kPointerSize;
}
LGap* LChunk::GetGapAt(int index) const {
return LGap::cast(instructions_[index]);
}
bool LChunk::IsGapAt(int index) const {
return instructions_[index]->IsGap();
}
int LChunk::NearestGapPos(int index) const {
while (!IsGapAt(index)) index--;
return index;
}
void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
GetGapAt(index)->GetOrCreateParallelMove(
LGap::START, zone())->AddMove(from, to, zone());
}
Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
}
Representation LChunk::LookupLiteralRepresentation(
LConstantOperand* operand) const {
return graph_->LookupValue(operand->index())->representation();
}
LChunk* LChunkBuilder::Build() { LChunk* LChunkBuilder::Build() {
ASSERT(is_unused()); ASSERT(is_unused());
chunk_ = new(zone()) LChunk(info(), graph()); chunk_ = new(zone()) LChunk(info(), graph());
......
...@@ -2224,65 +2224,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { ...@@ -2224,65 +2224,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder; class LChunkBuilder;
class LChunk: public ZoneObject { class LChunk: public LChunkBase {
public: public:
explicit LChunk(CompilationInfo* info, HGraph* graph); explicit LChunk(CompilationInfo* info, HGraph* graph)
: LChunkBase(info, graph) { }
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
int GetNextSpillIndex(bool is_double); int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double); LOperand* GetNextSpillSlot(bool is_double);
int ParameterAt(int index);
int GetParameterStackSlot(int index) const;
int spill_slot_count() const { return spill_slot_count_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
void AddGapMove(int index, LOperand* from, LOperand* to);
LGap* GetGapAt(int index) const;
bool IsGapAt(int index) const;
int NearestGapPos(int index) const;
void MarkEmptyBlocks();
const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
LLabel* GetLabel(int block_id) const {
HBasicBlock* block = graph_->blocks()->at(block_id);
int first_instruction = block->first_instruction_index();
return LLabel::cast(instructions_[first_instruction]);
}
int LookupDestination(int block_id) const {
LLabel* cur = GetLabel(block_id);
while (cur->replacement() != NULL) {
cur = cur->replacement();
}
return cur->block_id();
}
Label* GetAssemblyLabel(int block_id) const {
LLabel* label = GetLabel(block_id);
ASSERT(!label->HasReplacement());
return label->label();
}
const ZoneList<Handle<JSFunction> >* inlined_closures() const {
return &inlined_closures_;
}
void AddInlinedClosure(Handle<JSFunction> closure) {
inlined_closures_.Add(closure, zone());
}
Zone* zone() const { return graph_->zone(); }
private:
int spill_slot_count_;
CompilationInfo* info_;
HGraph* const graph_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
}; };
......
...@@ -9251,7 +9251,7 @@ void HTracer::TraceCompilation(FunctionLiteral* function) { ...@@ -9251,7 +9251,7 @@ void HTracer::TraceCompilation(FunctionLiteral* function) {
} }
void HTracer::TraceLithium(const char* name, LChunk* chunk) { void HTracer::TraceLithium(const char* name, LChunkBase* chunk) {
Trace(name, chunk->graph(), chunk); Trace(name, chunk->graph(), chunk);
} }
...@@ -9261,7 +9261,7 @@ void HTracer::TraceHydrogen(const char* name, HGraph* graph) { ...@@ -9261,7 +9261,7 @@ void HTracer::TraceHydrogen(const char* name, HGraph* graph) {
} }
void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { void HTracer::Trace(const char* name, HGraph* graph, LChunkBase* chunk) {
Tag tag(this, "cfg"); Tag tag(this, "cfg");
PrintStringProperty("name", name); PrintStringProperty("name", name);
const ZoneList<HBasicBlock*>* blocks = graph->blocks(); const ZoneList<HBasicBlock*>* blocks = graph->blocks();
...@@ -9523,7 +9523,7 @@ const char* const HPhase::kTotal = "Total"; ...@@ -9523,7 +9523,7 @@ const char* const HPhase::kTotal = "Total";
void HPhase::Begin(const char* name, void HPhase::Begin(const char* name,
HGraph* graph, HGraph* graph,
LChunk* chunk, LChunkBase* chunk,
LAllocator* allocator) { LAllocator* allocator) {
name_ = name; name_ = name;
graph_ = graph; graph_ = graph;
......
...@@ -48,7 +48,7 @@ class HGraph; ...@@ -48,7 +48,7 @@ class HGraph;
class HLoopInformation; class HLoopInformation;
class HTracer; class HTracer;
class LAllocator; class LAllocator;
class LChunk; class LChunkBase;
class LiveRange; class LiveRange;
...@@ -1334,7 +1334,7 @@ class HPhase BASE_EMBEDDED { ...@@ -1334,7 +1334,7 @@ class HPhase BASE_EMBEDDED {
HPhase(const char* name, HGraph* graph) { HPhase(const char* name, HGraph* graph) {
Begin(name, graph, NULL, NULL); Begin(name, graph, NULL, NULL);
} }
HPhase(const char* name, LChunk* chunk) { HPhase(const char* name, LChunkBase* chunk) {
Begin(name, NULL, chunk, NULL); Begin(name, NULL, chunk, NULL);
} }
HPhase(const char* name, LAllocator* allocator) { HPhase(const char* name, LAllocator* allocator) {
...@@ -1348,14 +1348,14 @@ class HPhase BASE_EMBEDDED { ...@@ -1348,14 +1348,14 @@ class HPhase BASE_EMBEDDED {
private: private:
void Begin(const char* name, void Begin(const char* name,
HGraph* graph, HGraph* graph,
LChunk* chunk, LChunkBase* chunk,
LAllocator* allocator); LAllocator* allocator);
void End() const; void End() const;
int64_t start_; int64_t start_;
const char* name_; const char* name_;
HGraph* graph_; HGraph* graph_;
LChunk* chunk_; LChunkBase* chunk_;
LAllocator* allocator_; LAllocator* allocator_;
unsigned start_allocation_size_; unsigned start_allocation_size_;
}; };
...@@ -1365,7 +1365,7 @@ class HTracer: public Malloced { ...@@ -1365,7 +1365,7 @@ class HTracer: public Malloced {
public: public:
void TraceCompilation(FunctionLiteral* function); void TraceCompilation(FunctionLiteral* function);
void TraceHydrogen(const char* name, HGraph* graph); void TraceHydrogen(const char* name, HGraph* graph);
void TraceLithium(const char* name, LChunk* chunk); void TraceLithium(const char* name, LChunkBase* chunk);
void TraceLiveRanges(const char* name, LAllocator* allocator); void TraceLiveRanges(const char* name, LAllocator* allocator);
static HTracer* Instance() { static HTracer* Instance() {
...@@ -1406,7 +1406,7 @@ class HTracer: public Malloced { ...@@ -1406,7 +1406,7 @@ class HTracer: public Malloced {
} }
void TraceLiveRange(LiveRange* range, const char* type, Zone* zone); void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
void Trace(const char* name, HGraph* graph, LChunk* chunk); void Trace(const char* name, HGraph* graph, LChunkBase* chunk);
void FlushToFile(); void FlushToFile();
void PrintEmptyProperty(const char* name) { void PrintEmptyProperty(const char* name) {
......
...@@ -387,42 +387,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) { ...@@ -387,42 +387,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
} }
void LChunk::MarkEmptyBlocks() {
HPhase phase("L_Mark empty blocks", this);
for (int i = 0; i < graph()->blocks()->length(); ++i) {
HBasicBlock* block = graph()->blocks()->at(i);
int first = block->first_instruction_index();
int last = block->last_instruction_index();
LInstruction* first_instr = instructions()->at(first);
LInstruction* last_instr = instructions()->at(last);
LLabel* label = LLabel::cast(first_instr);
if (last_instr->IsGoto()) {
LGoto* goto_instr = LGoto::cast(last_instr);
if (label->IsRedundant() &&
!label->is_loop_header()) {
bool can_eliminate = true;
for (int i = first + 1; i < last && can_eliminate; ++i) {
LInstruction* cur = instructions()->at(i);
if (cur->IsGap()) {
LGap* gap = LGap::cast(cur);
if (!gap->IsRedundant()) {
can_eliminate = false;
}
} else {
can_eliminate = false;
}
}
if (can_eliminate) {
label->set_replacement(GetLabel(goto_instr->block_id()));
}
}
}
}
}
void LStoreNamedField::PrintDataTo(StringStream* stream) { void LStoreNamedField::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream); object()->PrintTo(stream);
stream->Add("."); stream->Add(".");
...@@ -474,81 +438,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) { ...@@ -474,81 +438,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
} }
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap, zone());
index = instructions_.length();
instructions_.Add(instr, zone());
} else {
index = instructions_.length();
instructions_.Add(instr, zone());
instructions_.Add(gap, zone());
}
if (instr->HasPointerMap()) {
pointer_maps_.Add(instr->pointer_map(), zone());
instr->pointer_map()->set_lithium_position(index);
}
}
LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
int LChunk::GetParameterStackSlot(int index) const {
// The receiver is at index 0, the first parameter at index 1, so we
// shift all parameter indexes down by the number of parameters, and
// make sure they end up negative so they are distinguishable from
// spill slots.
int result = index - info()->scope()->num_parameters() - 1;
ASSERT(result < 0);
return result;
}
// A parameter relative to ebp in the arguments stub.
int LChunk::ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver.
return (1 + info()->scope()->num_parameters() - index) *
kPointerSize;
}
LGap* LChunk::GetGapAt(int index) const {
return LGap::cast(instructions_[index]);
}
bool LChunk::IsGapAt(int index) const {
return instructions_[index]->IsGap();
}
int LChunk::NearestGapPos(int index) const {
while (!IsGapAt(index)) index--;
return index;
}
void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
GetGapAt(index)->GetOrCreateParallelMove(
LGap::START, zone())->AddMove(from, to, zone());
}
Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
}
Representation LChunk::LookupLiteralRepresentation(
LConstantOperand* operand) const {
return graph_->LookupValue(operand->index())->representation();
}
LChunk* LChunkBuilder::Build() { LChunk* LChunkBuilder::Build() {
ASSERT(is_unused()); ASSERT(is_unused());
chunk_ = new(zone()) LChunk(info(), graph()); chunk_ = new(zone()) LChunk(info(), graph());
......
...@@ -2319,74 +2319,19 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { ...@@ -2319,74 +2319,19 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder; class LChunkBuilder;
class LChunk: public ZoneObject { class LChunk: public LChunkBase {
public: public:
LChunk(CompilationInfo* info, HGraph* graph) LChunk(CompilationInfo* info, HGraph* graph)
: spill_slot_count_(0), : LChunkBase(info, graph),
num_double_slots_(0), num_double_slots_(0) { }
info_(info),
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
inlined_closures_(1, graph->zone()) { }
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
int GetNextSpillIndex(bool is_double); int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double); LOperand* GetNextSpillSlot(bool is_double);
int ParameterAt(int index);
int GetParameterStackSlot(int index) const;
int spill_slot_count() const { return spill_slot_count_; }
int num_double_slots() const { return num_double_slots_; } int num_double_slots() const { return num_double_slots_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
void AddGapMove(int index, LOperand* from, LOperand* to);
LGap* GetGapAt(int index) const;
bool IsGapAt(int index) const;
int NearestGapPos(int index) const;
void MarkEmptyBlocks();
const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
LLabel* GetLabel(int block_id) const {
HBasicBlock* block = graph_->blocks()->at(block_id);
int first_instruction = block->first_instruction_index();
return LLabel::cast(instructions_[first_instruction]);
}
int LookupDestination(int block_id) const {
LLabel* cur = GetLabel(block_id);
while (cur->replacement() != NULL) {
cur = cur->replacement();
}
return cur->block_id();
}
Label* GetAssemblyLabel(int block_id) const {
LLabel* label = GetLabel(block_id);
ASSERT(!label->HasReplacement());
return label->label();
}
const ZoneList<Handle<JSFunction> >* inlined_closures() const {
return &inlined_closures_;
}
void AddInlinedClosure(Handle<JSFunction> closure) {
inlined_closures_.Add(closure, zone());
}
Zone* zone() const { return graph_->zone(); }
private: private:
int spill_slot_count_;
int num_double_slots_; int num_double_slots_;
CompilationInfo* info_;
HGraph* const graph_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
}; };
......
...@@ -27,6 +27,19 @@ ...@@ -27,6 +27,19 @@
#include "v8.h" #include "v8.h"
#include "lithium.h" #include "lithium.h"
#include "scopes.h"
#if V8_TARGET_ARCH_IA32
#include "ia32/lithium-ia32.h"
#elif V8_TARGET_ARCH_X64
#include "x64/lithium-x64.h"
#elif V8_TARGET_ARCH_ARM
#include "arm/lithium-arm.h"
#elif V8_TARGET_ARCH_MIPS
#include "mips/lithium-mips.h"
#else
#error "Unknown architecture."
#endif
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -240,4 +253,137 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) { ...@@ -240,4 +253,137 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
} }
LLabel* LChunkBase::GetLabel(int block_id) const {
HBasicBlock* block = graph_->blocks()->at(block_id);
int first_instruction = block->first_instruction_index();
return LLabel::cast(instructions_[first_instruction]);
}
int LChunkBase::LookupDestination(int block_id) const {
LLabel* cur = GetLabel(block_id);
while (cur->replacement() != NULL) {
cur = cur->replacement();
}
return cur->block_id();
}
Label* LChunkBase::GetAssemblyLabel(int block_id) const {
LLabel* label = GetLabel(block_id);
ASSERT(!label->HasReplacement());
return label->label();
}
void LChunkBase::MarkEmptyBlocks() {
HPhase phase("L_Mark empty blocks", this);
for (int i = 0; i < graph()->blocks()->length(); ++i) {
HBasicBlock* block = graph()->blocks()->at(i);
int first = block->first_instruction_index();
int last = block->last_instruction_index();
LInstruction* first_instr = instructions()->at(first);
LInstruction* last_instr = instructions()->at(last);
LLabel* label = LLabel::cast(first_instr);
if (last_instr->IsGoto()) {
LGoto* goto_instr = LGoto::cast(last_instr);
if (label->IsRedundant() &&
!label->is_loop_header()) {
bool can_eliminate = true;
for (int i = first + 1; i < last && can_eliminate; ++i) {
LInstruction* cur = instructions()->at(i);
if (cur->IsGap()) {
LGap* gap = LGap::cast(cur);
if (!gap->IsRedundant()) {
can_eliminate = false;
}
} else {
can_eliminate = false;
}
}
if (can_eliminate) {
label->set_replacement(GetLabel(goto_instr->block_id()));
}
}
}
}
}
void LChunkBase::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap, zone());
index = instructions_.length();
instructions_.Add(instr, zone());
} else {
index = instructions_.length();
instructions_.Add(instr, zone());
instructions_.Add(gap, zone());
}
if (instr->HasPointerMap()) {
pointer_maps_.Add(instr->pointer_map(), zone());
instr->pointer_map()->set_lithium_position(index);
}
}
LConstantOperand* LChunkBase::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
int LChunkBase::GetParameterStackSlot(int index) const {
// The receiver is at index 0, the first parameter at index 1, so we
// shift all parameter indexes down by the number of parameters, and
// make sure they end up negative so they are distinguishable from
// spill slots.
int result = index - info()->scope()->num_parameters() - 1;
ASSERT(result < 0);
return result;
}
// A parameter relative to ebp in the arguments stub.
int LChunkBase::ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver.
return (1 + info()->scope()->num_parameters() - index) *
kPointerSize;
}
LGap* LChunkBase::GetGapAt(int index) const {
return LGap::cast(instructions_[index]);
}
bool LChunkBase::IsGapAt(int index) const {
return instructions_[index]->IsGap();
}
int LChunkBase::NearestGapPos(int index) const {
while (!IsGapAt(index)) index--;
return index;
}
void LChunkBase::AddGapMove(int index, LOperand* from, LOperand* to) {
GetGapAt(index)->GetOrCreateParallelMove(
LGap::START, zone())->AddMove(from, to, zone());
}
Handle<Object> LChunkBase::LookupLiteral(LConstantOperand* operand) const {
return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
}
Representation LChunkBase::LookupLiteralRepresentation(
LConstantOperand* operand) const {
return graph_->LookupValue(operand->index())->representation();
}
} } // namespace v8::internal } } // namespace v8::internal
...@@ -622,6 +622,64 @@ class DeepIterator BASE_EMBEDDED { ...@@ -622,6 +622,64 @@ class DeepIterator BASE_EMBEDDED {
}; };
class LGap;
class LLabel;
// Superclass providing data and behavior common to all the
// arch-specific LChunk classes.
class LChunkBase: public ZoneObject {
public:
LChunkBase(CompilationInfo* info, HGraph* graph)
: spill_slot_count_(0),
info_(info),
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
inlined_closures_(1, graph->zone()) { }
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
int ParameterAt(int index);
int GetParameterStackSlot(int index) const;
int spill_slot_count() const { return spill_slot_count_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
void AddGapMove(int index, LOperand* from, LOperand* to);
LGap* GetGapAt(int index) const;
bool IsGapAt(int index) const;
int NearestGapPos(int index) const;
void MarkEmptyBlocks();
const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
LLabel* GetLabel(int block_id) const;
int LookupDestination(int block_id) const;
Label* GetAssemblyLabel(int block_id) const;
const ZoneList<Handle<JSFunction> >* inlined_closures() const {
return &inlined_closures_;
}
void AddInlinedClosure(Handle<JSFunction> closure) {
inlined_closures_.Add(closure, zone());
}
Zone* zone() const { return info_->zone(); }
protected:
int spill_slot_count_;
private:
CompilationInfo* info_;
HGraph* const graph_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
};
int ElementsKindToShiftSize(ElementsKind elements_kind); int ElementsKindToShiftSize(ElementsKind elements_kind);
......
...@@ -407,16 +407,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) { ...@@ -407,16 +407,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
} }
LChunk::LChunk(CompilationInfo* info, HGraph* graph)
: spill_slot_count_(0),
info_(info),
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
inlined_closures_(1, graph->zone()) {
}
int LChunk::GetNextSpillIndex(bool is_double) { int LChunk::GetNextSpillIndex(bool is_double) {
// Skip a slot if for a double-width slot. // Skip a slot if for a double-width slot.
if (is_double) spill_slot_count_++; if (is_double) spill_slot_count_++;
...@@ -434,117 +424,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) { ...@@ -434,117 +424,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
} }
void LChunk::MarkEmptyBlocks() {
HPhase phase("L_Mark empty blocks", this);
for (int i = 0; i < graph()->blocks()->length(); ++i) {
HBasicBlock* block = graph()->blocks()->at(i);
int first = block->first_instruction_index();
int last = block->last_instruction_index();
LInstruction* first_instr = instructions()->at(first);
LInstruction* last_instr = instructions()->at(last);
LLabel* label = LLabel::cast(first_instr);
if (last_instr->IsGoto()) {
LGoto* goto_instr = LGoto::cast(last_instr);
if (label->IsRedundant() &&
!label->is_loop_header()) {
bool can_eliminate = true;
for (int i = first + 1; i < last && can_eliminate; ++i) {
LInstruction* cur = instructions()->at(i);
if (cur->IsGap()) {
LGap* gap = LGap::cast(cur);
if (!gap->IsRedundant()) {
can_eliminate = false;
}
} else {
can_eliminate = false;
}
}
if (can_eliminate) {
label->set_replacement(GetLabel(goto_instr->block_id()));
}
}
}
}
}
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap, zone());
index = instructions_.length();
instructions_.Add(instr, zone());
} else {
index = instructions_.length();
instructions_.Add(instr, zone());
instructions_.Add(gap, zone());
}
if (instr->HasPointerMap()) {
pointer_maps_.Add(instr->pointer_map(), zone());
instr->pointer_map()->set_lithium_position(index);
}
}
LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
int LChunk::GetParameterStackSlot(int index) const {
// The receiver is at index 0, the first parameter at index 1, so we
// shift all parameter indexes down by the number of parameters, and
// make sure they end up negative so they are distinguishable from
// spill slots.
int result = index - info()->scope()->num_parameters() - 1;
ASSERT(result < 0);
return result;
}
// A parameter relative to ebp in the arguments stub.
int LChunk::ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver.
return (1 + info()->scope()->num_parameters() - index) *
kPointerSize;
}
LGap* LChunk::GetGapAt(int index) const {
return LGap::cast(instructions_[index]);
}
bool LChunk::IsGapAt(int index) const {
return instructions_[index]->IsGap();
}
int LChunk::NearestGapPos(int index) const {
while (!IsGapAt(index)) index--;
return index;
}
void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
GetGapAt(index)->GetOrCreateParallelMove(
LGap::START, zone())->AddMove(from, to, zone());
}
Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
}
Representation LChunk::LookupLiteralRepresentation(
LConstantOperand* operand) const {
return graph_->LookupValue(operand->index())->representation();
}
LChunk* LChunkBuilder::Build() { LChunk* LChunkBuilder::Build() {
ASSERT(is_unused()); ASSERT(is_unused());
chunk_ = new(zone()) LChunk(info(), graph()); chunk_ = new(zone()) LChunk(info(), graph());
......
...@@ -2188,65 +2188,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { ...@@ -2188,65 +2188,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder; class LChunkBuilder;
class LChunk: public ZoneObject { class LChunk: public LChunkBase {
public: public:
explicit LChunk(CompilationInfo* info, HGraph* graph); explicit LChunk(CompilationInfo* info, HGraph* graph)
: LChunkBase(info, graph) { }
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
int GetNextSpillIndex(bool is_double); int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double); LOperand* GetNextSpillSlot(bool is_double);
int ParameterAt(int index);
int GetParameterStackSlot(int index) const;
int spill_slot_count() const { return spill_slot_count_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
void AddGapMove(int index, LOperand* from, LOperand* to);
LGap* GetGapAt(int index) const;
bool IsGapAt(int index) const;
int NearestGapPos(int index) const;
void MarkEmptyBlocks();
const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
LLabel* GetLabel(int block_id) const {
HBasicBlock* block = graph_->blocks()->at(block_id);
int first_instruction = block->first_instruction_index();
return LLabel::cast(instructions_[first_instruction]);
}
int LookupDestination(int block_id) const {
LLabel* cur = GetLabel(block_id);
while (cur->replacement() != NULL) {
cur = cur->replacement();
}
return cur->block_id();
}
Label* GetAssemblyLabel(int block_id) const {
LLabel* label = GetLabel(block_id);
ASSERT(!label->HasReplacement());
return label->label();
}
const ZoneList<Handle<JSFunction> >* inlined_closures() const {
return &inlined_closures_;
}
void AddInlinedClosure(Handle<JSFunction> closure) {
inlined_closures_.Add(closure, zone());
}
Zone* zone() const { return graph_->zone(); }
private:
int spill_slot_count_;
CompilationInfo* info_;
HGraph* const graph_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
}; };
......
...@@ -376,42 +376,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) { ...@@ -376,42 +376,6 @@ LOperand* LChunk::GetNextSpillSlot(bool is_double) {
} }
void LChunk::MarkEmptyBlocks() {
HPhase phase("L_Mark empty blocks", this);
for (int i = 0; i < graph()->blocks()->length(); ++i) {
HBasicBlock* block = graph()->blocks()->at(i);
int first = block->first_instruction_index();
int last = block->last_instruction_index();
LInstruction* first_instr = instructions()->at(first);
LInstruction* last_instr = instructions()->at(last);
LLabel* label = LLabel::cast(first_instr);
if (last_instr->IsGoto()) {
LGoto* goto_instr = LGoto::cast(last_instr);
if (label->IsRedundant() &&
!label->is_loop_header()) {
bool can_eliminate = true;
for (int i = first + 1; i < last && can_eliminate; ++i) {
LInstruction* cur = instructions()->at(i);
if (cur->IsGap()) {
LGap* gap = LGap::cast(cur);
if (!gap->IsRedundant()) {
can_eliminate = false;
}
} else {
can_eliminate = false;
}
}
if (can_eliminate) {
label->set_replacement(GetLabel(goto_instr->block_id()));
}
}
}
}
}
void LStoreNamedField::PrintDataTo(StringStream* stream) { void LStoreNamedField::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream); object()->PrintTo(stream);
stream->Add("."); stream->Add(".");
...@@ -463,81 +427,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) { ...@@ -463,81 +427,6 @@ void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
} }
void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
int index = -1;
if (instr->IsControl()) {
instructions_.Add(gap, zone());
index = instructions_.length();
instructions_.Add(instr, zone());
} else {
index = instructions_.length();
instructions_.Add(instr, zone());
instructions_.Add(gap, zone());
}
if (instr->HasPointerMap()) {
pointer_maps_.Add(instr->pointer_map(), zone());
instr->pointer_map()->set_lithium_position(index);
}
}
LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
int LChunk::GetParameterStackSlot(int index) const {
// The receiver is at index 0, the first parameter at index 1, so we
// shift all parameter indexes down by the number of parameters, and
// make sure they end up negative so they are distinguishable from
// spill slots.
int result = index - info()->scope()->num_parameters() - 1;
ASSERT(result < 0);
return result;
}
// A parameter relative to ebp in the arguments stub.
int LChunk::ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver.
return (1 + info()->scope()->num_parameters() - index) *
kPointerSize;
}
LGap* LChunk::GetGapAt(int index) const {
return LGap::cast(instructions_[index]);
}
bool LChunk::IsGapAt(int index) const {
return instructions_[index]->IsGap();
}
int LChunk::NearestGapPos(int index) const {
while (!IsGapAt(index)) index--;
return index;
}
void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
GetGapAt(index)->GetOrCreateParallelMove(
LGap::START, zone())->AddMove(from, to, zone());
}
Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
}
Representation LChunk::LookupLiteralRepresentation(
LConstantOperand* operand) const {
return graph_->LookupValue(operand->index())->representation();
}
LChunk* LChunkBuilder::Build() { LChunk* LChunkBuilder::Build() {
ASSERT(is_unused()); ASSERT(is_unused());
chunk_ = new(zone()) LChunk(info(), graph()); chunk_ = new(zone()) LChunk(info(), graph());
......
...@@ -2178,71 +2178,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> { ...@@ -2178,71 +2178,13 @@ class LLoadFieldByIndex: public LTemplateInstruction<1, 2, 0> {
class LChunkBuilder; class LChunkBuilder;
class LChunk: public ZoneObject { class LChunk: public LChunkBase {
public: public:
LChunk(CompilationInfo* info, HGraph* graph) LChunk(CompilationInfo* info, HGraph* graph)
: spill_slot_count_(0), : LChunkBase(info, graph) { }
info_(info),
graph_(graph),
instructions_(32, graph->zone()),
pointer_maps_(8, graph->zone()),
inlined_closures_(1, graph->zone()) { }
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
LConstantOperand* DefineConstantOperand(HConstant* constant);
Handle<Object> LookupLiteral(LConstantOperand* operand) const;
Representation LookupLiteralRepresentation(LConstantOperand* operand) const;
int GetNextSpillIndex(bool is_double); int GetNextSpillIndex(bool is_double);
LOperand* GetNextSpillSlot(bool is_double); LOperand* GetNextSpillSlot(bool is_double);
int ParameterAt(int index);
int GetParameterStackSlot(int index) const;
int spill_slot_count() const { return spill_slot_count_; }
CompilationInfo* info() const { return info_; }
HGraph* graph() const { return graph_; }
const ZoneList<LInstruction*>* instructions() const { return &instructions_; }
void AddGapMove(int index, LOperand* from, LOperand* to);
LGap* GetGapAt(int index) const;
bool IsGapAt(int index) const;
int NearestGapPos(int index) const;
void MarkEmptyBlocks();
const ZoneList<LPointerMap*>* pointer_maps() const { return &pointer_maps_; }
LLabel* GetLabel(int block_id) const {
HBasicBlock* block = graph_->blocks()->at(block_id);
int first_instruction = block->first_instruction_index();
return LLabel::cast(instructions_[first_instruction]);
}
int LookupDestination(int block_id) const {
LLabel* cur = GetLabel(block_id);
while (cur->replacement() != NULL) {
cur = cur->replacement();
}
return cur->block_id();
}
Label* GetAssemblyLabel(int block_id) const {
LLabel* label = GetLabel(block_id);
ASSERT(!label->HasReplacement());
return label->label();
}
const ZoneList<Handle<JSFunction> >* inlined_closures() const {
return &inlined_closures_;
}
void AddInlinedClosure(Handle<JSFunction> closure) {
inlined_closures_.Add(closure, zone());
}
Zone* zone() const { return graph_->zone(); }
private:
int spill_slot_count_;
CompilationInfo* info_;
HGraph* const graph_;
ZoneList<LInstruction*> instructions_;
ZoneList<LPointerMap*> pointer_maps_;
ZoneList<Handle<JSFunction> > inlined_closures_;
}; };
......
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