[turbofan] remove some of the dependency of Instruction on Schedule
authordcarney@chromium.org <dcarney@chromium.org>
Tue, 14 Oct 2014 08:51:22 +0000 (08:51 +0000)
committerdcarney@chromium.org <dcarney@chromium.org>
Tue, 14 Oct 2014 08:51:22 +0000 (08:51 +0000)
R=bmeurer@chromium.org

BUG=

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24584 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

18 files changed:
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/graph-visualizer.cc
src/compiler/ia32/code-generator-ia32.cc
src/compiler/instruction-selector-impl.h
src/compiler/instruction-selector.cc
src/compiler/instruction.cc
src/compiler/instruction.h
src/compiler/mips/code-generator-mips.cc
src/compiler/register-allocator.cc
src/compiler/schedule.cc
src/compiler/schedule.h
src/compiler/x64/code-generator-x64.cc
src/zone-containers.h
test/cctest/compiler/test-instruction.cc

index f278326cf7bbd52648a850aba271c11361b4e5cc..6f8859b1064738bf44104ff1e17a0e7faa9ca56d 100644 (file)
@@ -193,7 +193,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ b(code_->GetLabel(i.InputBlock(0)));
+      __ b(code_->GetLabel(i.InputRpo(0)));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArchNop:
@@ -485,8 +485,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
 
   // Emit a branch. The true and false targets are always the last two inputs
   // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
+  BasicBlock::RpoNumber tblock =
+      i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+  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);
index da229d85d007d9d33c05471a059d0917bd156889..fe62d5991039212ce1a0a60c114d366efc2044f8 100644 (file)
@@ -164,7 +164,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ B(code_->GetLabel(i.InputBlock(0)));
+      __ B(code_->GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -526,8 +526,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
 
   // Emit a branch. The true and false targets are always the last two inputs
   // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
+  BasicBlock::RpoNumber tblock =
+      i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+  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);
index 318b7e96abb3d8362f227eecf0af92be02405f79..92d3b0523f88fd7449146bafb2239c9aa1c881df 100644 (file)
@@ -6,14 +6,9 @@
 #define V8_COMPILER_CODE_GENERATOR_IMPL_H_
 
 #include "src/compiler/code-generator.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/generic-graph.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/linkage.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
 #include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
 
 namespace v8 {
 namespace internal {
@@ -61,12 +56,12 @@ class InstructionOperandConverter {
   }
 
   Label* InputLabel(int index) {
-    return gen_->code()->GetLabel(InputBlock(index));
+    return gen_->code()->GetLabel(InputRpo(index));
   }
 
-  BasicBlock* InputBlock(int index) {
-    int block_id = InputInt32(index);
-    return gen_->schedule()->GetBlockById(BasicBlock::Id::FromInt(block_id));
+  BasicBlock::RpoNumber InputRpo(int index) {
+    int rpo_number = InputInt32(index);
+    return BasicBlock::RpoNumber::FromInt(rpo_number);
   }
 
   Register OutputRegister(int index = 0) {
index fc62119cd6c2bc32a1a1c5237ed5a4cea2ec16f9..bb0ef1bc19473a2dad38431234a43c71ff1a6ef0 100644 (file)
@@ -14,7 +14,7 @@ namespace compiler {
 
 CodeGenerator::CodeGenerator(InstructionSequence* code)
     : code_(code),
-      current_block_(NULL),
+      current_block_(BasicBlock::RpoNumber::Invalid()),
       current_source_position_(SourcePosition::Invalid()),
       masm_(code->zone()->isolate(), NULL, 0),
       resolver_(this),
@@ -103,11 +103,12 @@ 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->block();
+    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->block()->id().ToInt());
+      // TODO(dcarney): should not be rpo number there
+      SNPrintF(buffer, "-- B%d (rpo) start --", current_block_.ToInt());
       masm()->RecordComment(buffer.start());
     }
     masm()->bind(block_start->label());
index e740dd3a26641f7a86b13f333325a5f1672c2450..69d9f631f419f4672824236f1cf5cb59c46bfc21 100644 (file)
@@ -39,9 +39,8 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
 
   // Checks if {block} will appear directly after {current_block_} when
   // assembling code, in which case, a fall-through can be used.
-  bool IsNextInAssemblyOrder(const BasicBlock* block) const {
-    return block->rpo_number() == (current_block_->rpo_number() + 1) &&
-           block->deferred() == current_block_->deferred();
+  bool IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const {
+    return current_block_.IsNext(block);
   }
 
   // Record a safepoint with the given pointer map.
@@ -119,7 +118,7 @@ class CodeGenerator FINAL : public GapResolver::Assembler {
   };
 
   InstructionSequence* code_;
-  BasicBlock* current_block_;
+  BasicBlock::RpoNumber current_block_;
   SourcePosition current_source_position_;
   MacroAssembler masm_;
   GapResolver resolver_;
index 4340c250b5159f947be30c54fcf649d99a9d3d90..342ab544ace004b030b3ed061b1f30423e68d750 100644 (file)
@@ -591,9 +591,9 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
 
     PrintIntProperty("loop_depth", current->loop_depth());
 
-    if (current->code_start() >= 0) {
-      int first_index = current->first_instruction_index();
-      int last_index = current->last_instruction_index();
+    if (instructions->code_start(current) >= 0) {
+      int first_index = instructions->first_instruction_index(current);
+      int last_index = instructions->last_instruction_index(current);
       PrintIntProperty("first_lir_id", LifetimePosition::FromInstructionIndex(
                                            first_index).Value());
       PrintIntProperty("last_lir_id", LifetimePosition::FromInstructionIndex(
@@ -672,8 +672,8 @@ void GraphC1Visualizer::PrintSchedule(const char* phase,
 
     if (instructions != NULL) {
       Tag LIR_tag(this, "LIR");
-      for (int j = current->first_instruction_index();
-           j <= current->last_instruction_index(); j++) {
+      for (int j = instructions->first_instruction_index(current);
+           j <= instructions->last_instruction_index(current); j++) {
         PrintIndent();
         os_ << j << " " << *instructions->InstructionAt(j) << " <|@\n";
       }
index 454a02fa902190f2264abd2b0f5a5aa1d6a52f13..8543fd7849859b24364c489c9a097875099aef1b 100644 (file)
@@ -195,7 +195,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ jmp(code()->GetLabel(i.InputBlock(0)));
+      __ jmp(code()->GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -470,8 +470,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
 
   // Emit a branch. The true and false targets are always the last two inputs
   // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
+  BasicBlock::RpoNumber tblock =
+      i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+  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);
index f6a437d00387f3e6c3112241675fb85dabcfea98..b5459590f7640b1a35686d391d202a8867cc585e 100644 (file)
@@ -130,7 +130,7 @@ class OperandGenerator {
 
   InstructionOperand* Label(BasicBlock* block) {
     // TODO(bmeurer): We misuse ImmediateOperand here.
-    return TempImmediate(block->id().ToInt());
+    return TempImmediate(block->rpo_number());
   }
 
  protected:
index d62e253ab1b8c066880b7796110bec59e5eddeff..0cfd950acdef9ac65c97ce814fcfdefa810c6766 100644 (file)
@@ -55,11 +55,11 @@ void InstructionSelector::SelectInstructions() {
   // Schedule the selected instructions.
   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     BasicBlock* block = *i;
-    size_t end = block->code_end();
-    size_t start = block->code_start();
+    size_t end = sequence()->code_end(block);
+    size_t start = sequence()->code_start(block);
     sequence()->StartBlock(block);
     while (start-- > end) {
-      sequence()->AddInstruction(instructions_[start], block);
+      sequence()->AddInstruction(instructions_[start]);
     }
     sequence()->EndBlock(block);
   }
@@ -141,8 +141,7 @@ Instruction* InstructionSelector::Emit(Instruction* instr) {
 
 
 bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
-  return block->rpo_number() == (current_block_->rpo_number() + 1) &&
-         block->deferred() == current_block_->deferred();
+  return current_block_->GetRpoNumber().IsNext(block->GetRpoNumber());
 }
 
 
@@ -384,9 +383,8 @@ void InstructionSelector::VisitBlock(BasicBlock* block) {
   }
 
   // We're done with the block.
-  // TODO(bmeurer): We should not mutate the schedule.
-  block->set_code_start(static_cast<int>(instructions_.size()));
-  block->set_code_end(current_block_end);
+  sequence()->set_code_start(block, static_cast<int>(instructions_.size()));
+  sequence()->set_code_end(block, current_block_end);
 
   current_block_ = NULL;
 }
index 1a8276591b91f4c8e74538b6be33b6e83d23c865..7f575741e39c8bf8e6cd946ae1056621fc171d94 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "src/compiler/common-operator.h"
 #include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph.h"
 
 namespace v8 {
 namespace internal {
@@ -321,6 +322,7 @@ InstructionSequence::InstructionSequence(Linkage* linkage, Graph* graph,
     : zone_(schedule->zone()),
       node_count_(graph->NodeCount()),
       node_map_(zone()->NewArray<int>(node_count_)),
+      block_data_(schedule->BasicBlockCount(), zone()),
       linkage_(linkage),
       schedule_(schedule),
       constants_(ConstantMap::key_compare(),
@@ -346,32 +348,36 @@ int InstructionSequence::GetVirtualRegister(const Node* node) {
 }
 
 
-Label* InstructionSequence::GetLabel(BasicBlock* block) {
-  return GetBlockStart(block)->label();
+Label* InstructionSequence::GetLabel(BasicBlock::RpoNumber rpo) {
+  return GetBlockStart(rpo)->label();
 }
 
 
-BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) {
-  return BlockStartInstruction::cast(InstructionAt(block->code_start()));
+BlockStartInstruction* InstructionSequence::GetBlockStart(
+    BasicBlock::RpoNumber rpo) {
+  BlockStartInstruction* block_start =
+      BlockStartInstruction::cast(InstructionAt(code_start(rpo)));
+  DCHECK_EQ(rpo.ToInt(), block_start->rpo_number().ToInt());
+  return block_start;
 }
 
 
 void InstructionSequence::StartBlock(BasicBlock* block) {
-  block->set_code_start(static_cast<int>(instructions_.size()));
+  set_code_start(block, static_cast<int>(instructions_.size()));
   BlockStartInstruction* block_start =
       BlockStartInstruction::New(zone(), block);
-  AddInstruction(block_start, block);
+  AddInstruction(block_start);
 }
 
 
 void InstructionSequence::EndBlock(BasicBlock* block) {
   int end = static_cast<int>(instructions_.size());
-  DCHECK(block->code_start() >= 0 && block->code_start() < end);
-  block->set_code_end(end);
+  DCHECK(code_start(block) >= 0 && code_start(block) < end);
+  set_code_end(block, end);
 }
 
 
-int InstructionSequence::AddInstruction(Instruction* instr, BasicBlock* block) {
+int InstructionSequence::AddInstruction(Instruction* instr) {
   // TODO(titzer): the order of these gaps is a holdover from Lithium.
   GapInstruction* gap = GapInstruction::New(zone());
   if (instr->IsControl()) instructions_.push_back(gap);
@@ -395,7 +401,8 @@ BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) {
     DCHECK_LE(0, instruction_index);
     Instruction* instruction = InstructionAt(instruction_index--);
     if (instruction->IsBlockStart()) {
-      return BlockStartInstruction::cast(instruction)->block();
+      return schedule()->rpo_order()->at(
+          BlockStartInstruction::cast(instruction)->rpo_number().ToSize());
     }
   }
 }
@@ -537,8 +544,8 @@ std::ostream& operator<<(std::ostream& os, const InstructionSequence& code) {
       os << " loop blocks: [" << block->rpo_number() << ", "
          << block->loop_end() << ")";
     }
-    os << "  instructions: [" << block->code_start() << ", "
-       << block->code_end() << ")\n  predecessors:";
+    os << "  instructions: [" << code.code_start(block) << ", "
+       << code.code_end(block) << ")\n  predecessors:";
 
     for (BasicBlock::Predecessors::iterator iter = block->predecessors_begin();
          iter != block->predecessors_end(); ++iter) {
@@ -560,8 +567,8 @@ std::ostream& operator<<(std::ostream& os, const InstructionSequence& code) {
     }
 
     ScopedVector<char> buf(32);
-    for (int j = block->first_instruction_index();
-         j <= block->last_instruction_index(); j++) {
+    for (int j = code.first_instruction_index(block);
+         j <= code.last_instruction_index(block); j++) {
       // TODO(svenpanne) Add some basic formatting to our streams.
       SNPrintF(buf, "%5d", j);
       os << "   " << buf.start() << ": " << *code.InstructionAt(j) << "\n";
index 2bb2b72c1b89380ddb97b7bd21c9a0d24753b931..72ea0433d59d536491a7d73f524908bd55e4df5d 100644 (file)
 
 #include "src/compiler/common-operator.h"
 #include "src/compiler/frame.h"
-#include "src/compiler/graph.h"
 #include "src/compiler/instruction-codes.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/schedule.h"
+#include "src/compiler/source-position.h"
 // TODO(titzer): don't include the macro-assembler?
 #include "src/macro-assembler.h"
 #include "src/zone-allocator.h"
@@ -596,8 +596,8 @@ class GapInstruction : public Instruction {
 // TODO(titzer): move code_start and code_end from BasicBlock to here.
 class BlockStartInstruction FINAL : public GapInstruction {
  public:
-  BasicBlock* block() const { return block_; }
   Label* label() { return &label_; }
+  BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
 
   static BlockStartInstruction* New(Zone* zone, BasicBlock* block) {
     void* buffer = zone->New(sizeof(BlockStartInstruction));
@@ -611,9 +611,10 @@ class BlockStartInstruction FINAL : public GapInstruction {
 
  private:
   explicit BlockStartInstruction(BasicBlock* block)
-      : GapInstruction(kBlockStartInstruction), block_(block) {}
+      : GapInstruction(kBlockStartInstruction),
+        rpo_number_(block->GetRpoNumber()) {}
 
-  BasicBlock* block_;
+  BasicBlock::RpoNumber rpo_number_;
   Label label_;
 };
 
@@ -781,8 +782,6 @@ class InstructionSequence FINAL {
     return block->loop_header();
   }
 
-  int GetLoopEnd(BasicBlock* block) const { return block->loop_end(); }
-
   BasicBlock* GetBasicBlock(int instruction_index);
 
   int GetVirtualRegister(const Node* node);
@@ -797,8 +796,8 @@ class InstructionSequence FINAL {
 
   void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
 
-  Label* GetLabel(BasicBlock* block);
-  BlockStartInstruction* GetBlockStart(BasicBlock* block);
+  Label* GetLabel(BasicBlock::RpoNumber rpo);
+  BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo);
 
   typedef InstructionDeque::const_iterator const_iterator;
   const_iterator begin() const { return instructions_.begin(); }
@@ -821,10 +820,32 @@ class InstructionSequence FINAL {
   const PointerMapDeque* pointer_maps() const { return &pointer_maps_; }
   Zone* zone() const { return zone_; }
 
-  // Used by the code generator while adding instructions.
-  int AddInstruction(Instruction* instr, BasicBlock* block);
+  // Used by the instruction selector while adding instructions.
+  int AddInstruction(Instruction* instr);
   void StartBlock(BasicBlock* block);
   void EndBlock(BasicBlock* block);
+  void set_code_start(BasicBlock* block, int start) {
+    return GetBlockData(block->GetRpoNumber()).set_code_start(start);
+  }
+  void set_code_end(BasicBlock* block, int end) {
+    return GetBlockData(block->GetRpoNumber()).set_code_end(end);
+  }
+  // TODO(dcarney): use RpoNumber for all of the below.
+  int code_start(BasicBlock::RpoNumber rpo_number) const {
+    return GetBlockData(rpo_number).code_start();
+  }
+  int code_start(BasicBlock* block) const {
+    return GetBlockData(block->GetRpoNumber()).code_start();
+  }
+  int code_end(BasicBlock* block) const {
+    return GetBlockData(block->GetRpoNumber()).code_end();
+  }
+  int first_instruction_index(BasicBlock* block) const {
+    return GetBlockData(block->GetRpoNumber()).first_instruction_index();
+  }
+  int last_instruction_index(BasicBlock* block) const {
+    return GetBlockData(block->GetRpoNumber()).last_instruction_index();
+  }
 
   int AddConstant(Node* node, Constant constant) {
     int virtual_register = GetVirtualRegister(node);
@@ -868,14 +889,51 @@ class InstructionSequence FINAL {
   int GetFrameStateDescriptorCount();
 
  private:
+  class BlockData {
+   public:
+    BlockData() : code_start_(-1), code_end_(-1) {}
+    // Instruction indexes (used by the register allocator).
+    int first_instruction_index() const {
+      DCHECK(code_start_ >= 0);
+      DCHECK(code_end_ > 0);
+      DCHECK(code_end_ >= code_start_);
+      return code_start_;
+    }
+    int last_instruction_index() const {
+      DCHECK(code_start_ >= 0);
+      DCHECK(code_end_ > 0);
+      DCHECK(code_end_ >= code_start_);
+      return code_end_ - 1;
+    }
+
+    int32_t code_start() const { return code_start_; }
+    void set_code_start(int32_t start) { code_start_ = start; }
+
+    int32_t code_end() const { return code_end_; }
+    void set_code_end(int32_t end) { code_end_ = end; }
+
+   private:
+    int32_t code_start_;  // start index of arch-specific code.
+    int32_t code_end_;    // end index of arch-specific code.
+  };
+
+  const BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) const {
+    return block_data_[rpo_number.ToSize()];
+  }
+  BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) {
+    return block_data_[rpo_number.ToSize()];
+  }
+
   friend std::ostream& operator<<(std::ostream& os,
                                   const InstructionSequence& code);
 
   typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
+  typedef ZoneVector<BlockData> BlockDataVector;
 
   Zone* zone_;
   int node_count_;
   int* node_map_;
+  BlockDataVector block_data_;
   Linkage* linkage_;
   Schedule* schedule_;
   ConstantMap constants_;
index 19d1b024e01cc9b2ecaac2dd9902dd25ec6fdc2f..8dcca27601ecf684d2de257ab017e3aa200d7482 100644 (file)
@@ -154,7 +154,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ Branch(code_->GetLabel(i.InputBlock(0)));
+      __ Branch(code_->GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -393,8 +393,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
 
   // Emit a branch. The true and false targets are always the last two inputs
   // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
+  BasicBlock::RpoNumber tblock =
+      i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+  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);
index fbaf4fa4e7e941d962855f9f53657cd85ddc22d8..c0ee02fb39fb56adc4b34a6d619b1c69952bfefd 100644 (file)
@@ -559,10 +559,11 @@ void RegisterAllocator::AddInitialIntervals(BasicBlock* block,
                                             BitVector* live_out) {
   // Add an interval that includes the entire block to the live range for
   // each live_out value.
-  LifetimePosition start =
-      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
-  LifetimePosition end = LifetimePosition::FromInstructionIndex(
-                             block->last_instruction_index()).NextInstruction();
+  LifetimePosition start = LifetimePosition::FromInstructionIndex(
+      code()->first_instruction_index(block));
+  LifetimePosition end =
+      LifetimePosition::FromInstructionIndex(
+          code()->last_instruction_index(block)).NextInstruction();
   BitVector::Iterator iterator(live_out);
   while (!iterator.Done()) {
     int operand_index = iterator.Current();
@@ -651,7 +652,7 @@ LiveRange* RegisterAllocator::LiveRangeFor(int index) {
 
 
 GapInstruction* RegisterAllocator::GetLastGap(BasicBlock* block) {
-  int last_instruction = block->last_instruction_index();
+  int last_instruction = code()->last_instruction_index(block);
   return code()->GapAt(last_instruction - 1);
 }
 
@@ -729,8 +730,8 @@ void RegisterAllocator::AddConstraintsGapMove(int index,
 
 
 void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) {
-  int start = block->first_instruction_index();
-  int end = block->last_instruction_index();
+  int start = code()->first_instruction_index(block);
+  int end = code()->last_instruction_index(block);
   DCHECK_NE(-1, start);
   for (int i = start; i <= end; ++i) {
     if (code()->IsGapAt(i)) {
@@ -752,7 +753,7 @@ void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) {
 
 void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
     BasicBlock* block) {
-  int end = block->last_instruction_index();
+  int end = code()->last_instruction_index(block);
   Instruction* last_instruction = InstructionAt(end);
   for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
     InstructionOperand* output_operand = last_instruction->OutputAt(i);
@@ -773,7 +774,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
       for (BasicBlock::Successors::iterator succ = block->successors_begin();
            succ != block->successors_end(); ++succ) {
         DCHECK((*succ)->PredecessorCount() == 1);
-        int gap_index = (*succ)->first_instruction_index() + 1;
+        int gap_index = code()->first_instruction_index(*succ) + 1;
         DCHECK(code()->IsGapAt(gap_index));
 
         // Create an unconstrained operand for the same virtual register
@@ -790,7 +791,7 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
       for (BasicBlock::Successors::iterator succ = block->successors_begin();
            succ != block->successors_end(); ++succ) {
         DCHECK((*succ)->PredecessorCount() == 1);
-        int gap_index = (*succ)->first_instruction_index() + 1;
+        int gap_index = code()->first_instruction_index(*succ) + 1;
         range->SetSpillStartIndex(gap_index);
 
         // This move to spill operand is not a real use. Liveness analysis
@@ -937,12 +938,12 @@ bool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr,
 
 void RegisterAllocator::ProcessInstructions(BasicBlock* block,
                                             BitVector* live) {
-  int block_start = block->first_instruction_index();
+  int block_start = code()->first_instruction_index(block);
 
   LifetimePosition block_start_position =
       LifetimePosition::FromInstructionIndex(block_start);
 
-  for (int index = block->last_instruction_index(); index >= block_start;
+  for (int index = code()->last_instruction_index(block); index >= block_start;
        index--) {
     LifetimePosition curr_position =
         LifetimePosition::FromInstructionIndex(index);
@@ -1081,19 +1082,21 @@ void RegisterAllocator::ResolvePhis(BasicBlock* block) {
       BasicBlock* cur_block = block->PredecessorAt(j);
       // The gap move must be added without any special processing as in
       // the AddConstraintsGapMove.
-      code()->AddGapMove(cur_block->last_instruction_index() - 1, operand,
+      code()->AddGapMove(code()->last_instruction_index(cur_block) - 1, operand,
                          phi_operand);
 
-      Instruction* branch = InstructionAt(cur_block->last_instruction_index());
+      Instruction* branch =
+          InstructionAt(code()->last_instruction_index(cur_block));
       DCHECK(!branch->HasPointerMap());
       USE(branch);
     }
 
     LiveRange* live_range = LiveRangeFor(phi_vreg);
-    BlockStartInstruction* block_start = code()->GetBlockStart(block);
+    BlockStartInstruction* block_start =
+        code()->GetBlockStart(block->GetRpoNumber());
     block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone())
         ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone());
-    live_range->SetSpillStartIndex(block->first_instruction_index());
+    live_range->SetSpillStartIndex(code()->first_instruction_index(block));
 
     // We use the phi-ness of some nodes in some later heuristics.
     live_range->set_is_phi(true);
@@ -1147,10 +1150,10 @@ void RegisterAllocator::ResolvePhis() {
 
 void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block,
                                            BasicBlock* pred) {
-  LifetimePosition pred_end =
-      LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
-  LifetimePosition cur_start =
-      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
+  LifetimePosition pred_end = LifetimePosition::FromInstructionIndex(
+      code()->last_instruction_index(pred));
+  LifetimePosition cur_start = LifetimePosition::FromInstructionIndex(
+      code()->first_instruction_index(block));
   LiveRange* pred_cover = NULL;
   LiveRange* cur_cover = NULL;
   LiveRange* cur_range = range;
@@ -1175,12 +1178,13 @@ void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block,
     if (!pred_op->Equals(cur_op)) {
       GapInstruction* gap = NULL;
       if (block->PredecessorCount() == 1) {
-        gap = code()->GapAt(block->first_instruction_index());
+        gap = code()->GapAt(code()->first_instruction_index(block));
       } else {
         DCHECK(pred->SuccessorCount() == 1);
         gap = GetLastGap(pred);
 
-        Instruction* branch = InstructionAt(pred->last_instruction_index());
+        Instruction* branch =
+            InstructionAt(code()->last_instruction_index(pred));
         DCHECK(!branch->HasPointerMap());
         USE(branch);
       }
@@ -1320,7 +1324,7 @@ void RegisterAllocator::BuildLiveRanges() {
       DCHECK(hint != NULL);
 
       LifetimePosition block_start = LifetimePosition::FromInstructionIndex(
-          block->first_instruction_index());
+          code()->first_instruction_index(block));
       Define(block_start, phi_operand, hint);
     }
 
@@ -1333,9 +1337,9 @@ void RegisterAllocator::BuildLiveRanges() {
       // for each value live on entry to the header.
       BitVector::Iterator iterator(live);
       LifetimePosition start = LifetimePosition::FromInstructionIndex(
-          block->first_instruction_index());
+          code()->first_instruction_index(block));
       int end_index =
-          code()->BlockAt(block->loop_end())->last_instruction_index();
+          code()->last_instruction_index(code()->BlockAt(block->loop_end()));
       LifetimePosition end =
           LifetimePosition::FromInstructionIndex(end_index).NextInstruction();
       while (!iterator.Done()) {
@@ -1967,7 +1971,7 @@ LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
     // If possible try to move spilling position backwards to loop header.
     // This will reduce number of memory moves on the back edge.
     LifetimePosition loop_start = LifetimePosition::FromInstructionIndex(
-        loop_header->first_instruction_index());
+        code()->first_instruction_index(loop_header));
 
     if (range->Covers(loop_start)) {
       if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) {
@@ -2105,7 +2109,7 @@ LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
   if (block == end_block && !end_block->IsLoopHeader()) return end;
 
   return LifetimePosition::FromInstructionIndex(
-      block->first_instruction_index());
+      code()->first_instruction_index(block));
 }
 
 
index d641b4bfdb99f56313d562ead0322388f1704fb8..ac6b440d78377d1b8f49cdd496615356a98616d5 100644 (file)
@@ -18,9 +18,6 @@ BasicBlock::BasicBlock(Zone* zone, Id id)
       loop_header_(NULL),
       loop_depth_(0),
       loop_end_(-1),
-      code_start_(-1),
-      code_end_(-1),
-      deferred_(false),
       control_(kNone),
       control_input_(NULL),
       nodes_(zone),
@@ -86,14 +83,6 @@ void BasicBlock::set_rpo_number(int32_t rpo_number) {
 void BasicBlock::set_loop_end(int32_t loop_end) { loop_end_ = loop_end; }
 
 
-void BasicBlock::set_code_start(int32_t code_start) {
-  code_start_ = code_start;
-}
-
-
-void BasicBlock::set_code_end(int32_t code_end) { code_end_ = code_end; }
-
-
 void BasicBlock::set_loop_header(BasicBlock* loop_header) {
   loop_header_ = loop_header;
 }
index 68686b52f5fceb687fb57793b192590480ab8edf..acfc44768d2694ddbfafa63d3bc47afb215d067b 100644 (file)
@@ -50,24 +50,28 @@ class BasicBlock FINAL : public ZoneObject {
     size_t index_;
   };
 
+  class RpoNumber FINAL {
+   public:
+    int ToInt() const { return static_cast<int>(index_); }
+    size_t ToSize() const { return index_; }
+    static RpoNumber FromInt(int index) {
+      return RpoNumber(static_cast<size_t>(index));
+    }
+    static RpoNumber Invalid() { return RpoNumber(static_cast<size_t>(-1)); }
+
+    bool IsNext(const RpoNumber other) const {
+      return other.index_ == this->index_ + 1;
+    }
+
+   private:
+    explicit RpoNumber(size_t index) : index_(index) {}
+    size_t index_;
+  };
+
   BasicBlock(Zone* zone, Id id);
 
   Id id() const { return id_; }
 
-  // Instruction indexes (used by the register allocator).
-  int first_instruction_index() {
-    DCHECK(code_start_ >= 0);
-    DCHECK(code_end_ > 0);
-    DCHECK(code_end_ >= code_start_);
-    return code_start_;
-  }
-  int last_instruction_index() {
-    DCHECK(code_start_ >= 0);
-    DCHECK(code_end_ > 0);
-    DCHECK(code_end_ >= code_start_);
-    return code_end_ - 1;
-  }
-
   // Predecessors and successors.
   typedef ZoneVector<BasicBlock*> Predecessors;
   Predecessors::iterator predecessors_begin() { return predecessors_.begin(); }
@@ -126,17 +130,10 @@ class BasicBlock FINAL : public ZoneObject {
   int32_t loop_end() const { return loop_end_; }
   void set_loop_end(int32_t loop_end);
 
+  RpoNumber GetRpoNumber() const { return RpoNumber::FromInt(rpo_number_); }
   int32_t rpo_number() const { return rpo_number_; }
   void set_rpo_number(int32_t rpo_number);
 
-  int32_t code_start() const { return code_start_; }
-  void set_code_start(int32_t start);
-
-  int32_t code_end() const { return code_end_; }
-  void set_code_end(int32_t end);
-
-  bool deferred() const { return deferred_; }
-
   // Loop membership helpers.
   inline bool IsLoopHeader() const { return loop_end_ >= 0; }
   bool LoopContains(BasicBlock* block) const;
@@ -150,10 +147,7 @@ class BasicBlock FINAL : public ZoneObject {
                              // enclosing loop header.
   int32_t loop_depth_;       // loop nesting, 0 is top-level
   int32_t loop_end_;         // end of the loop, if this block is a loop header.
-  int32_t code_start_;       // start index of arch-specific code.
-  int32_t code_end_;         // end index of arch-specific code.
-  bool deferred_;            // {true} if this block is considered the slow
-                             // path.
+
   Control control_;          // Control at the end of the block.
   Node* control_input_;      // Input value for control.
   NodeVector nodes_;         // nodes of this block in forward order.
index fa9f5117ad3ffcc55d6f7903fb938f97c0b1b7a8..441187668b84b6ca4dc00634d4e42e8b2b5978c4 100644 (file)
@@ -233,7 +233,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
       break;
     }
     case kArchJmp:
-      __ jmp(code_->GetLabel(i.InputBlock(0)));
+      __ jmp(code_->GetLabel(i.InputRpo(0)));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -583,8 +583,10 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr,
 
   // Emit a branch. The true and false targets are always the last two inputs
   // to the instruction.
-  BasicBlock* tblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 2);
-  BasicBlock* fblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 1);
+  BasicBlock::RpoNumber tblock =
+      i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+  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);
index 2ee178029ff8d95c245e02d478d297b09d3f39bb..4998cbf3fe990b08208e93da5a49491d96ee5064 100644 (file)
@@ -23,6 +23,12 @@ class ZoneVector : public std::vector<T, zone_allocator<T> > {
   explicit ZoneVector(Zone* zone)
       : std::vector<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}
 
+  // Constructs a new vector and fills it with {size} elements, each
+  // constructed via the default constructor.
+  ZoneVector(int size, Zone* zone)
+      : std::vector<T, zone_allocator<T> >(size, T(), zone_allocator<T>(zone)) {
+  }
+
   // Constructs a new vector and fills it with {size} elements, each
   // having the value {def}.
   ZoneVector(int size, T def, Zone* zone)
index 073d584489f565180c7a27e7846977dd85dd28ec..d0e4762f45443d22803e96b75449f2070e613534 100644 (file)
@@ -81,10 +81,10 @@ class InstructionTester : public HandleAndZoneScope {
     return node;
   }
 
-  int NewInstr(BasicBlock* block) {
+  int NewInstr() {
     InstructionCode opcode = static_cast<InstructionCode>(110);
     TestInstr* instr = TestInstr::New(zone(), opcode);
-    return code->AddInstruction(instr, block);
+    return code->AddInstruction(instr);
   }
 
   UnallocatedOperand* NewUnallocated(int vreg) {
@@ -122,7 +122,7 @@ TEST(InstructionBasic) {
        i++, index++) {
     BasicBlock* block = *i;
     CHECK_EQ(block, R.code->BlockAt(index));
-    CHECK_EQ(-1, R.code->GetLoopEnd(block));
+    CHECK_EQ(-1, block->loop_end());
   }
 }
 
@@ -142,19 +142,19 @@ TEST(InstructionGetBasicBlock) {
   R.allocCode();
 
   R.code->StartBlock(b0);
-  int i0 = R.NewInstr(b0);
-  int i1 = R.NewInstr(b0);
+  int i0 = R.NewInstr();
+  int i1 = R.NewInstr();
   R.code->EndBlock(b0);
   R.code->StartBlock(b1);
-  int i2 = R.NewInstr(b1);
-  int i3 = R.NewInstr(b1);
-  int i4 = R.NewInstr(b1);
-  int i5 = R.NewInstr(b1);
+  int i2 = R.NewInstr();
+  int i3 = R.NewInstr();
+  int i4 = R.NewInstr();
+  int i5 = R.NewInstr();
   R.code->EndBlock(b1);
   R.code->StartBlock(b2);
-  int i6 = R.NewInstr(b2);
-  int i7 = R.NewInstr(b2);
-  int i8 = R.NewInstr(b2);
+  int i6 = R.NewInstr();
+  int i7 = R.NewInstr();
+  int i8 = R.NewInstr();
   R.code->EndBlock(b2);
   R.code->StartBlock(b3);
   R.code->EndBlock(b3);
@@ -171,17 +171,17 @@ TEST(InstructionGetBasicBlock) {
   CHECK_EQ(b2, R.code->GetBasicBlock(i7));
   CHECK_EQ(b2, R.code->GetBasicBlock(i8));
 
-  CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index()));
-  CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index()));
+  CHECK_EQ(b0, R.code->GetBasicBlock(R.code->first_instruction_index(b0)));
+  CHECK_EQ(b0, R.code->GetBasicBlock(R.code->last_instruction_index(b0)));
 
-  CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index()));
-  CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index()));
+  CHECK_EQ(b1, R.code->GetBasicBlock(R.code->first_instruction_index(b1)));
+  CHECK_EQ(b1, R.code->GetBasicBlock(R.code->last_instruction_index(b1)));
 
-  CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index()));
-  CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index()));
+  CHECK_EQ(b2, R.code->GetBasicBlock(R.code->first_instruction_index(b2)));
+  CHECK_EQ(b2, R.code->GetBasicBlock(R.code->last_instruction_index(b2)));
 
-  CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index()));
-  CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index()));
+  CHECK_EQ(b3, R.code->GetBasicBlock(R.code->first_instruction_index(b3)));
+  CHECK_EQ(b3, R.code->GetBasicBlock(R.code->last_instruction_index(b3)));
 }
 
 
@@ -195,8 +195,8 @@ TEST(InstructionIsGapAt) {
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
   R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
   R.code->EndBlock(b0);
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
@@ -222,15 +222,15 @@ TEST(InstructionIsGapAt2) {
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
   R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
   R.code->EndBlock(b0);
 
   TestInstr* i1 = TestInstr::New(R.zone(), 102);
   TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
   R.code->StartBlock(b1);
-  R.code->AddInstruction(i1, b1);
-  R.code->AddInstruction(g1, b1);
+  R.code->AddInstruction(i1);
+  R.code->AddInstruction(g1);
   R.code->EndBlock(b1);
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
@@ -263,8 +263,8 @@ TEST(InstructionAddGapMove) {
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
   R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
   R.code->EndBlock(b0);
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());