Revision: 17084
Author:   [email protected]
Date:     Wed Oct  2 16:58:37 2013 UTC
Log:      MIPS: Improve and simplify removal of unreachable code.

Port r17073 (ba68149)

Original commit message:
- Detect unreachable basic blocks of code either following an unconditional deopt or after a provably untaken branch of HBranch or HCompareObjectEqAndBranch instructions. - Emit dummy uses in unreachable blocks during Hydrogen -> Lithium translation.

BUG=chromium:258519
[email protected], [email protected]

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

Patch from Balazs Kilvady <[email protected]>.
http://code.google.com/p/v8/source/detail?r=17084

Modified:
 /branches/bleeding_edge/src/lithium-codegen.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
 /branches/bleeding_edge/src/mips/lithium-codegen-mips.h
 /branches/bleeding_edge/src/mips/lithium-mips.cc
 /branches/bleeding_edge/src/mips/lithium-mips.h

=======================================
--- /branches/bleeding_edge/src/lithium-codegen.cc Wed Oct 2 15:27:51 2013 UTC +++ /branches/bleeding_edge/src/lithium-codegen.cc Wed Oct 2 16:58:37 2013 UTC
@@ -39,7 +39,7 @@
 #include "arm/lithium-arm.h"
 #include "arm/lithium-codegen-arm.h"
 #elif V8_TARGET_ARCH_MIPS
-#include "mips/lithium-codegeng.h"
+#include "mips/lithium-mips.h"
 #include "mips/lithium-codegen-mips.h"
 #else
 #error Unsupported target architecture.
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Oct 2 11:25:06 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Wed Oct 2 16:58:37 2013 UTC
@@ -96,24 +96,6 @@
   info()->set_bailout_reason(reason);
   status_ = ABORTED;
 }
-
-
-void LCodeGen::Comment(const char* format, ...) {
-  if (!FLAG_code_comments) return;
-  char buffer[4 * KB];
-  StringBuilder builder(buffer, ARRAY_SIZE(buffer));
-  va_list arguments;
-  va_start(arguments, format);
-  builder.AddFormattedList(format, arguments);
-  va_end(arguments);
-
-  // Copy the string before recording it in the assembler to avoid
-  // issues when the stack allocated buffer goes out of scope.
-  size_t length = builder.position();
-  Vector<char> copy = Vector<char>::New(length + 1);
-  OS::MemCopy(copy.start(), builder.Finalize(), copy.length());
-  masm()->RecordComment(copy.start());
-}


 bool LCodeGen::GeneratePrologue() {
@@ -263,37 +245,6 @@
   ASSERT(slots >= 0);
   __ Subu(sp, sp, Operand(slots * kPointerSize));
 }
-
-
-bool LCodeGen::GenerateBody() {
-  ASSERT(is_generating());
-  bool emit_instructions = true;
-  for (current_instruction_ = 0;
-       !is_aborted() && current_instruction_ < instructions_->length();
-       current_instruction_++) {
-    LInstruction* instr = instructions_->at(current_instruction_);
-
-    // Don't emit code for basic blocks with a replacement.
-    if (instr->IsLabel()) {
-      emit_instructions = !LLabel::cast(instr)->HasReplacement();
-    }
-    if (!emit_instructions) continue;
-
-    if (FLAG_code_comments && instr->HasInterestingComment(this)) {
-      Comment(";;; <@%d,#%d> %s",
-              current_instruction_,
-              instr->hydrogen_value()->id(),
-              instr->Mnemonic());
-    }
-
-    RecordAndUpdatePosition(instr->position());
-
-    instr->CompileToNative(this);
-  }
-  EnsureSpaceForLazyDeopt();
-  last_lazy_deopt_pc_ = masm()->pc_offset();
-  return !is_aborted();
-}


 bool LCodeGen::GenerateDeferredCode() {
@@ -703,7 +654,7 @@
                                RelocInfo::Mode mode,
                                LInstruction* instr,
                                SafepointMode safepoint_mode) {
-  EnsureSpaceForLazyDeopt();
+  EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
   ASSERT(instr != NULL);
   LPointerMap* pointers = instr->pointer_map();
   RecordPosition(pointers->position());
@@ -2011,13 +1962,6 @@
 }


-int LCodeGen::GetNextEmittedBlock() const {
-  for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) {
-    if (!chunk_->GetLabel(i)->HasReplacement()) return i;
-  }
-  return -1;
-}
-
 template<class InstrType>
 void LCodeGen::EmitBranch(InstrType instr,
                           Condition condition,
@@ -5635,14 +5579,13 @@
 }


-void LCodeGen::EnsureSpaceForLazyDeopt() {
+void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
   if (info()->IsStub()) return;
   // Ensure that we have enough space after the previous lazy-bailout
   // instruction for patching the code here.
   int current_pc = masm()->pc_offset();
-  int patch_size = Deoptimizer::patch_size();
-  if (current_pc < last_lazy_deopt_pc_ + patch_size) {
-    int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
+  if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+    int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
     ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
     while (padding_size > 0) {
       __ nop();
@@ -5653,7 +5596,7 @@


 void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
-  EnsureSpaceForLazyDeopt();
+  EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
   last_lazy_deopt_pc_ = masm()->pc_offset();
   ASSERT(instr->HasEnvironment());
   LEnvironment* env = instr->environment();
@@ -5721,7 +5664,7 @@
     CallCode(isolate()->builtins()->StackCheck(),
              RelocInfo::CODE_TARGET,
              instr);
-    EnsureSpaceForLazyDeopt();
+    EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
     last_lazy_deopt_pc_ = masm()->pc_offset();
     __ bind(&done);
     RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
@@ -5733,7 +5676,7 @@
         new(zone()) DeferredStackCheck(this, instr);
     __ LoadRoot(at, Heap::kStackLimitRootIndex);
     __ Branch(deferred_stack_check->entry(), lo, sp, Operand(at));
-    EnsureSpaceForLazyDeopt();
+    EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
     last_lazy_deopt_pc_ = masm()->pc_offset();
     __ bind(instr->done_label());
     deferred_stack_check->SetExit(instr->done_label());
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Tue Oct 1 21:01:25 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.h Wed Oct 2 16:58:37 2013 UTC
@@ -31,6 +31,7 @@
 #include "deoptimizer.h"
 #include "mips/lithium-gap-resolver-mips.h"
 #include "mips/lithium-mips.h"
+#include "lithium-codegen.h"
 #include "safepoint-table.h"
 #include "scopes.h"
 #include "v8utils.h"
@@ -42,26 +43,18 @@
 class LDeferredCode;
 class SafepointGenerator;

-class LCodeGen V8_FINAL  BASE_EMBEDDED {
+class LCodeGen: public LCodeGenBase {
  public:
   LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
-      : zone_(info->zone()),
-        chunk_(static_cast<LPlatformChunk*>(chunk)),
-        masm_(assembler),
-        info_(info),
-        current_block_(-1),
-        current_instruction_(-1),
-        instructions_(chunk->instructions()),
+      : LCodeGenBase(chunk, assembler, info),
         deoptimizations_(4, info->zone()),
         deopt_jump_table_(4, info->zone()),
         deoptimization_literals_(8, info->zone()),
         inlined_function_count_(0),
         scope_(info->scope()),
-        status_(UNUSED),
         translations_(info->zone()),
         deferred_(8, info->zone()),
         osr_pc_offset_(-1),
-        last_lazy_deopt_pc_(0),
         frame_is_built_(false),
         safepoints_(info->zone()),
         resolver_(this),
@@ -70,14 +63,6 @@
     PopulateDeoptimizationLiteralsWithInlinedFunctions();
   }

-
-  // Simple accessors.
-  MacroAssembler* masm() const { return masm_; }
-  CompilationInfo* info() const { return info_; }
-  Isolate* isolate() const { return info_->isolate(); }
-  Factory* factory() const { return isolate()->factory(); }
-  Heap* heap() const { return isolate()->heap(); }
-  Zone* zone() const { return zone_; }

   int LookupDestination(int block_id) const {
     return chunk()->LookupDestination(block_id);
@@ -177,31 +162,16 @@
 #undef DECLARE_DO

  private:
-  enum Status {
-    UNUSED,
-    GENERATING,
-    DONE,
-    ABORTED
-  };
-
-  bool is_unused() const { return status_ == UNUSED; }
-  bool is_generating() const { return status_ == GENERATING; }
-  bool is_done() const { return status_ == DONE; }
-  bool is_aborted() const { return status_ == ABORTED; }
-
   StrictModeFlag strict_mode_flag() const {
     return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
   }

-  LPlatformChunk* chunk() const { return chunk_; }
   Scope* scope() const { return scope_; }
-  HGraph* graph() const { return chunk()->graph(); }

   Register scratch0() { return kLithiumScratchReg; }
   Register scratch1() { return kLithiumScratchReg2; }
   DoubleRegister double_scratch0() { return kLithiumScratchDouble; }

-  int GetNextEmittedBlock() const;
   LInstruction* GetNextInstruction();

   void EmitClassOfTest(Label* if_true,
@@ -214,14 +184,12 @@
   int GetStackSlotCount() const { return chunk()->spill_slot_count(); }

   void Abort(BailoutReason reason);
-  void FPRINTF_CHECKING Comment(const char* format, ...);

void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }

   // Code generation passes.  Returns true if code generation should
   // continue.
   bool GeneratePrologue();
-  bool GenerateBody();
   bool GenerateDeferredCode();
   bool GenerateDeoptJumpTable();
   bool GenerateSafepointTable();
@@ -328,7 +296,7 @@
                                               int arguments,
                                               Safepoint::DeoptMode mode);
   void RecordPosition(int position);
-  void RecordAndUpdatePosition(int position);
+  void RecordAndUpdatePosition(int position) V8_OVERRIDE;

   static Condition TokenToCondition(Token::Value op, bool is_unsigned);
   void EmitGoto(int block);
@@ -407,7 +375,7 @@
                                            LEnvironment* environment);


-  void EnsureSpaceForLazyDeopt();
+  void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
   void DoLoadKeyedExternalArray(LLoadKeyed* instr);
   void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
   void DoLoadKeyedFixedArray(LLoadKeyed* instr);
@@ -415,24 +383,14 @@
   void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
   void DoStoreKeyedFixedArray(LStoreKeyed* instr);

-  Zone* zone_;
-  LPlatformChunk* const chunk_;
-  MacroAssembler* const masm_;
-  CompilationInfo* const info_;
-
-  int current_block_;
-  int current_instruction_;
-  const ZoneList<LInstruction*>* instructions_;
   ZoneList<LEnvironment*> deoptimizations_;
   ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
   ZoneList<Handle<Object> > deoptimization_literals_;
   int inlined_function_count_;
   Scope* const scope_;
-  Status status_;
   TranslationBuffer translations_;
   ZoneList<LDeferredCode*> deferred_;
   int osr_pc_offset_;
-  int last_lazy_deopt_pc_;
   bool frame_is_built_;

   // Builder that keeps track of safepoints in the code. The table
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.cc Tue Oct 1 21:01:25 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.cc Wed Oct 2 16:58:37 2013 UTC
@@ -865,7 +865,22 @@
   HInstruction* old_current = current_instruction_;
   current_instruction_ = current;
   if (current->has_position()) position_ = current->position();
-  LInstruction* instr = current->CompileToLithium(this);
+
+  LInstruction* instr = NULL;
+  if (current->CanReplaceWithDummyUses()) {
+    HValue* first_operand = current->OperandCount() == 0
+        ? graph()->GetConstant1()
+        : current->OperandAt(0);
+    instr = DefineAsRegister(new(zone()) LDummyUse(UseAny(first_operand)));
+    for (int i = 1; i < current->OperandCount(); ++i) {
+      LInstruction* dummy =
+          new(zone()) LDummyUse(UseAny(current->OperandAt(i)));
+      dummy->set_hydrogen_value(current);
+      chunk_->AddInstruction(dummy, current_block_);
+    }
+  } else {
+    instr = current->CompileToLithium(this);
+  }

   if (instr != NULL) {
     // Associate the hydrogen instruction first, since we may need it for
@@ -999,19 +1014,15 @@


 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
-  return new(zone()) LGoto(instr->FirstSuccessor()->block_id());
+  return new(zone()) LGoto(instr->FirstSuccessor());
 }


 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
+
   HValue* value = instr->value();
-  if (value->EmitAtUses()) {
-    HBasicBlock* successor = HConstant::cast(value)->BooleanValue()
-        ? instr->FirstSuccessor()
-        : instr->SecondSuccessor();
-    return new(zone()) LGoto(successor->block_id());
-  }
-
   LBranch* result = new(zone()) LBranch(UseRegister(value));
   // Tagged values that are not known smis or booleans require a
   // deoptimization environment. If the instruction is generic no
@@ -1690,6 +1701,8 @@

 LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
     HCompareObjectEqAndBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
   LOperand* left = UseRegisterAtStart(instr->left());
   LOperand* right = UseRegisterAtStart(instr->right());
   return new(zone()) LCmpObjectEqAndBranch(left, right);
=======================================
--- /branches/bleeding_edge/src/mips/lithium-mips.h Tue Oct 1 21:01:25 2013 UTC +++ /branches/bleeding_edge/src/mips/lithium-mips.h Wed Oct 2 16:58:37 2013 UTC
@@ -401,17 +401,17 @@

 class LGoto V8_FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  explicit LGoto(int block_id) : block_id_(block_id) { }
+  explicit LGoto(HBasicBlock* block) : block_(block) { }

   virtual bool HasInterestingComment(LCodeGen* gen) const V8_OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
   virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
   virtual bool IsControl() const V8_OVERRIDE { return true; }

-  int block_id() const { return block_id_; }
+  int block_id() const { return block_->block_id(); }

  private:
-  int block_id_;
+  HBasicBlock* block_;
 };


@@ -2732,6 +2732,8 @@
   // Build the sequence for the graph.
   LPlatformChunk* Build();

+  LInstruction* CheckElideControlInstruction(HControlInstruction* instr);
+
   // Declare methods that deal with the individual node types.
 #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
   HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to