Break Crankshaft into phases.
Crankshaft now runs by calling CreateGraph on the HGraphBuilder, then calling Optimize and Codegen on the HGraph. BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10700115 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12064 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
1132b27e25
commit
c1ee1b457f
@ -43,9 +43,9 @@ class SafepointGenerator;
|
|||||||
|
|
||||||
class LCodeGen BASE_EMBEDDED {
|
class LCodeGen BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||||
: zone_(info->zone()),
|
: zone_(info->zone()),
|
||||||
chunk_(chunk),
|
chunk_(static_cast<LChunk*>(chunk)),
|
||||||
masm_(assembler),
|
masm_(assembler),
|
||||||
info_(info),
|
info_(info),
|
||||||
current_block_(-1),
|
current_block_(-1),
|
||||||
|
@ -308,11 +308,19 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (graph != NULL) {
|
if (graph != NULL) {
|
||||||
Handle<Code> optimized_code = graph->Compile();
|
SmartArrayPointer<char> bailout_reason;
|
||||||
if (!optimized_code.is_null()) {
|
if (!graph->Optimize(&bailout_reason)) {
|
||||||
info->SetCode(optimized_code);
|
if (!bailout_reason.is_empty()) builder.Bailout(*bailout_reason);
|
||||||
FinishOptimization(info->closure(), start);
|
} else {
|
||||||
return true;
|
LChunkBase* chunk = LChunkBase::NewChunk(graph);
|
||||||
|
if (chunk != NULL) {
|
||||||
|
Handle<Code> optimized_code = chunk->Codegen();
|
||||||
|
if (!optimized_code.is_null()) {
|
||||||
|
info->SetCode(optimized_code);
|
||||||
|
FinishOptimization(info->closure(), start);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
106
src/hydrogen.cc
106
src/hydrogen.cc
@ -703,47 +703,6 @@ HGraph::HGraph(CompilationInfo* info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Handle<Code> HGraph::Compile() {
|
|
||||||
int values = GetMaximumValueID();
|
|
||||||
if (values > LUnallocated::kMaxVirtualRegisters) {
|
|
||||||
if (FLAG_trace_bailout) {
|
|
||||||
PrintF("Not enough virtual registers for (values).\n");
|
|
||||||
}
|
|
||||||
return Handle<Code>::null();
|
|
||||||
}
|
|
||||||
LAllocator allocator(values, this);
|
|
||||||
LChunkBuilder builder(info(), this, &allocator);
|
|
||||||
LChunk* chunk = builder.Build();
|
|
||||||
if (chunk == NULL) return Handle<Code>::null();
|
|
||||||
|
|
||||||
if (!allocator.Allocate(chunk)) {
|
|
||||||
if (FLAG_trace_bailout) {
|
|
||||||
PrintF("Not enough virtual registers (regalloc).\n");
|
|
||||||
}
|
|
||||||
return Handle<Code>::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
MacroAssembler assembler(isolate(), NULL, 0);
|
|
||||||
LCodeGen generator(chunk, &assembler, info());
|
|
||||||
|
|
||||||
chunk->MarkEmptyBlocks();
|
|
||||||
|
|
||||||
if (generator.GenerateCode()) {
|
|
||||||
if (FLAG_trace_codegen) {
|
|
||||||
PrintF("Crankshaft Compiler - ");
|
|
||||||
}
|
|
||||||
CodeGenerator::MakeCodePrologue(info());
|
|
||||||
Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
|
|
||||||
Handle<Code> code =
|
|
||||||
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
|
|
||||||
generator.FinishCode(code);
|
|
||||||
CodeGenerator::PrintCode(code, info());
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
return Handle<Code>::null();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
HBasicBlock* HGraph::CreateBasicBlock() {
|
HBasicBlock* HGraph::CreateBasicBlock() {
|
||||||
HBasicBlock* result = new(zone()) HBasicBlock(this);
|
HBasicBlock* result = new(zone()) HBasicBlock(this);
|
||||||
blocks_.Add(result, zone());
|
blocks_.Add(result, zone());
|
||||||
@ -3122,48 +3081,55 @@ HGraph* HGraphBuilder::CreateGraph() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
graph()->OrderBlocks();
|
return graph();
|
||||||
graph()->AssignDominators();
|
}
|
||||||
|
|
||||||
|
bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
||||||
|
*bailout_reason = SmartArrayPointer<char>();
|
||||||
|
OrderBlocks();
|
||||||
|
AssignDominators();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Do a full verify after building the graph and computing dominators.
|
// Do a full verify after building the graph and computing dominators.
|
||||||
graph()->Verify(true);
|
Verify(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
graph()->PropagateDeoptimizingMark();
|
PropagateDeoptimizingMark();
|
||||||
if (!graph()->CheckConstPhiUses()) {
|
if (!CheckConstPhiUses()) {
|
||||||
Bailout("Unsupported phi use of const variable");
|
*bailout_reason = SmartArrayPointer<char>(StrDup(
|
||||||
return NULL;
|
"Unsupported phi use of const variable"));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
graph()->EliminateRedundantPhis();
|
EliminateRedundantPhis();
|
||||||
if (!graph()->CheckArgumentsPhiUses()) {
|
if (!CheckArgumentsPhiUses()) {
|
||||||
Bailout("Unsupported phi use of arguments");
|
*bailout_reason = SmartArrayPointer<char>(StrDup(
|
||||||
return NULL;
|
"Unsupported phi use of arguments"));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
|
if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis();
|
||||||
graph()->CollectPhis();
|
CollectPhis();
|
||||||
|
|
||||||
if (graph()->has_osr_loop_entry()) {
|
if (has_osr_loop_entry()) {
|
||||||
const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis();
|
const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
|
||||||
for (int j = 0; j < phis->length(); j++) {
|
for (int j = 0; j < phis->length(); j++) {
|
||||||
HPhi* phi = phis->at(j);
|
HPhi* phi = phis->at(j);
|
||||||
graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi);
|
osr_values()->at(phi->merged_index())->set_incoming_value(phi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HInferRepresentation rep(graph());
|
HInferRepresentation rep(this);
|
||||||
rep.Analyze();
|
rep.Analyze();
|
||||||
|
|
||||||
graph()->MarkDeoptimizeOnUndefined();
|
MarkDeoptimizeOnUndefined();
|
||||||
graph()->InsertRepresentationChanges();
|
InsertRepresentationChanges();
|
||||||
|
|
||||||
graph()->InitializeInferredTypes();
|
InitializeInferredTypes();
|
||||||
graph()->Canonicalize();
|
Canonicalize();
|
||||||
|
|
||||||
// Perform common subexpression elimination and loop-invariant code motion.
|
// Perform common subexpression elimination and loop-invariant code motion.
|
||||||
if (FLAG_use_gvn) {
|
if (FLAG_use_gvn) {
|
||||||
HPhase phase("H_Global value numbering", graph());
|
HPhase phase("H_Global value numbering", this);
|
||||||
HGlobalValueNumberer gvn(graph(), info());
|
HGlobalValueNumberer gvn(this, info());
|
||||||
bool removed_side_effects = gvn.Analyze();
|
bool removed_side_effects = gvn.Analyze();
|
||||||
// Trigger a second analysis pass to further eliminate duplicate values that
|
// Trigger a second analysis pass to further eliminate duplicate values that
|
||||||
// could only be discovered by removing side-effect-generating instructions
|
// could only be discovered by removing side-effect-generating instructions
|
||||||
@ -3175,19 +3141,19 @@ HGraph* HGraphBuilder::CreateGraph() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (FLAG_use_range) {
|
if (FLAG_use_range) {
|
||||||
HRangeAnalysis rangeAnalysis(graph());
|
HRangeAnalysis rangeAnalysis(this);
|
||||||
rangeAnalysis.Analyze();
|
rangeAnalysis.Analyze();
|
||||||
}
|
}
|
||||||
graph()->ComputeMinusZeroChecks();
|
ComputeMinusZeroChecks();
|
||||||
|
|
||||||
// Eliminate redundant stack checks on backwards branches.
|
// Eliminate redundant stack checks on backwards branches.
|
||||||
HStackCheckEliminator sce(graph());
|
HStackCheckEliminator sce(this);
|
||||||
sce.Process();
|
sce.Process();
|
||||||
|
|
||||||
graph()->EliminateRedundantBoundsChecks();
|
EliminateRedundantBoundsChecks();
|
||||||
graph()->DehoistSimpleArrayIndexComputations();
|
DehoistSimpleArrayIndexComputations();
|
||||||
|
|
||||||
return graph();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -281,8 +281,6 @@ class HGraph: public ZoneObject {
|
|||||||
|
|
||||||
void CollectPhis();
|
void CollectPhis();
|
||||||
|
|
||||||
Handle<Code> Compile();
|
|
||||||
|
|
||||||
void set_undefined_constant(HConstant* constant) {
|
void set_undefined_constant(HConstant* constant) {
|
||||||
undefined_constant_.set(constant);
|
undefined_constant_.set(constant);
|
||||||
}
|
}
|
||||||
@ -313,6 +311,8 @@ class HGraph: public ZoneObject {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Optimize(SmartArrayPointer<char>* bailout_reason);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void Verify(bool do_full_verify) const;
|
void Verify(bool do_full_verify) const;
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,9 +46,9 @@ class SafepointGenerator;
|
|||||||
|
|
||||||
class LCodeGen BASE_EMBEDDED {
|
class LCodeGen BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||||
: zone_(info->zone()),
|
: zone_(info->zone()),
|
||||||
chunk_(chunk),
|
chunk_(static_cast<LChunk*>(chunk)),
|
||||||
masm_(assembler),
|
masm_(assembler),
|
||||||
info_(info),
|
info_(info),
|
||||||
current_block_(-1),
|
current_block_(-1),
|
||||||
|
@ -1062,9 +1062,9 @@ void LAllocator::ResolvePhis(HBasicBlock* block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LAllocator::Allocate(LChunk* chunk) {
|
bool LAllocator::Allocate(LChunkBase* chunk) {
|
||||||
ASSERT(chunk_ == NULL);
|
ASSERT(chunk_ == NULL);
|
||||||
chunk_ = chunk;
|
chunk_ = static_cast<LChunk*>(chunk);
|
||||||
MeetRegisterConstraints();
|
MeetRegisterConstraints();
|
||||||
if (!AllocationOk()) return false;
|
if (!AllocationOk()) return false;
|
||||||
ResolvePhis();
|
ResolvePhis();
|
||||||
|
@ -445,7 +445,7 @@ class LAllocator BASE_EMBEDDED {
|
|||||||
// Returns the register kind required by the given virtual register.
|
// Returns the register kind required by the given virtual register.
|
||||||
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
||||||
|
|
||||||
bool Allocate(LChunk* chunk);
|
bool Allocate(LChunkBase* chunk);
|
||||||
|
|
||||||
const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
|
const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
|
||||||
const Vector<LiveRange*>* fixed_live_ranges() const {
|
const Vector<LiveRange*>* fixed_live_ranges() const {
|
||||||
|
@ -31,12 +31,16 @@
|
|||||||
|
|
||||||
#if V8_TARGET_ARCH_IA32
|
#if V8_TARGET_ARCH_IA32
|
||||||
#include "ia32/lithium-ia32.h"
|
#include "ia32/lithium-ia32.h"
|
||||||
|
#include "ia32/lithium-codegen-ia32.h"
|
||||||
#elif V8_TARGET_ARCH_X64
|
#elif V8_TARGET_ARCH_X64
|
||||||
#include "x64/lithium-x64.h"
|
#include "x64/lithium-x64.h"
|
||||||
|
#include "x64/lithium-codegen-x64.h"
|
||||||
#elif V8_TARGET_ARCH_ARM
|
#elif V8_TARGET_ARCH_ARM
|
||||||
#include "arm/lithium-arm.h"
|
#include "arm/lithium-arm.h"
|
||||||
|
#include "arm/lithium-codegen-arm.h"
|
||||||
#elif V8_TARGET_ARCH_MIPS
|
#elif V8_TARGET_ARCH_MIPS
|
||||||
#include "mips/lithium-mips.h"
|
#include "mips/lithium-mips.h"
|
||||||
|
#include "mips/lithium-codegen-mips.h"
|
||||||
#else
|
#else
|
||||||
#error "Unknown architecture."
|
#error "Unknown architecture."
|
||||||
#endif
|
#endif
|
||||||
@ -386,4 +390,50 @@ Representation LChunkBase::LookupLiteralRepresentation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LChunkBase* LChunkBase::NewChunk(HGraph* graph) {
|
||||||
|
int values = graph->GetMaximumValueID();
|
||||||
|
if (values > LUnallocated::kMaxVirtualRegisters) {
|
||||||
|
if (FLAG_trace_bailout) {
|
||||||
|
PrintF("Not enough virtual registers for (values).\n");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
LAllocator allocator(values, graph);
|
||||||
|
LChunkBuilder builder(graph->info(), graph, &allocator);
|
||||||
|
LChunkBase* chunk = builder.Build();
|
||||||
|
if (chunk == NULL) return NULL;
|
||||||
|
|
||||||
|
if (!allocator.Allocate(chunk)) {
|
||||||
|
if (FLAG_trace_bailout) {
|
||||||
|
PrintF("Not enough virtual registers (regalloc).\n");
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Handle<Code> LChunkBase::Codegen() {
|
||||||
|
MacroAssembler assembler(info()->isolate(), NULL, 0);
|
||||||
|
LCodeGen generator(this, &assembler, info());
|
||||||
|
|
||||||
|
MarkEmptyBlocks();
|
||||||
|
|
||||||
|
if (generator.GenerateCode()) {
|
||||||
|
if (FLAG_trace_codegen) {
|
||||||
|
PrintF("Crankshaft Compiler - ");
|
||||||
|
}
|
||||||
|
CodeGenerator::MakeCodePrologue(info());
|
||||||
|
Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
|
||||||
|
Handle<Code> code =
|
||||||
|
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
|
||||||
|
generator.FinishCode(code);
|
||||||
|
CodeGenerator::PrintCode(code, info());
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
return Handle<Code>::null();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
@ -622,6 +622,7 @@ class DeepIterator BASE_EMBEDDED {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class LChunk;
|
||||||
class LGap;
|
class LGap;
|
||||||
class LLabel;
|
class LLabel;
|
||||||
|
|
||||||
@ -629,13 +630,7 @@ class LLabel;
|
|||||||
// arch-specific LChunk classes.
|
// arch-specific LChunk classes.
|
||||||
class LChunkBase: public ZoneObject {
|
class LChunkBase: public ZoneObject {
|
||||||
public:
|
public:
|
||||||
LChunkBase(CompilationInfo* info, HGraph* graph)
|
static LChunkBase* NewChunk(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);
|
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
|
||||||
LConstantOperand* DefineConstantOperand(HConstant* constant);
|
LConstantOperand* DefineConstantOperand(HConstant* constant);
|
||||||
@ -668,7 +663,17 @@ class LChunkBase: public ZoneObject {
|
|||||||
|
|
||||||
Zone* zone() const { return info_->zone(); }
|
Zone* zone() const { return info_->zone(); }
|
||||||
|
|
||||||
|
Handle<Code> Codegen();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
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()) { }
|
||||||
|
|
||||||
int spill_slot_count_;
|
int spill_slot_count_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -43,9 +43,9 @@ class SafepointGenerator;
|
|||||||
|
|
||||||
class LCodeGen BASE_EMBEDDED {
|
class LCodeGen BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||||
: zone_(info->zone()),
|
: zone_(info->zone()),
|
||||||
chunk_(chunk),
|
chunk_(static_cast<LChunk*>(chunk)),
|
||||||
masm_(assembler),
|
masm_(assembler),
|
||||||
info_(info),
|
info_(info),
|
||||||
current_block_(-1),
|
current_block_(-1),
|
||||||
|
@ -45,9 +45,9 @@ class SafepointGenerator;
|
|||||||
|
|
||||||
class LCodeGen BASE_EMBEDDED {
|
class LCodeGen BASE_EMBEDDED {
|
||||||
public:
|
public:
|
||||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||||
: zone_(info->zone()),
|
: zone_(info->zone()),
|
||||||
chunk_(chunk),
|
chunk_(static_cast<LChunk*>(chunk)),
|
||||||
masm_(assembler),
|
masm_(assembler),
|
||||||
info_(info),
|
info_(info),
|
||||||
current_block_(-1),
|
current_block_(-1),
|
||||||
|
Loading…
Reference in New Issue
Block a user