author | Sander Mathijs van Veen <sander@leaningtech.com> |
Tue, 11 Oct 2016 07:04:00 +0200 | |
changeset 317871 | 07358be0ec02a2aebfdb9fef9dfc41450a5b7e40 |
parent 317870 | 9de739c57c87fbfcb47f9c36523d750277c12c94 |
child 317872 | 44726da7a2869614b04e2193f17f6060bdbf4ceb |
push id | 33170 |
push user | cbook@mozilla.com |
push date | Fri, 14 Oct 2016 10:37:07 +0000 |
treeherder | autoland@0d101ebfd95c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | nbp |
bugs | 1295130 |
milestone | 52.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
|
new file mode 100644 --- /dev/null +++ b/js/src/jit/FoldLinearArithConstants.cpp @@ -0,0 +1,101 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jit/FoldLinearArithConstants.h" + +#include "jit/IonAnalysis.h" +#include "jit/MIR.h" +#include "jit/MIRGenerator.h" +#include "jit/MIRGraph.h" + +using namespace js; +using namespace jit; + +namespace js { +namespace jit { + +// Mark this node and its children as RecoveredOnBailout when they are not used. +// The marked nodes will be removed during DCE. Marking as RecoveredOnBailout is +// necessary because the Sink pass is ran before this pass. +static void +markNodesAsRecoveredOnBailout(MDefinition* def) +{ + if (def->hasLiveDefUses() || !DeadIfUnused(def) || !def->canRecoverOnBailout()) + return; + + JitSpew(JitSpew_FLAC, "mark as recovered on bailout: %s%u", def->opName(), def->id()); + def->setRecoveredOnBailoutUnchecked(); + + // Recursively mark nodes that do not have multiple uses. This loop is + // necessary because a node could be an unused right shift zero or an + // unused add, and both need to be marked as RecoveredOnBailout. + for (size_t i = 0; i < def->numOperands(); i++) + markNodesAsRecoveredOnBailout(def->getOperand(i)); +} + +// Fold AddIs with one variable and two or more constants into one AddI. +static void +AnalyzeAdd(TempAllocator& alloc, MAdd* add) +{ + if (add->specialization() != MIRType::Int32 || add->isRecoveredOnBailout()) + return; + + if (!add->hasUses()) + return; + + JitSpew(JitSpew_FLAC, "analyze add: %s%u", add->opName(), add->id()); + + SimpleLinearSum sum = ExtractLinearSum(add); + if (sum.constant == 0 || !sum.term) + return; + + // Do not replace an add where the outcome is the same add instruction. + int idx = add->getOperand(0)->isConstant() ? 0 : 1 ; + MOZ_ASSERT(add->getOperand(idx)->toConstant()->type() == MIRType::Int32); + if (sum.term == add->getOperand(1 - idx) || + sum.constant == add->getOperand(idx)->toConstant()->toInt32()) + { + return; + } + + MInstruction* rhs = MConstant::New(alloc, Int32Value(sum.constant)); + add->block()->insertBefore(add, rhs); + + MAdd* addNew = MAdd::NewAsmJS(alloc, sum.term, rhs, MIRType::Int32); + + add->replaceAllLiveUsesWith(addNew); + add->block()->insertBefore(add, addNew); + JitSpew(JitSpew_FLAC, "replaced with: %s%u", addNew->opName(), addNew->id()); + JitSpew(JitSpew_FLAC, "and constant: %s%u (%d)", rhs->opName(), rhs->id(), sum.constant); + + // Mark the stale nodes as RecoveredOnBailout since the Sink pass has + // been run before this pass. DCE will then remove the unused nodes. + markNodesAsRecoveredOnBailout(add); +} + +bool +FoldLinearArithConstants(MIRGenerator* mir, MIRGraph& graph) +{ + for (PostorderIterator block(graph.poBegin()); block != graph.poEnd(); block++) { + if (mir->shouldCancel("Fold Linear Arithmetic Constants (main loop)")) + return false; + + for (MInstructionIterator i = block->begin(); i != block->end(); i++) { + if (!graph.alloc().ensureBallast()) + return false; + + if (mir->shouldCancel("Fold Linear Arithmetic Constants (inner loop)")) + return false; + + if (i->isAdd()) + AnalyzeAdd(graph.alloc(), i->toAdd()); + } + } + return true; +} + +} /* namespace jit */ +} /* namespace js */
new file mode 100644 --- /dev/null +++ b/js/src/jit/FoldLinearArithConstants.h @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_FoldLinearArithConstants_h +#define jit_FoldLinearArithConstants_h + +#include "jit/MIR.h" +#include "jit/MIRGraph.h" + +namespace js { +namespace jit { + +MOZ_MUST_USE bool +FoldLinearArithConstants(MIRGenerator* mir, MIRGraph& graph); + +} /* namespace jit */ +} /* namespace js */ + +#endif /* jit_FoldLinearArithConstants_h */
--- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -21,16 +21,17 @@ #include "jit/BaselineFrame.h" #include "jit/BaselineInspector.h" #include "jit/BaselineJIT.h" #include "jit/CodeGenerator.h" #include "jit/EagerSimdUnbox.h" #include "jit/EdgeCaseAnalysis.h" #include "jit/EffectiveAddressAnalysis.h" #include "jit/FlowAliasAnalysis.h" +#include "jit/FoldLinearArithConstants.h" #include "jit/InstructionReordering.h" #include "jit/IonAnalysis.h" #include "jit/IonBuilder.h" #include "jit/IonOptimizationLevels.h" #include "jit/JitcodeMap.h" #include "jit/JitCommon.h" #include "jit/JitCompartment.h" #include "jit/JitSpewer.h" @@ -1786,16 +1787,27 @@ OptimizeMIR(MIRGenerator* mir) return false; gs.spewPass("Remove Unnecessary Bitops"); AssertExtendedGraphCoherency(graph); if (mir->shouldCancel("Remove Unnecessary Bitops")) return false; } + { + AutoTraceLog log(logger, TraceLogger_FoldLinearArithConstants); + if (!FoldLinearArithConstants(mir, graph)) + return false; + gs.spewPass("Fold Linear Arithmetic Constants"); + AssertBasicGraphCoherency(graph); + + if (mir->shouldCancel("Fold Linear Arithmetic Constants")) + return false; + } + if (mir->optimizationInfo().eaaEnabled()) { AutoTraceLog log(logger, TraceLogger_EffectiveAddressAnalysis); EffectiveAddressAnalysis eaa(mir, graph); if (!eaa.analyze()) return false; gs.spewPass("Effective Address Analysis"); AssertExtendedGraphCoherency(graph);
--- a/js/src/jit/JitSpewer.cpp +++ b/js/src/jit/JitSpewer.cpp @@ -410,16 +410,17 @@ jit::CheckLogging() " scripts Compiled scripts\n" " mir MIR information\n" " prune Prune unused branches\n" " escape Escape analysis\n" " alias Alias analysis\n" " alias-sum Alias analysis: shows summaries for every block\n" " gvn Global Value Numbering\n" " licm Loop invariant code motion\n" + " flac Fold linear arithmetic constants\n" " sincos Replace sin/cos by sincos\n" " sink Sink transformation\n" " regalloc Register allocation\n" " inline Inlining\n" " snapshots Snapshot information\n" " codegen Native code generation\n" " bailouts Bailouts\n" " caches Inline caches\n" @@ -466,16 +467,18 @@ jit::CheckLogging() if (ContainsFlag(env, "gvn")) EnableChannel(JitSpew_GVN); if (ContainsFlag(env, "range")) EnableChannel(JitSpew_Range); if (ContainsFlag(env, "unroll")) EnableChannel(JitSpew_Unrolling); if (ContainsFlag(env, "licm")) EnableChannel(JitSpew_LICM); + if (ContainsFlag(env, "flac")) + EnableChannel(JitSpew_FLAC); if (ContainsFlag(env, "sincos")) EnableChannel(JitSpew_Sincos); if (ContainsFlag(env, "sink")) EnableChannel(JitSpew_Sink); if (ContainsFlag(env, "regalloc")) EnableChannel(JitSpew_RegAlloc); if (ContainsFlag(env, "inline")) EnableChannel(JitSpew_Inlining);
--- a/js/src/jit/JitSpewer.h +++ b/js/src/jit/JitSpewer.h @@ -39,16 +39,18 @@ namespace jit { /* Information during sinking */ \ _(Sink) \ /* Information during Range analysis */ \ _(Range) \ /* Information during loop unrolling */ \ _(Unrolling) \ /* Information during LICM */ \ _(LICM) \ + /* Info about fold linear constants */ \ + _(FLAC) \ /* Information during regalloc */ \ _(RegAlloc) \ /* Information during inlining */ \ _(Inlining) \ /* Information during codegen */ \ _(Codegen) \ /* Debug info about safepoints */ \ _(Safepoints) \
--- a/js/src/moz.build +++ b/js/src/moz.build @@ -242,16 +242,17 @@ UNIFIED_SOURCES += [ 'jit/CodeGenerator.cpp', 'jit/CompileWrappers.cpp', 'jit/Disassembler.cpp', 'jit/EagerSimdUnbox.cpp', 'jit/EdgeCaseAnalysis.cpp', 'jit/EffectiveAddressAnalysis.cpp', 'jit/ExecutableAllocator.cpp', 'jit/FlowAliasAnalysis.cpp', + 'jit/FoldLinearArithConstants.cpp', 'jit/InstructionReordering.cpp', 'jit/Ion.cpp', 'jit/IonAnalysis.cpp', 'jit/IonBuilder.cpp', 'jit/IonCaches.cpp', 'jit/IonOptimizationLevels.cpp', 'jit/JitcodeMap.cpp', 'jit/JitFrames.cpp',
--- a/js/src/vm/TraceLogging.cpp +++ b/js/src/vm/TraceLogging.cpp @@ -696,20 +696,21 @@ TraceLoggerThreadState::init() " ParserCompileScript, ParserCompileLazy, ParserCompileModule,\n" " IrregexpCompile, IrregexpExecute, Scripts, Engine, WasmCompilation\n" "\n" " IonCompiler Output all information about compilation. It includes:\n" " IonCompilation, IonLinking, PruneUnusedBranches, FoldTests,\n" " SplitCriticalEdges, RenumberBlocks, ScalarReplacement, \n" " DominatorTree, PhiAnalysis, MakeLoopsContiguous, ApplyTypes, \n" " EagerSimdUnbox, AliasAnalysis, GVN, LICM, Sincos, RangeAnalysis, \n" - " LoopUnrolling, EffectiveAddressAnalysis, AlignmentMaskAnalysis, \n" - " EliminateDeadCode, ReorderInstructions, EdgeCaseAnalysis, \n" - " EliminateRedundantChecks, AddKeepAliveInstructions, GenerateLIR, \n" - " RegisterAllocation, GenerateCode, Scripts, IonBuilderRestartLoop\n" + " LoopUnrolling, FoldLinearArithConstants, EffectiveAddressAnalysis, \n" + " AlignmentMaskAnalysis, EliminateDeadCode, ReorderInstructions, \n" + " EdgeCaseAnalysis, EliminateRedundantChecks, \n" + " AddKeepAliveInstructions, GenerateLIR, RegisterAllocation, \n" + " GenerateCode, Scripts, IonBuilderRestartLoop\n" "\n" " VMSpecific Output the specific name of the VM call" "\n" "Specific log items:\n" ); for (uint32_t i = 1; i < TraceLogger_Last; i++) { TraceLoggerTextId id = TraceLoggerTextId(i); if (!TLTextIdIsTogglable(id)) @@ -768,16 +769,17 @@ TraceLoggerThreadState::init() enabledTextIds[TraceLogger_ApplyTypes] = true; enabledTextIds[TraceLogger_EagerSimdUnbox] = true; enabledTextIds[TraceLogger_AliasAnalysis] = true; enabledTextIds[TraceLogger_GVN] = true; enabledTextIds[TraceLogger_LICM] = true; enabledTextIds[TraceLogger_Sincos] = true; enabledTextIds[TraceLogger_RangeAnalysis] = true; enabledTextIds[TraceLogger_LoopUnrolling] = true; + enabledTextIds[TraceLogger_FoldLinearArithConstants] = true; enabledTextIds[TraceLogger_EffectiveAddressAnalysis] = true; enabledTextIds[TraceLogger_AlignmentMaskAnalysis] = true; enabledTextIds[TraceLogger_EliminateDeadCode] = true; enabledTextIds[TraceLogger_ReorderInstructions] = true; enabledTextIds[TraceLogger_EdgeCaseAnalysis] = true; enabledTextIds[TraceLogger_EliminateRedundantChecks] = true; enabledTextIds[TraceLogger_AddKeepAliveInstructions] = true; enabledTextIds[TraceLogger_GenerateLIR] = true;
--- a/js/src/vm/TraceLoggingTypes.h +++ b/js/src/vm/TraceLoggingTypes.h @@ -53,16 +53,17 @@ _(AliasAnalysis) \ _(GVN) \ _(LICM) \ _(Sincos) \ _(RangeAnalysis) \ _(LoopUnrolling) \ _(Sink) \ _(RemoveUnnecessaryBitops) \ + _(FoldLinearArithConstants) \ _(EffectiveAddressAnalysis) \ _(AlignmentMaskAnalysis) \ _(EliminateDeadCode) \ _(ReorderInstructions) \ _(EdgeCaseAnalysis) \ _(EliminateRedundantChecks) \ _(AddKeepAliveInstructions) \ _(GenerateLIR) \