mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1137573 - OdinMonkey: Alignment Mask Analysis r=luke
This commit is contained in:
parent
74b74f6f58
commit
ebb2d05ec1
89
js/src/jit/AlignmentMaskAnalysis.cpp
Normal file
89
js/src/jit/AlignmentMaskAnalysis.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/* -*- 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/AlignmentMaskAnalysis.h"
|
||||
#include "jit/MIR.h"
|
||||
#include "jit/MIRGraph.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace jit;
|
||||
|
||||
static bool
|
||||
IsAlignmentMask(uint32_t m)
|
||||
{
|
||||
// Test whether m is just leading ones and trailing zeros.
|
||||
return (-m & ~m) == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
AnalyzeAsmHeapAddress(MDefinition *ptr, MIRGraph &graph)
|
||||
{
|
||||
// Fold (a+i)&m to (a&m)+i, since the users of the BitAnd include heap
|
||||
// accesses. This will expose the redundancy for GVN when expressions
|
||||
// like this:
|
||||
// a&m
|
||||
// (a+1)&m,
|
||||
// (a+2)&m,
|
||||
// are transformed into this:
|
||||
// a&m
|
||||
// (a&m)+1
|
||||
// (a&m)+2
|
||||
// and it will allow the constants to be folded by the
|
||||
// EffectiveAddressAnalysis pass.
|
||||
|
||||
if (!ptr->isBitAnd())
|
||||
return;
|
||||
|
||||
MDefinition *lhs = ptr->toBitAnd()->getOperand(0);
|
||||
MDefinition *rhs = ptr->toBitAnd()->getOperand(1);
|
||||
int lhsIndex = 0;
|
||||
if (lhs->isConstantValue()) {
|
||||
mozilla::Swap(lhs, rhs);
|
||||
lhsIndex = 1;
|
||||
}
|
||||
if (!lhs->isAdd() || !lhs->hasOneUse() || !rhs->isConstantValue())
|
||||
return;
|
||||
|
||||
MDefinition *op0 = lhs->toAdd()->getOperand(0);
|
||||
MDefinition *op1 = lhs->toAdd()->getOperand(1);
|
||||
int op0Index = 0;
|
||||
if (op0->isConstantValue()) {
|
||||
mozilla::Swap(op0, op1);
|
||||
op0Index = 1;
|
||||
}
|
||||
if (!op1->isConstantValue())
|
||||
return;
|
||||
|
||||
uint32_t i = op1->constantValue().toInt32();
|
||||
uint32_t m = rhs->constantValue().toInt32();
|
||||
if (!IsAlignmentMask(m) || ((i & m) != i))
|
||||
return;
|
||||
|
||||
ptr->replaceAllUsesWith(lhs);
|
||||
ptr->toBitAnd()->replaceOperand(lhsIndex, op0);
|
||||
lhs->toAdd()->replaceOperand(op0Index, ptr);
|
||||
|
||||
MInstructionIterator iter = ptr->block()->begin(ptr->toBitAnd());
|
||||
++iter;
|
||||
lhs->block()->moveBefore(*iter, lhs->toAdd());
|
||||
}
|
||||
|
||||
bool
|
||||
AlignmentMaskAnalysis::analyze()
|
||||
{
|
||||
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {
|
||||
for (MInstructionIterator i = block->begin(); i != block->end(); i++) {
|
||||
// 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.
|
||||
if (i->isAsmJSLoadHeap())
|
||||
AnalyzeAsmHeapAddress(i->toAsmJSLoadHeap()->ptr(), graph_);
|
||||
else if (i->isAsmJSStoreHeap())
|
||||
AnalyzeAsmHeapAddress(i->toAsmJSStoreHeap()->ptr(), graph_);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
30
js/src/jit/AlignmentMaskAnalysis.h
Normal file
30
js/src/jit/AlignmentMaskAnalysis.h
Normal file
@ -0,0 +1,30 @@
|
||||
/* -*- 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_AlignmentMaskAnalysis_h
|
||||
#define jit_AlignmentMaskAnalysis_h
|
||||
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
class MIRGraph;
|
||||
|
||||
class AlignmentMaskAnalysis
|
||||
{
|
||||
MIRGraph &graph_;
|
||||
|
||||
public:
|
||||
explicit AlignmentMaskAnalysis(MIRGraph &graph)
|
||||
: graph_(graph)
|
||||
{}
|
||||
|
||||
bool analyze();
|
||||
};
|
||||
|
||||
} /* namespace jit */
|
||||
} /* namespace js */
|
||||
|
||||
#endif /* jit_AlignmentMaskAnalysis_h */
|
@ -89,13 +89,6 @@ AnalyzeLsh(TempAllocator &alloc, MLsh *lsh)
|
||||
last->block()->insertAfter(last, eaddr);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsAlignmentMask(uint32_t m)
|
||||
{
|
||||
// Test whether m is just leading ones and trailing zeros.
|
||||
return (-m & ~m) == 0;
|
||||
}
|
||||
|
||||
template<typename MAsmJSHeapAccessType>
|
||||
static void
|
||||
AnalyzeAsmHeapAccess(MAsmJSHeapAccessType *ins, MIRGraph &graph)
|
||||
@ -116,6 +109,8 @@ AnalyzeAsmHeapAccess(MAsmJSHeapAccessType *ins, MIRGraph &graph)
|
||||
}
|
||||
} else if (ptr->isAdd()) {
|
||||
// Look for heap[a+i] where i is a constant offset, and fold the offset.
|
||||
// Alignment masks have already been moved out of the way by the
|
||||
// Alignment Mask Analysis pass.
|
||||
MDefinition *op0 = ptr->toAdd()->getOperand(0);
|
||||
MDefinition *op1 = ptr->toAdd()->getOperand(1);
|
||||
if (op0->isConstantValue())
|
||||
@ -125,29 +120,6 @@ AnalyzeAsmHeapAccess(MAsmJSHeapAccessType *ins, MIRGraph &graph)
|
||||
if (ins->tryAddDisplacement(imm))
|
||||
ins->replacePtr(op0);
|
||||
}
|
||||
} else if (ptr->isBitAnd() && ptr->hasOneUse()) {
|
||||
// Transform heap[(a+i)&m] to heap[(a&m)+i] so that we can fold i into
|
||||
// the access. Since we currently just mutate the BitAnd in place, this
|
||||
// requires that we are its only user.
|
||||
MDefinition *lhs = ptr->toBitAnd()->getOperand(0);
|
||||
MDefinition *rhs = ptr->toBitAnd()->getOperand(1);
|
||||
int lhsIndex = 0;
|
||||
if (lhs->isConstantValue()) {
|
||||
mozilla::Swap(lhs, rhs);
|
||||
lhsIndex = 1;
|
||||
}
|
||||
if (lhs->isAdd() && rhs->isConstantValue()) {
|
||||
MDefinition *op0 = lhs->toAdd()->getOperand(0);
|
||||
MDefinition *op1 = lhs->toAdd()->getOperand(1);
|
||||
if (op0->isConstantValue())
|
||||
mozilla::Swap(op0, op1);
|
||||
if (op1->isConstantValue()) {
|
||||
uint32_t i = op1->constantValue().toInt32();
|
||||
uint32_t m = rhs->constantValue().toInt32();
|
||||
if (IsAlignmentMask(m) && ((i & m) == i) && ins->tryAddDisplacement(i))
|
||||
ptr->toBitAnd()->replaceOperand(lhsIndex, op0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "gc/Marking.h"
|
||||
#include "jit/AliasAnalysis.h"
|
||||
#include "jit/AlignmentMaskAnalysis.h"
|
||||
#include "jit/BacktrackingAllocator.h"
|
||||
#include "jit/BaselineFrame.h"
|
||||
#include "jit/BaselineInspector.h"
|
||||
@ -1248,6 +1249,18 @@ OptimizeMIR(MIRGenerator *mir)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mir->optimizationInfo().amaEnabled()) {
|
||||
AutoTraceLog log(logger, TraceLogger_AlignmentMaskAnalysis);
|
||||
AlignmentMaskAnalysis ama(graph);
|
||||
if (!ama.analyze())
|
||||
return false;
|
||||
IonSpewPass("Alignment Mask Analysis");
|
||||
AssertExtendedGraphCoherency(graph);
|
||||
|
||||
if (mir->shouldCancel("Alignment Mask Analysis"))
|
||||
return false;
|
||||
}
|
||||
|
||||
ValueNumberer gvn(mir, graph);
|
||||
if (!gvn.init())
|
||||
return false;
|
||||
|
@ -55,6 +55,7 @@ OptimizationInfo::initAsmjsOptimizationInfo()
|
||||
// Take normal option values for not specified values.
|
||||
initNormalOptimizationInfo();
|
||||
|
||||
ama_ = true;
|
||||
level_ = Optimization_AsmJS;
|
||||
edgeCaseAnalysis_ = false;
|
||||
eliminateRedundantChecks_ = false;
|
||||
|
@ -49,6 +49,9 @@ class OptimizationInfo
|
||||
// Toggles whether Effective Address Analysis is performed.
|
||||
bool eaa_;
|
||||
|
||||
// Toggles whether Alignment Mask Analysis is performed.
|
||||
bool ama_;
|
||||
|
||||
// Toggles whether Edge Case Analysis is used.
|
||||
bool edgeCaseAnalysis_;
|
||||
|
||||
@ -167,6 +170,10 @@ class OptimizationInfo
|
||||
return eaa_ && !js_JitOptions.disableEaa;
|
||||
}
|
||||
|
||||
bool amaEnabled() const {
|
||||
return ama_ && !js_JitOptions.disableAma;
|
||||
}
|
||||
|
||||
bool edgeCaseAnalysisEnabled() const {
|
||||
return edgeCaseAnalysis_ && !js_JitOptions.disableEdgeCaseAnalysis;
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ JitOptions::JitOptions()
|
||||
// Toggles whether Effective Address Analysis is globally disabled.
|
||||
SET_DEFAULT(disableEaa, false);
|
||||
|
||||
// Toggles whether Alignment Mask Analysis is globally disabled.
|
||||
SET_DEFAULT(disableAma, false);
|
||||
|
||||
// Whether functions are compiled immediately.
|
||||
SET_DEFAULT(eagerCompilation, false);
|
||||
|
||||
|
@ -55,6 +55,7 @@ struct JitOptions
|
||||
bool disableSink;
|
||||
bool disableLoopUnrolling;
|
||||
bool disableEaa;
|
||||
bool disableAma;
|
||||
bool eagerCompilation;
|
||||
mozilla::Maybe<uint32_t> forcedDefaultIonWarmUpThreshold;
|
||||
mozilla::Maybe<IonRegisterAllocator> forcedRegisterAllocator;
|
||||
|
@ -140,6 +140,7 @@ UNIFIED_SOURCES += [
|
||||
'irregexp/RegExpParser.cpp',
|
||||
'irregexp/RegExpStack.cpp',
|
||||
'jit/AliasAnalysis.cpp',
|
||||
'jit/AlignmentMaskAnalysis.cpp',
|
||||
'jit/BacktrackingAllocator.cpp',
|
||||
'jit/Bailouts.cpp',
|
||||
'jit/BaselineBailouts.cpp',
|
||||
|
@ -683,6 +683,7 @@ TraceLoggerThreadState::init()
|
||||
enabledTextIds[TraceLogger_RangeAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_LoopUnrolling] = true;
|
||||
enabledTextIds[TraceLogger_EffectiveAddressAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_AlignmentMaskAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_EliminateDeadCode] = true;
|
||||
enabledTextIds[TraceLogger_EdgeCaseAnalysis] = true;
|
||||
enabledTextIds[TraceLogger_EliminateRedundantChecks] = true;
|
||||
|
@ -50,6 +50,7 @@
|
||||
_(RangeAnalysis) \
|
||||
_(LoopUnrolling) \
|
||||
_(EffectiveAddressAnalysis) \
|
||||
_(AlignmentMaskAnalysis) \
|
||||
_(EliminateDeadCode) \
|
||||
_(EdgeCaseAnalysis) \
|
||||
_(EliminateRedundantChecks) \
|
||||
|
Loading…
Reference in New Issue
Block a user