Bug 923799 - Mark UDivOrMod as clobbering eax when used for Mod, r=jandem.
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 10 Oct 2013 07:31:04 -0600
changeset 150327 266e7e5e3a2b484ae6de3d1b73fa2d0f3935f210
parent 150326 94bd7574eff132ca85d9a63b873af16765716f7e
child 150328 f868d4f8f27e489485aee5063c7e165328883c86
push id34825
push userbhackett@mozilla.com
push dateThu, 10 Oct 2013 13:31:14 +0000
treeherdermozilla-inbound@266e7e5e3a2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs923799
milestone27.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 923799 - Mark UDivOrMod as clobbering eax when used for Mod, r=jandem.
js/src/jit/LiveRangeAllocator.cpp
js/src/jit/shared/Lowering-shared-inl.h
js/src/jit/shared/Lowering-shared.h
js/src/jit/shared/Lowering-x86-shared.cpp
--- a/js/src/jit/LiveRangeAllocator.cpp
+++ b/js/src/jit/LiveRangeAllocator.cpp
@@ -627,19 +627,38 @@ LiveRangeAllocator<VREG>::buildLivenessI
                         if (LSafepoint *safepoint = ins->safepoint())
                             AddRegisterToSafepoint(safepoint, reg, *temp);
                     } else {
                         JS_ASSERT(!ins->isCall());
                         if (!vregs[temp].getInterval(0)->addRangeAtHead(inputOf(*ins), outputOf(*ins)))
                             return false;
                     }
                 } else {
+                    // Normally temps are considered to cover both the input
+                    // and output of the associated instruction. In some cases
+                    // though we want to use a fixed register as both an input
+                    // and clobbered register in the instruction, so watch for
+                    // this and shorten the temp to cover only the output.
+                    CodePosition from = inputOf(*ins);
+                    if (temp->policy() == LDefinition::PRESET) {
+                        AnyRegister reg = temp->output()->toRegister();
+                        for (LInstruction::InputIterator alloc(**ins); alloc.more(); alloc.next()) {
+                            if (alloc->isUse()) {
+                                LUse *use = alloc->toUse();
+                                if (use->isFixedRegister()) {
+                                    if (GetFixedRegister(vregs[use].def(), use) == reg)
+                                        from = outputOf(*ins);
+                                }
+                            }
+                        }
+                    }
+
                     CodePosition to =
                         ins->isCall() ? outputOf(*ins) : outputOf(*ins).next();
-                    if (!vregs[temp].getInterval(0)->addRangeAtHead(inputOf(*ins), to))
+                    if (!vregs[temp].getInterval(0)->addRangeAtHead(from, to))
                         return false;
                 }
             }
 
             DebugOnly<bool> hasUseRegister = false;
             DebugOnly<bool> hasUseRegisterAtStart = false;
 
             for (LInstruction::InputIterator alloc(**ins); alloc.more(); alloc.next()) {
@@ -679,17 +698,16 @@ LiveRangeAllocator<VREG>::buildLivenessI
 
                     // Don't treat RECOVERED_INPUT uses as keeping the vreg alive.
                     if (use->policy() == LUse::RECOVERED_INPUT)
                         continue;
 
                     CodePosition to;
                     if (forLSRA) {
                         if (use->isFixedRegister()) {
-                            JS_ASSERT(!use->usedAtStart());
                             AnyRegister reg = GetFixedRegister(vregs[use].def(), use);
                             if (!addFixedRangeAtHead(reg, inputOf(*ins), outputOf(*ins)))
                                 return false;
                             to = inputOf(*ins);
 
                             // Fixed intervals are not added to safepoints, so do it
                             // here.
                             LSafepoint *safepoint = ins->safepoint();
--- a/js/src/jit/shared/Lowering-shared-inl.h
+++ b/js/src/jit/shared/Lowering-shared-inl.h
@@ -337,16 +337,22 @@ LIRGeneratorShared::useKeepaliveOrConsta
 
 LUse
 LIRGeneratorShared::useFixed(MDefinition *mir, Register reg)
 {
     return use(mir, LUse(reg));
 }
 
 LUse
+LIRGeneratorShared::useFixedAtStart(MDefinition *mir, Register reg)
+{
+    return use(mir, LUse(reg, true));
+}
+
+LUse
 LIRGeneratorShared::useFixed(MDefinition *mir, FloatRegister reg)
 {
     return use(mir, LUse(reg));
 }
 
 LUse
 LIRGeneratorShared::useFixed(MDefinition *mir, AnyRegister reg)
 {
--- a/js/src/jit/shared/Lowering-shared.h
+++ b/js/src/jit/shared/Lowering-shared.h
@@ -67,16 +67,17 @@ class LIRGeneratorShared : public MInstr
     inline LUse use(MDefinition *mir, LUse policy);
     inline LUse use(MDefinition *mir);
     inline LUse useAtStart(MDefinition *mir);
     inline LUse useRegister(MDefinition *mir);
     inline LUse useRegisterAtStart(MDefinition *mir);
     inline LUse useFixed(MDefinition *mir, Register reg);
     inline LUse useFixed(MDefinition *mir, FloatRegister reg);
     inline LUse useFixed(MDefinition *mir, AnyRegister reg);
+    inline LUse useFixedAtStart(MDefinition *mir, Register reg);
     inline LAllocation useOrConstant(MDefinition *mir);
     // "Any" is architecture dependent, and will include registers and stack slots on X86,
     // and only registers on ARM.
     inline LAllocation useAny(MDefinition *mir);
     inline LAllocation useAnyOrConstant(MDefinition *mir);
     // "Storable" is architecture dependend, and will include registers and constants on X86
     // and only registers on ARM.
     // this is a generic "things we can expect to write into memory in 1 instruction"
--- a/js/src/jit/shared/Lowering-x86-shared.cpp
+++ b/js/src/jit/shared/Lowering-x86-shared.cpp
@@ -219,19 +219,19 @@ bool
 LIRGeneratorX86Shared::visitAsmJSUDiv(MAsmJSUDiv *div)
 {
     return lowerUDiv(div);
 }
 
 bool
 LIRGeneratorX86Shared::lowerUMod(MInstruction *mod)
 {
-    LUDivOrMod *lir = new LUDivOrMod(useFixed(mod->getOperand(0), eax),
+    LUDivOrMod *lir = new LUDivOrMod(useFixedAtStart(mod->getOperand(0), eax),
                                      useRegister(mod->getOperand(1)),
-                                     LDefinition::BogusTemp());
+                                     tempFixed(eax));
     return defineFixed(lir, mod, LAllocation(AnyRegister(edx)));
 }
 
 bool
 LIRGeneratorX86Shared::visitAsmJSUMod(MAsmJSUMod *mod)
 {
     return lowerUMod(mod);
 }