Bug 1096138 - IonMonkey: Augment Nops with Mops to avoid collisions with fixed live ranges. r=jandem, a=sledru
authorDan Gohman <sunfish@mozilla.com>
Fri, 09 Jan 2015 09:04:12 -0500
changeset 200502 c34347a324e60be0d1938f8f9c2a79d4225ea655
parent 200501 34349c4ca4de5e235806b05aca2c75bf95f5bf68
child 200505 175f522174821e22b5d9ffb42c3310bafb56b201
push id158
push userryanvm@gmail.com
push dateFri, 09 Jan 2015 14:04:38 +0000
treeherdermozilla-esr31@c34347a324e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, sledru
bugs1096138
milestone31.4.0esrpre
Bug 1096138 - IonMonkey: Augment Nops with Mops to avoid collisions with fixed live ranges. r=jandem, a=sledru
js/src/jit/CodeGenerator.cpp
js/src/jit/CodeGenerator.h
js/src/jit/LIR-Common.h
js/src/jit/LOpcodes.h
js/src/jit/Lowering.cpp
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -1072,16 +1072,22 @@ CodeGenerator::visitLabel(LLabel *lir)
 
 bool
 CodeGenerator::visitNop(LNop *lir)
 {
     return true;
 }
 
 bool
+CodeGenerator::visitMop(LMop *lir)
+{
+    return true;
+}
+
+bool
 CodeGenerator::visitOsiPoint(LOsiPoint *lir)
 {
     // Note: markOsiPoint ensures enough space exists between the last
     // LOsiPoint and this one to patch adjacent call instructions.
 
     JS_ASSERT(masm.framePushed() == frameSize());
 
     uint32_t osiCallPointOffset;
--- a/js/src/jit/CodeGenerator.h
+++ b/js/src/jit/CodeGenerator.h
@@ -53,16 +53,17 @@ class CodeGenerator : public CodeGenerat
 
   public:
     bool generate();
     bool generateAsmJS(Label *stackOverflowLabel);
     bool link(JSContext *cx, types::CompilerConstraintList *constraints);
 
     bool visitLabel(LLabel *lir);
     bool visitNop(LNop *lir);
+    bool visitMop(LMop *lir);
     bool visitOsiPoint(LOsiPoint *lir);
     bool visitGoto(LGoto *lir);
     bool visitTableSwitch(LTableSwitch *ins);
     bool visitTableSwitchV(LTableSwitchV *ins);
     bool visitCloneLiteral(LCloneLiteral *lir);
     bool visitParameter(LParameter *lir);
     bool visitCallee(LCallee *lir);
     bool visitStart(LStart *lir);
--- a/js/src/jit/LIR-Common.h
+++ b/js/src/jit/LIR-Common.h
@@ -37,16 +37,22 @@ class LLabel : public LInstructionHelper
 };
 
 class LNop : public LInstructionHelper<0, 0, 0>
 {
   public:
     LIR_HEADER(Nop)
 };
 
+class LMop : public LInstructionHelper<0, 0, 0>
+{
+  public:
+    LIR_HEADER(Mop)
+};
+
 // An LOsiPoint captures a snapshot after a call and ensures enough space to
 // patch in a call to the invalidation mechanism.
 //
 // Note: LSafepoints are 1:1 with LOsiPoints, so it holds a reference to the
 // corresponding LSafepoint to inform it of the LOsiPoint's masm offset when it
 // gets CG'd.
 class LOsiPoint : public LInstructionHelper<0, 0, 0>
 {
--- a/js/src/jit/LOpcodes.h
+++ b/js/src/jit/LOpcodes.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_LOpcodes_h
 #define jit_LOpcodes_h
 
 #define LIR_COMMON_OPCODE_LIST(_)   \
     _(Label)                        \
     _(Nop)                          \
+    _(Mop)                          \
     _(OsiPoint)                     \
     _(MoveGroup)                    \
     _(Integer)                      \
     _(Pointer)                      \
     _(Double)                       \
     _(Float32)                      \
     _(Value)                        \
     _(CloneLiteral)                 \
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -3611,22 +3611,34 @@ LIRGenerator::visitInstruction(MInstruct
         updateResumeState(ins);
 
     if (gen->errored())
         return false;
 #ifdef DEBUG
     ins->setInWorklistUnchecked();
 #endif
 
+    // If we added a Nop for this instruction, we'll also add a Mop, so that
+    // that live-ranges for fixed register defs, which with LSRA extend through
+    // the Nop so that they can extend through the OsiPoint don't, with their
+    // one-extra extension, extend into a position where they use the input
+    // move group for the following instruction.
+    bool needsMop = !current->instructions().empty() && current->rbegin()->isNop();
+
     // If no safepoint was created, there's no need for an OSI point.
     if (LOsiPoint *osiPoint = popOsiPoint()) {
         if (!add(osiPoint))
             return false;
     }
 
+    if (needsMop) {
+        if (!add(new(alloc()) LMop))
+            return false;
+    }
+
     return true;
 }
 
 bool
 LIRGenerator::definePhis()
 {
     size_t lirIndex = 0;
     MBasicBlock *block = current->mir();