[turbofan] move label generation to code generator
authordcarney@chromium.org <dcarney@chromium.org>
Thu, 6 Nov 2014 14:59:07 +0000 (14:59 +0000)
committerdcarney@chromium.org <dcarney@chromium.org>
Thu, 6 Nov 2014 14:59:41 +0000 (14:59 +0000)
R=bmeurer@chromium.org

BUG=

Review URL: https://codereview.chromium.org/707803002

Cr-Commit-Position: refs/heads/master@{#25201}
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25201 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/assembler.h
src/compiler/arm/code-generator-arm.cc
src/compiler/arm64/code-generator-arm64.cc
src/compiler/code-generator-impl.h
src/compiler/code-generator.cc
src/compiler/code-generator.h
src/compiler/ia32/code-generator-ia32.cc
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/mips/code-generator-mips.cc
src/compiler/x64/code-generator-x64.cc

index b8d55b04243ea8f3bbdb124c2a9720c03ff65b70..e95b7edf75ce157918cae03ecd69ec7c208fdecb 100644 (file)
@@ -243,7 +243,7 @@ class CpuFeatures : public AllStatic {
 // unknown pc location. Assembler::bind() is used to bind a label to the
 // current pc. A label can be bound only once.
 
-class Label BASE_EMBEDDED {
+class Label {
  public:
   enum Distance {
     kNear, kFar
index 91bb660453862456b1b1786ff1db60d6cd7c442c..343376589f6f6ac73096c7d855d3ab8c45c73f35 100644 (file)
@@ -193,7 +193,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ b(code_->GetLabel(i.InputRpo(0)));
+      __ b(GetLabel(i.InputRpo(0)));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArchNop:
@@ -515,8 +515,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
   BasicBlock::RpoNumber fblock =
       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
   bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  Label* tlabel = GetLabel(tblock);
+  Label* flabel = fallthru ? &done : GetLabel(fblock);
   switch (condition) {
     case kUnorderedEqual:
       __ b(vs, flabel);
index 0c75b7c384327e39fc04d8831e3ea1b46e069231..41d4c5458d2bcb0c622e51ae931d9c5ddd8c92bc 100644 (file)
@@ -172,12 +172,12 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter {
   } while (0)
 
 
-#define ASSEMBLE_TEST_AND_BRANCH(asm_instr, width)             \
-  do {                                                         \
-    bool fallthrough = IsNextInAssemblyOrder(i.InputRpo(3));   \
-    __ asm_instr(i.InputRegister##width(0), i.InputInt6(1),    \
-                 code_->GetLabel(i.InputRpo(2)));              \
-    if (!fallthrough) __ B(code_->GetLabel(i.InputRpo(3)));    \
+#define ASSEMBLE_TEST_AND_BRANCH(asm_instr, width)           \
+  do {                                                       \
+    bool fallthrough = IsNextInAssemblyOrder(i.InputRpo(3)); \
+    __ asm_instr(i.InputRegister##width(0), i.InputInt6(1),  \
+                 GetLabel(i.InputRpo(2)));                   \
+    if (!fallthrough) __ B(GetLabel(i.InputRpo(3)));         \
   } while (0)
 
 
@@ -216,7 +216,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ B(code_->GetLabel(i.InputRpo(0)));
+      __ B(GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -614,8 +614,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
   BasicBlock::RpoNumber fblock =
       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
   bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  Label* tlabel = GetLabel(tblock);
+  Label* flabel = fallthru ? &done : GetLabel(fblock);
   switch (condition) {
     case kUnorderedEqual:
       __ B(vs, flabel);
index 0be26269a318f917adc0a693398730ff7ea73142..0dc919ad6b30d87742eadf1f2cb05b6498f84b02 100644 (file)
@@ -57,9 +57,7 @@ class InstructionOperandConverter {
     return ToHeapObject(instr_->InputAt(index));
   }
 
-  Label* InputLabel(int index) {
-    return gen_->code()->GetLabel(InputRpo(index));
-  }
+  Label* InputLabel(int index) { return gen_->GetLabel(InputRpo(index)); }
 
   BasicBlock::RpoNumber InputRpo(int index) {
     int rpo_number = InputInt32(index);
index 7ca27ce7596e90326b26bf574a4798ac8ca8bc9e..6b04eef62451abef4c491f28c567a333f7dbc487 100644 (file)
@@ -18,6 +18,7 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
       linkage_(linkage),
       code_(code),
       info_(info),
+      labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
       current_block_(BasicBlock::RpoNumber::Invalid()),
       current_source_position_(SourcePosition::Invalid()),
       masm_(code->zone()->isolate(), NULL, 0),
@@ -26,7 +27,11 @@ CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
       deoptimization_states_(code->zone()),
       deoptimization_literals_(code->zone()),
       translations_(code->zone()),
-      last_lazy_deopt_pc_(0) {}
+      last_lazy_deopt_pc_(0) {
+  for (int i = 0; i < code->InstructionBlockCount(); ++i) {
+    new (&labels_[i]) Label;
+  }
+}
 
 
 Handle<Code> CodeGenerator::GenerateCode() {
@@ -45,19 +50,24 @@ Handle<Code> CodeGenerator::GenerateCode() {
   info->set_prologue_offset(masm()->pc_offset());
   AssemblePrologue();
 
-  // Assemble all non-deferred instructions.
-  for (auto const block : code()->instruction_blocks()) {
-    if (block->IsDeferred()) continue;
-    for (int i = block->code_start(); i < block->code_end(); ++i) {
-      AssembleInstruction(code()->InstructionAt(i));
-    }
-  }
-
-  // Assemble all deferred instructions.
-  for (auto const block : code()->instruction_blocks()) {
-    if (!block->IsDeferred()) continue;
-    for (int i = block->code_start(); i < block->code_end(); ++i) {
-      AssembleInstruction(code()->InstructionAt(i));
+  // Assemble all non-deferred blocks, followed by deferred ones.
+  for (int deferred = 0; deferred < 2; ++deferred) {
+    for (auto const block : code()->instruction_blocks()) {
+      if (block->IsDeferred() == (deferred == 0)) {
+        continue;
+      }
+      // Bind a label for a block.
+      current_block_ = block->rpo_number();
+      if (FLAG_code_comments) {
+        // TODO(titzer): these code comments are a giant memory leak.
+        Vector<char> buffer = Vector<char>::New(32);
+        SNPrintF(buffer, "-- B%d start --", block->id().ToInt());
+        masm()->RecordComment(buffer.start());
+      }
+      masm()->bind(GetLabel(current_block_));
+      for (int i = block->code_start(); i < block->code_end(); ++i) {
+        AssembleInstruction(code()->InstructionAt(i));
+      }
     }
   }
 
@@ -120,18 +130,6 @@ void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
 
 
 void CodeGenerator::AssembleInstruction(Instruction* instr) {
-  if (instr->IsBlockStart()) {
-    // Bind a label for a block start and handle parallel moves.
-    BlockStartInstruction* block_start = BlockStartInstruction::cast(instr);
-    current_block_ = block_start->rpo_number();
-    if (FLAG_code_comments) {
-      // TODO(titzer): these code comments are a giant memory leak.
-      Vector<char> buffer = Vector<char>::New(32);
-      SNPrintF(buffer, "-- B%d start --", block_start->id().ToInt());
-      masm()->RecordComment(buffer.start());
-    }
-    masm()->bind(block_start->label());
-  }
   if (instr->IsGapMoves()) {
     // Handle parallel moves associated with the gap instruction.
     AssembleGap(GapInstruction::cast(instr));
index 2184a8405d5757993010ca8ab68aaecf4d78e565..b03e2add31192a19d8fe33d571f5e4c5555558a7 100644 (file)
@@ -33,6 +33,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   Isolate* isolate() const { return zone()->isolate(); }
   Linkage* linkage() const { return linkage_; }
 
+  Label* GetLabel(BasicBlock::RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
+
  private:
   MacroAssembler* masm() { return &masm_; }
   GapResolver* resolver() { return &resolver_; }
@@ -122,6 +124,7 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   Linkage* const linkage_;
   InstructionSequence* const code_;
   CompilationInfo* const info_;
+  Label* const labels_;
   BasicBlock::RpoNumber current_block_;
   SourcePosition current_source_position_;
   MacroAssembler masm_;
index 8711242a7b1514ae1cb6dee87e0542e10ac44849..dda469639d9fc25ad7c396509a20a75da3f79a02 100644 (file)
@@ -195,7 +195,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ jmp(code()->GetLabel(i.InputRpo(0)));
+      __ jmp(GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -498,8 +498,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
   BasicBlock::RpoNumber fblock =
       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
   bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  Label* tlabel = GetLabel(tblock);
+  Label* flabel = fallthru ? &done : GetLabel(fblock);
   Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
   switch (condition) {
     case kUnorderedEqual:
index 218130c686c585f8de4456a18522916f9c2a660b..d575be4d12a17a248c84734d671bf1c19f7a3946 100644 (file)
@@ -420,6 +420,7 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
                                          InstructionBlocks* instruction_blocks)
     : zone_(instruction_zone),
       instruction_blocks_(instruction_blocks),
+      block_starts_(zone()),
       constants_(ConstantMap::key_compare(),
                  ConstantMap::allocator_type(zone())),
       immediates_(zone()),
@@ -428,29 +429,25 @@ InstructionSequence::InstructionSequence(Zone* instruction_zone,
       pointer_maps_(zone()),
       doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
       references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
-      deoptimization_entries_(zone()) {}
-
-
-Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) {
-  return GetBlockStart(rpo)->label();
+      deoptimization_entries_(zone()) {
+  block_starts_.reserve(instruction_blocks_->size());
 }
 
 
 BlockStartInstruction* InstructionSequence::GetBlockStart(
     BasicBlock::RpoNumber rpo) {
   InstructionBlock* block = InstructionBlockAt(rpo);
-  BlockStartInstruction* block_start =
-      BlockStartInstruction::cast(InstructionAt(block->code_start()));
-  DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt());
-  return block_start;
+  return BlockStartInstruction::cast(InstructionAt(block->code_start()));
 }
 
 
 void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
+  DCHECK(block_starts_.size() == rpo.ToSize());
   InstructionBlock* block = InstructionBlockAt(rpo);
-  block->set_code_start(static_cast<int>(instructions_.size()));
-  BlockStartInstruction* block_start =
-      BlockStartInstruction::New(zone(), block->id(), rpo);
+  int code_start = static_cast<int>(instructions_.size());
+  block->set_code_start(code_start);
+  block_starts_.push_back(code_start);
+  BlockStartInstruction* block_start = BlockStartInstruction::New(zone());
   AddInstruction(block_start);
 }
 
@@ -483,15 +480,15 @@ int InstructionSequence::AddInstruction(Instruction* instr) {
 
 const InstructionBlock* InstructionSequence::GetInstructionBlock(
     int instruction_index) const {
-  // TODO(turbofan): Optimize this.
-  for (;;) {
-    DCHECK_LE(0, instruction_index);
-    Instruction* instruction = InstructionAt(instruction_index--);
-    if (instruction->IsBlockStart()) {
-      return instruction_blocks_->at(
-          BlockStartInstruction::cast(instruction)->rpo_number().ToSize());
-    }
-  }
+  DCHECK(instruction_blocks_->size() == block_starts_.size());
+  auto begin = block_starts_.begin();
+  auto end = std::lower_bound(begin, block_starts_.end(), instruction_index,
+                              std::less_equal<int>());
+  size_t index = std::distance(begin, end) - 1;
+  auto block = instruction_blocks_->at(index);
+  DCHECK(block->code_start() <= instruction_index &&
+         instruction_index < block->code_end());
+  return block;
 }
 
 
index 426d4cd28d20015fc2dc6d5e0aead20cebdfea12..b6fcb3c074aaa8a441d38e7f5c7746c0f8a34857 100644 (file)
@@ -617,17 +617,11 @@ class GapInstruction : public Instruction {
 
 // This special kind of gap move instruction represents the beginning of a
 // block of code.
-// TODO(titzer): move code_start and code_end from BasicBlock to here.
 class BlockStartInstruction FINAL : public GapInstruction {
  public:
-  Label* label() { return &label_; }
-  BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
-  BasicBlock::Id id() const { return id_; }
-
-  static BlockStartInstruction* New(Zone* zone, BasicBlock::Id id,
-                                    BasicBlock::RpoNumber rpo_number) {
+  static BlockStartInstruction* New(Zone* zone) {
     void* buffer = zone->New(sizeof(BlockStartInstruction));
-    return new (buffer) BlockStartInstruction(id, rpo_number);
+    return new (buffer) BlockStartInstruction();
   }
 
   static BlockStartInstruction* cast(Instruction* instr) {
@@ -636,14 +630,7 @@ class BlockStartInstruction FINAL : public GapInstruction {
   }
 
  private:
-  BlockStartInstruction(BasicBlock::Id id, BasicBlock::RpoNumber rpo_number)
-      : GapInstruction(kBlockStartInstruction),
-        id_(id),
-        rpo_number_(rpo_number) {}
-
-  BasicBlock::Id id_;
-  BasicBlock::RpoNumber rpo_number_;
-  Label label_;
+  BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {}
 };
 
 
@@ -925,7 +912,6 @@ class InstructionSequence FINAL {
 
   void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
 
-  Label* GetLabel(BasicBlock::RpoNumber rpo);
   BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo);
 
   typedef InstructionDeque::const_iterator const_iterator;
@@ -1000,6 +986,7 @@ class InstructionSequence FINAL {
 
   Zone* const zone_;
   InstructionBlocks* const instruction_blocks_;
+  IntVector block_starts_;
   ConstantMap constants_;
   ConstantDeque immediates_;
   InstructionDeque instructions_;
index 1c6688e953f9bc5df5ded75ce90f49c15045da12..2836113db2b0beb601cf573357b5877cff77bfad 100644 (file)
@@ -154,7 +154,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ Branch(code_->GetLabel(i.InputRpo(0)));
+      __ Branch(GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -403,8 +403,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
   BasicBlock::RpoNumber fblock =
       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
   bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  Label* tlabel = GetLabel(tblock);
+  Label* flabel = fallthru ? &done : GetLabel(fblock);
   Condition cc = kNoCondition;
 
   // MIPS does not have condition code flags, so compare and branch are
index bb02441ff5c373a55a36754772a766165395cfaa..be9af48d4bf57d610535423fcc00a9bc89227a89 100644 (file)
@@ -238,7 +238,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ jmp(code_->GetLabel(i.InputRpo(0)));
+      __ jmp(GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -620,8 +620,8 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
   BasicBlock::RpoNumber fblock =
       i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
   bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
+  Label* tlabel = GetLabel(tblock);
+  Label* flabel = fallthru ? &done : GetLabel(fblock);
   Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
   switch (condition) {
     case kUnorderedEqual: