author | Sander Mathijs van Veen <sander@leaningtech.com> |
Tue, 11 Oct 2016 07:06:00 +0200 | |
changeset 317872 | 44726da7a2869614b04e2193f17f6060bdbf4ceb |
parent 317871 | 07358be0ec02a2aebfdb9fef9dfc41450a5b7e40 |
child 317873 | 9f289545ab7d9f3a3b5b18452818df1e3e44f382 |
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
|
--- a/js/src/jit/EffectiveAddressAnalysis.cpp +++ b/js/src/jit/EffectiveAddressAnalysis.cpp @@ -1,15 +1,16 @@ /* -*- 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/EffectiveAddressAnalysis.h" +#include "jit/IonAnalysis.h" #include "jit/MIR.h" #include "jit/MIRGraph.h" using namespace js; using namespace jit; static void AnalyzeLsh(TempAllocator& alloc, MLsh* lsh) @@ -95,16 +96,86 @@ AnalyzeLsh(TempAllocator& alloc, MLsh* l if (base->isRecoveredOnBailout()) return; MEffectiveAddress* eaddr = MEffectiveAddress::New(alloc, base, index, scale, displacement); last->replaceAllUsesWith(eaddr); last->block()->insertAfter(last, eaddr); } +// Transform: +// +// [AddI] +// addl $9, %esi +// [LoadUnboxedScalar] +// movsd 0x0(%rbx,%rsi,8), %xmm4 +// +// into: +// +// [LoadUnboxedScalar] +// movsd 0x48(%rbx,%rsi,8), %xmm4 +// +// This is possible when the AddI is only used by the LoadUnboxedScalar opcode. +static void +AnalyzeLoadUnboxedScalar(TempAllocator& alloc, MLoadUnboxedScalar* load) +{ + if (load->isRecoveredOnBailout()) + return; + + if (!load->getOperand(1)->isAdd()) + return; + + JitSpew(JitSpew_EAA, "analyze: %s%u", load->opName(), load->id()); + + MAdd* add = load->getOperand(1)->toAdd(); + + if (add->specialization() != MIRType::Int32 || !add->hasUses() || + add->truncateKind() != MDefinition::TruncateKind::Truncate) + { + return; + } + + MDefinition* lhs = add->lhs(); + MDefinition* rhs = add->rhs(); + MDefinition* constant = nullptr; + MDefinition* node = nullptr; + + if (lhs->isConstant()) { + constant = lhs; + node = rhs; + } else if (rhs->isConstant()) { + constant = rhs; + node = lhs; + } else + return; + + MOZ_ASSERT(constant->type() == MIRType::Int32); + + size_t storageSize = Scalar::byteSize(load->storageType()); + int32_t c1 = load->offsetAdjustment(); + int32_t c2 = 0; + if (!SafeMul(constant->maybeConstantValue()->toInt32(), storageSize, &c2)) + return; + + int32_t offset = 0; + if (!SafeAdd(c1, c2, &offset)) + return; + + JitSpew(JitSpew_EAA, "set offset: %d + %d = %d on: %s%u", c1, c2, offset, + load->opName(), load->id()); + load->setOffsetAdjustment(offset); + load->replaceOperand(1, node); + + if (!add->hasLiveDefUses() && DeadIfUnused(add) && add->canRecoverOnBailout()) { + JitSpew(JitSpew_EAA, "mark as recovered on bailout: %s%u", + add->opName(), add->id()); + add->setRecoveredOnBailoutUnchecked(); + } +} + template<typename AsmJSMemoryAccess> bool EffectiveAddressAnalysis::tryAddDisplacement(AsmJSMemoryAccess* ins, int32_t o) { #ifdef WASM_HUGE_MEMORY // Compute the new offset. Check for overflow. uint32_t oldOffset = ins->offset(); uint32_t newOffset = oldOffset + o; @@ -189,16 +260,18 @@ EffectiveAddressAnalysis::analyze() return false; // Note that we don't check for MAsmJSCompareExchangeHeap // or MAsmJSAtomicBinopHeap, because the backend and the OOB // mechanism don't support non-zero offsets for them yet // (TODO bug 1254935). if (i->isLsh()) AnalyzeLsh(graph_.alloc(), i->toLsh()); + else if (i->isLoadUnboxedScalar()) + AnalyzeLoadUnboxedScalar(graph_.alloc(), i->toLoadUnboxedScalar()); else if (i->isAsmJSLoadHeap()) analyzeAsmJSHeapAccess(i->toAsmJSLoadHeap()); else if (i->isAsmJSStoreHeap()) analyzeAsmJSHeapAccess(i->toAsmJSStoreHeap()); } } return true; }
--- a/js/src/jit/JitSpewer.cpp +++ b/js/src/jit/JitSpewer.cpp @@ -411,16 +411,17 @@ jit::CheckLogging() " 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" + " eaa Effective address analysis\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" @@ -469,16 +470,18 @@ jit::CheckLogging() 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, "eaa")) + EnableChannel(JitSpew_EAA); 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 @@ -41,16 +41,18 @@ namespace jit { /* Information during Range analysis */ \ _(Range) \ /* Information during loop unrolling */ \ _(Unrolling) \ /* Information during LICM */ \ _(LICM) \ /* Info about fold linear constants */ \ _(FLAC) \ + /* Effective address analysis info */ \ + _(EAA) \ /* Information during regalloc */ \ _(RegAlloc) \ /* Information during inlining */ \ _(Inlining) \ /* Information during codegen */ \ _(Codegen) \ /* Debug info about safepoints */ \ _(Safepoints) \
--- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -9961,16 +9961,19 @@ class MLoadUnboxedScalar return requiresBarrier_; } bool canonicalizeDoubles() const { return canonicalizeDoubles_; } int32_t offsetAdjustment() const { return offsetAdjustment_; } + void setOffsetAdjustment(int32_t offsetAdjustment) { + offsetAdjustment_ = offsetAdjustment; + } AliasSet getAliasSet() const override { // When a barrier is needed make the instruction effectful by // giving it a "store" effect. if (requiresBarrier_) return AliasSet::Store(AliasSet::UnboxedElement); return AliasSet::Load(AliasSet::UnboxedElement); }