Bug 1050160 - DeadIfUnused should not check for resume points. r=nbp
authorDavid (v45h) Moreira <vash@v45h.org>
Thu, 06 Nov 2014 11:34:27 +0100
changeset 214382 006c4625df019c61b63b49a24a7b2fad22b1456e
parent 214381 a6540a77d6f72004c2a3262b70c6f6a03f0d3929
child 214383 1c969fba2f6487a8ea3769091ab68ff6db82689a
push id27780
push userkwierso@gmail.com
push dateFri, 07 Nov 2014 02:25:05 +0000
treeherdermozilla-central@e6d47abb6a7b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1050160
milestone36.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 1050160 - DeadIfUnused should not check for resume points. r=nbp
js/src/jit/IonAnalysis.cpp
js/src/jit/IonAnalysis.h
js/src/jit/ValueNumbering.cpp
--- a/js/src/jit/IonAnalysis.cpp
+++ b/js/src/jit/IonAnalysis.cpp
@@ -530,34 +530,48 @@ jit::EliminateDeadResumePointOperands(MI
                 use->replaceProducer(constant);
             }
         }
     }
 
     return true;
 }
 
+// Test whether |def| would be needed if it had no uses.
+bool
+js::jit::DeadIfUnused(const MDefinition *def)
+{
+    return !def->isEffectful() && !def->isGuard() && !def->isControlInstruction() &&
+           (!def->isInstruction() || !def->toInstruction()->resumePoint());
+}
+
+// Test whether |def| may be safely discarded, due to being dead or due to being
+// located in a basic block which has itself been marked for discarding.
+bool
+js::jit::IsDiscardable(const MDefinition *def)
+{
+    return !def->hasUses() && (DeadIfUnused(def) || def->block()->isMarked());
+}
+
 // Instructions are useless if they are unused and have no side effects.
 // This pass eliminates useless instructions.
 // The graph itself is unchanged.
 bool
 jit::EliminateDeadCode(MIRGenerator *mir, MIRGraph &graph)
 {
     // Traverse in postorder so that we hit uses before definitions.
     // Traverse instruction list backwards for the same reason.
     for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
         if (mir->shouldCancel("Eliminate Dead Code (main loop)"))
             return false;
 
         // Remove unused instructions.
         for (MInstructionReverseIterator iter = block->rbegin(); iter != block->rend(); ) {
             MInstruction *inst = *iter++;
-            if (!inst->isEffectful() && !inst->resumePoint() &&
-                !inst->hasUses() && !inst->isGuard() &&
-                !inst->isControlInstruction())
+            if (js::jit::IsDiscardable(inst))
             {
                 block->discard(inst);
             } else if (!inst->isRecoveredOnBailout() && !inst->isGuard() &&
                        !inst->hasLiveDefUses() && inst->canRecoverOnBailout())
             {
                 inst->setRecoveredOnBailout();
             }
         }
--- a/js/src/jit/IonAnalysis.h
+++ b/js/src/jit/IonAnalysis.h
@@ -163,12 +163,18 @@ ConvertLinearInequality(TempAllocator &a
 bool
 AnalyzeNewScriptDefiniteProperties(JSContext *cx, JSFunction *fun,
                                    types::TypeObject *type, HandleNativeObject baseobj,
                                    Vector<types::TypeNewScript::Initializer> *initializerList);
 
 bool
 AnalyzeArgumentsUsage(JSContext *cx, JSScript *script);
 
+bool
+DeadIfUnused(const MDefinition *def);
+
+bool
+IsDiscardable(const MDefinition *def);
+
 } // namespace jit
 } // namespace js
 
 #endif /* jit_IonAnalysis_h */
--- a/js/src/jit/ValueNumbering.cpp
+++ b/js/src/jit/ValueNumbering.cpp
@@ -132,32 +132,16 @@ ValueNumberer::VisibleValues::clear()
 bool
 ValueNumberer::VisibleValues::has(const MDefinition *def) const
 {
     Ptr p = set_.lookup(def);
     return p && *p == def;
 }
 #endif
 
-// Test whether |def| would be needed if it had no uses.
-static bool
-DeadIfUnused(const MDefinition *def)
-{
-    return !def->isEffectful() && !def->isGuard() && !def->isControlInstruction() &&
-           (!def->isInstruction() || !def->toInstruction()->resumePoint());
-}
-
-// Test whether |def| may be safely discarded, due to being dead or due to being
-// located in a basic block which has itself been marked for discarding.
-static bool
-IsDiscardable(const MDefinition *def)
-{
-    return !def->hasUses() && (DeadIfUnused(def) || def->block()->isMarked());
-}
-
 // Call MDefinition::justReplaceAllUsesWith, and add some GVN-specific asserts.
 static void
 ReplaceAllUsesWith(MDefinition *from, MDefinition *to)
 {
     MOZ_ASSERT(from != to, "GVN shouldn't try to replace a value with itself");
     MOZ_ASSERT(from->type() == to->type(), "Def replacement has different type");
     MOZ_ASSERT(!to->isDiscarded(), "GVN replaces an instruction by a removed instruction");