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 {
|
||||
public:
|
||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
: zone_(info->zone()),
|
||||
chunk_(chunk),
|
||||
chunk_(static_cast<LChunk*>(chunk)),
|
||||
masm_(assembler),
|
||||
info_(info),
|
||||
current_block_(-1),
|
||||
|
@ -308,11 +308,19 @@ static bool MakeCrankshaftCode(CompilationInfo* info) {
|
||||
}
|
||||
|
||||
if (graph != NULL) {
|
||||
Handle<Code> optimized_code = graph->Compile();
|
||||
if (!optimized_code.is_null()) {
|
||||
info->SetCode(optimized_code);
|
||||
FinishOptimization(info->closure(), start);
|
||||
return true;
|
||||
SmartArrayPointer<char> bailout_reason;
|
||||
if (!graph->Optimize(&bailout_reason)) {
|
||||
if (!bailout_reason.is_empty()) builder.Bailout(*bailout_reason);
|
||||
} else {
|
||||
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* result = new(zone()) HBasicBlock(this);
|
||||
blocks_.Add(result, zone());
|
||||
@ -3122,48 +3081,55 @@ HGraph* HGraphBuilder::CreateGraph() {
|
||||
}
|
||||
}
|
||||
|
||||
graph()->OrderBlocks();
|
||||
graph()->AssignDominators();
|
||||
return graph();
|
||||
}
|
||||
|
||||
bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) {
|
||||
*bailout_reason = SmartArrayPointer<char>();
|
||||
OrderBlocks();
|
||||
AssignDominators();
|
||||
|
||||
#ifdef DEBUG
|
||||
// Do a full verify after building the graph and computing dominators.
|
||||
graph()->Verify(true);
|
||||
Verify(true);
|
||||
#endif
|
||||
|
||||
graph()->PropagateDeoptimizingMark();
|
||||
if (!graph()->CheckConstPhiUses()) {
|
||||
Bailout("Unsupported phi use of const variable");
|
||||
return NULL;
|
||||
PropagateDeoptimizingMark();
|
||||
if (!CheckConstPhiUses()) {
|
||||
*bailout_reason = SmartArrayPointer<char>(StrDup(
|
||||
"Unsupported phi use of const variable"));
|
||||
return false;
|
||||
}
|
||||
graph()->EliminateRedundantPhis();
|
||||
if (!graph()->CheckArgumentsPhiUses()) {
|
||||
Bailout("Unsupported phi use of arguments");
|
||||
return NULL;
|
||||
EliminateRedundantPhis();
|
||||
if (!CheckArgumentsPhiUses()) {
|
||||
*bailout_reason = SmartArrayPointer<char>(StrDup(
|
||||
"Unsupported phi use of arguments"));
|
||||
return false;
|
||||
}
|
||||
if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
|
||||
graph()->CollectPhis();
|
||||
if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis();
|
||||
CollectPhis();
|
||||
|
||||
if (graph()->has_osr_loop_entry()) {
|
||||
const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis();
|
||||
if (has_osr_loop_entry()) {
|
||||
const ZoneList<HPhi*>* phis = osr_loop_entry()->phis();
|
||||
for (int j = 0; j < phis->length(); 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();
|
||||
|
||||
graph()->MarkDeoptimizeOnUndefined();
|
||||
graph()->InsertRepresentationChanges();
|
||||
MarkDeoptimizeOnUndefined();
|
||||
InsertRepresentationChanges();
|
||||
|
||||
graph()->InitializeInferredTypes();
|
||||
graph()->Canonicalize();
|
||||
InitializeInferredTypes();
|
||||
Canonicalize();
|
||||
|
||||
// Perform common subexpression elimination and loop-invariant code motion.
|
||||
if (FLAG_use_gvn) {
|
||||
HPhase phase("H_Global value numbering", graph());
|
||||
HGlobalValueNumberer gvn(graph(), info());
|
||||
HPhase phase("H_Global value numbering", this);
|
||||
HGlobalValueNumberer gvn(this, info());
|
||||
bool removed_side_effects = gvn.Analyze();
|
||||
// Trigger a second analysis pass to further eliminate duplicate values that
|
||||
// could only be discovered by removing side-effect-generating instructions
|
||||
@ -3175,19 +3141,19 @@ HGraph* HGraphBuilder::CreateGraph() {
|
||||
}
|
||||
|
||||
if (FLAG_use_range) {
|
||||
HRangeAnalysis rangeAnalysis(graph());
|
||||
HRangeAnalysis rangeAnalysis(this);
|
||||
rangeAnalysis.Analyze();
|
||||
}
|
||||
graph()->ComputeMinusZeroChecks();
|
||||
ComputeMinusZeroChecks();
|
||||
|
||||
// Eliminate redundant stack checks on backwards branches.
|
||||
HStackCheckEliminator sce(graph());
|
||||
HStackCheckEliminator sce(this);
|
||||
sce.Process();
|
||||
|
||||
graph()->EliminateRedundantBoundsChecks();
|
||||
graph()->DehoistSimpleArrayIndexComputations();
|
||||
EliminateRedundantBoundsChecks();
|
||||
DehoistSimpleArrayIndexComputations();
|
||||
|
||||
return graph();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -281,8 +281,6 @@ class HGraph: public ZoneObject {
|
||||
|
||||
void CollectPhis();
|
||||
|
||||
Handle<Code> Compile();
|
||||
|
||||
void set_undefined_constant(HConstant* constant) {
|
||||
undefined_constant_.set(constant);
|
||||
}
|
||||
@ -313,6 +311,8 @@ class HGraph: public ZoneObject {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool Optimize(SmartArrayPointer<char>* bailout_reason);
|
||||
|
||||
#ifdef DEBUG
|
||||
void Verify(bool do_full_verify) const;
|
||||
#endif
|
||||
|
@ -46,9 +46,9 @@ class SafepointGenerator;
|
||||
|
||||
class LCodeGen BASE_EMBEDDED {
|
||||
public:
|
||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
: zone_(info->zone()),
|
||||
chunk_(chunk),
|
||||
chunk_(static_cast<LChunk*>(chunk)),
|
||||
masm_(assembler),
|
||||
info_(info),
|
||||
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);
|
||||
chunk_ = chunk;
|
||||
chunk_ = static_cast<LChunk*>(chunk);
|
||||
MeetRegisterConstraints();
|
||||
if (!AllocationOk()) return false;
|
||||
ResolvePhis();
|
||||
|
@ -445,7 +445,7 @@ class LAllocator BASE_EMBEDDED {
|
||||
// Returns the register kind required by the given virtual register.
|
||||
RegisterKind RequiredRegisterKind(int virtual_register) const;
|
||||
|
||||
bool Allocate(LChunk* chunk);
|
||||
bool Allocate(LChunkBase* chunk);
|
||||
|
||||
const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
|
||||
const Vector<LiveRange*>* fixed_live_ranges() const {
|
||||
|
@ -31,12 +31,16 @@
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
#include "ia32/lithium-ia32.h"
|
||||
#include "ia32/lithium-codegen-ia32.h"
|
||||
#elif V8_TARGET_ARCH_X64
|
||||
#include "x64/lithium-x64.h"
|
||||
#include "x64/lithium-codegen-x64.h"
|
||||
#elif V8_TARGET_ARCH_ARM
|
||||
#include "arm/lithium-arm.h"
|
||||
#include "arm/lithium-codegen-arm.h"
|
||||
#elif V8_TARGET_ARCH_MIPS
|
||||
#include "mips/lithium-mips.h"
|
||||
#include "mips/lithium-codegen-mips.h"
|
||||
#else
|
||||
#error "Unknown architecture."
|
||||
#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
|
||||
|
@ -622,6 +622,7 @@ class DeepIterator BASE_EMBEDDED {
|
||||
};
|
||||
|
||||
|
||||
class LChunk;
|
||||
class LGap;
|
||||
class LLabel;
|
||||
|
||||
@ -629,13 +630,7 @@ class LLabel;
|
||||
// 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()) { }
|
||||
static LChunkBase* NewChunk(HGraph* graph);
|
||||
|
||||
void AddInstruction(LInstruction* instruction, HBasicBlock* block);
|
||||
LConstantOperand* DefineConstantOperand(HConstant* constant);
|
||||
@ -668,7 +663,17 @@ class LChunkBase: public ZoneObject {
|
||||
|
||||
Zone* zone() const { return info_->zone(); }
|
||||
|
||||
Handle<Code> Codegen();
|
||||
|
||||
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_;
|
||||
|
||||
private:
|
||||
|
@ -43,9 +43,9 @@ class SafepointGenerator;
|
||||
|
||||
class LCodeGen BASE_EMBEDDED {
|
||||
public:
|
||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
: zone_(info->zone()),
|
||||
chunk_(chunk),
|
||||
chunk_(static_cast<LChunk*>(chunk)),
|
||||
masm_(assembler),
|
||||
info_(info),
|
||||
current_block_(-1),
|
||||
|
@ -45,9 +45,9 @@ class SafepointGenerator;
|
||||
|
||||
class LCodeGen BASE_EMBEDDED {
|
||||
public:
|
||||
LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
LCodeGen(LChunkBase* chunk, MacroAssembler* assembler, CompilationInfo* info)
|
||||
: zone_(info->zone()),
|
||||
chunk_(chunk),
|
||||
chunk_(static_cast<LChunk*>(chunk)),
|
||||
masm_(assembler),
|
||||
info_(info),
|
||||
current_block_(-1),
|
||||
|
Loading…
Reference in New Issue
Block a user