зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1113338: Generalize AsmJS{Load,Store}Heap to handle partial loads; r=luke
--HG-- extra : rebase_source : 14f1292bcaef32933e4a13136165973657cabeec
This commit is contained in:
Родитель
de9ea0eeeb
Коммит
26252ed8ba
|
@ -2765,9 +2765,23 @@ class FunctionCompiler
|
|||
return nullptr;
|
||||
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
Label *outOfBoundsLabel = Scalar::isSimdType(accessType) ? &m().onOutOfBoundsLabel() : nullptr;
|
||||
MOZ_ASSERT(!Scalar::isSimdType(accessType), "SIMD loads should use loadSimdHeap");
|
||||
MAsmJSLoadHeap *load = MAsmJSLoadHeap::New(alloc(), accessType, ptr, needsBoundsCheck);
|
||||
curBlock_->add(load);
|
||||
return load;
|
||||
}
|
||||
|
||||
MDefinition *loadSimdHeap(Scalar::Type accessType, MDefinition *ptr, NeedsBoundsCheck chk,
|
||||
unsigned numElems)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return nullptr;
|
||||
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
MOZ_ASSERT(Scalar::isSimdType(accessType), "loadSimdHeap can only load from a SIMD view");
|
||||
Label *outOfBoundsLabel = &m().onOutOfBoundsLabel();
|
||||
MAsmJSLoadHeap *load = MAsmJSLoadHeap::New(alloc(), accessType, ptr, needsBoundsCheck,
|
||||
outOfBoundsLabel);
|
||||
outOfBoundsLabel, numElems);
|
||||
curBlock_->add(load);
|
||||
return load;
|
||||
}
|
||||
|
@ -2778,9 +2792,22 @@ class FunctionCompiler
|
|||
return;
|
||||
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
Label *outOfBoundsLabel = Scalar::isSimdType(accessType) ? &m().onOutOfBoundsLabel() : nullptr;
|
||||
MOZ_ASSERT(!Scalar::isSimdType(accessType), "SIMD stores should use loadSimdHeap");
|
||||
MAsmJSStoreHeap *store = MAsmJSStoreHeap::New(alloc(), accessType, ptr, v, needsBoundsCheck);
|
||||
curBlock_->add(store);
|
||||
}
|
||||
|
||||
void storeSimdHeap(Scalar::Type accessType, MDefinition *ptr, MDefinition *v,
|
||||
NeedsBoundsCheck chk, unsigned numElems)
|
||||
{
|
||||
if (inDeadCode())
|
||||
return;
|
||||
|
||||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
MOZ_ASSERT(Scalar::isSimdType(accessType), "storeSimdHeap can only load from a SIMD view");
|
||||
Label *outOfBoundsLabel = &m().onOutOfBoundsLabel();
|
||||
MAsmJSStoreHeap *store = MAsmJSStoreHeap::New(alloc(), accessType, ptr, v, needsBoundsCheck,
|
||||
outOfBoundsLabel);
|
||||
outOfBoundsLabel, numElems);
|
||||
curBlock_->add(store);
|
||||
}
|
||||
|
||||
|
@ -2800,6 +2827,7 @@ class FunctionCompiler
|
|||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
MAsmJSLoadHeap *load = MAsmJSLoadHeap::New(alloc(), accessType, ptr, needsBoundsCheck,
|
||||
/* outOfBoundsLabel = */ nullptr,
|
||||
/* numElems */ 0,
|
||||
MembarBeforeLoad, MembarAfterLoad);
|
||||
curBlock_->add(load);
|
||||
return load;
|
||||
|
@ -2813,6 +2841,7 @@ class FunctionCompiler
|
|||
bool needsBoundsCheck = chk == NEEDS_BOUNDS_CHECK && !m().usesSignalHandlersForOOB();
|
||||
MAsmJSStoreHeap *store = MAsmJSStoreHeap::New(alloc(), accessType, ptr, v, needsBoundsCheck,
|
||||
/* outOfBoundsLabel = */ nullptr,
|
||||
/* numElems = */ 0,
|
||||
MembarBeforeStore, MembarAfterStore);
|
||||
curBlock_->add(store);
|
||||
}
|
||||
|
@ -5591,7 +5620,7 @@ CheckSimdShuffle(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDe
|
|||
|
||||
static bool
|
||||
CheckSimdLoadStoreArgs(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType,
|
||||
Scalar::Type *viewType, MDefinition **index,
|
||||
unsigned numElems, Scalar::Type *viewType, MDefinition **index,
|
||||
NeedsBoundsCheck *needsBoundsCheck)
|
||||
{
|
||||
ParseNode *view = CallArgList(call);
|
||||
|
@ -5644,7 +5673,8 @@ CheckSimdLoadStoreArgs(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opTyp
|
|||
}
|
||||
|
||||
static bool
|
||||
CheckSimdLoad(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefinition **def, Type *type)
|
||||
CheckSimdLoad(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType,
|
||||
unsigned numElems, MDefinition **def, Type *type)
|
||||
{
|
||||
unsigned numArgs = CallArgListLength(call);
|
||||
if (numArgs != 2)
|
||||
|
@ -5653,16 +5683,17 @@ CheckSimdLoad(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefin
|
|||
Scalar::Type viewType;
|
||||
MDefinition *index;
|
||||
NeedsBoundsCheck needsBoundsCheck;
|
||||
if (!CheckSimdLoadStoreArgs(f, call, opType, &viewType, &index, &needsBoundsCheck))
|
||||
if (!CheckSimdLoadStoreArgs(f, call, opType, numElems, &viewType, &index, &needsBoundsCheck))
|
||||
return false;
|
||||
|
||||
*def = f.loadHeap(viewType, index, needsBoundsCheck);
|
||||
*def = f.loadSimdHeap(viewType, index, needsBoundsCheck, numElems);
|
||||
*type = opType;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckSimdStore(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefinition **def, Type *type)
|
||||
CheckSimdStore(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType,
|
||||
unsigned numElems, MDefinition **def, Type *type)
|
||||
{
|
||||
unsigned numArgs = CallArgListLength(call);
|
||||
if (numArgs != 3)
|
||||
|
@ -5671,7 +5702,7 @@ CheckSimdStore(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefi
|
|||
Scalar::Type viewType;
|
||||
MDefinition *index;
|
||||
NeedsBoundsCheck needsBoundsCheck;
|
||||
if (!CheckSimdLoadStoreArgs(f, call, opType, &viewType, &index, &needsBoundsCheck))
|
||||
if (!CheckSimdLoadStoreArgs(f, call, opType, numElems, &viewType, &index, &needsBoundsCheck))
|
||||
return false;
|
||||
|
||||
Type retType = opType;
|
||||
|
@ -5683,7 +5714,7 @@ CheckSimdStore(FunctionCompiler &f, ParseNode *call, AsmJSSimdType opType, MDefi
|
|||
if (!(vecType <= retType))
|
||||
return f.failf(vecExpr, "%s is not a subtype of %s", vecType.toChars(), retType.toChars());
|
||||
|
||||
f.storeHeap(viewType, index, vec, needsBoundsCheck);
|
||||
f.storeSimdHeap(viewType, index, vec, needsBoundsCheck, numElems);
|
||||
*def = vec;
|
||||
*type = vecType;
|
||||
return true;
|
||||
|
@ -5791,9 +5822,9 @@ CheckSimdOperationCall(FunctionCompiler &f, ParseNode *call, const ModuleCompile
|
|||
return CheckSimdShuffle(f, call, opType, def, type);
|
||||
|
||||
case AsmJSSimdOperation_load:
|
||||
return CheckSimdLoad(f, call, opType, def, type);
|
||||
return CheckSimdLoad(f, call, opType, 4, def, type);
|
||||
case AsmJSSimdOperation_store:
|
||||
return CheckSimdStore(f, call, opType, def, type);
|
||||
return CheckSimdStore(f, call, opType, 4, def, type);
|
||||
|
||||
case AsmJSSimdOperation_bitselect:
|
||||
return CheckSimdSelect(f, call, opType, /*isElementWise */ false, def, type);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/HashFunctions.h"
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "jstypes.h"
|
||||
|
||||
#include "js/Value.h"
|
||||
|
@ -552,6 +553,29 @@ SimdTypeToLength(MIRType type)
|
|||
return 1 << ((type >> VECTOR_SCALE_SHIFT) & VECTOR_SCALE_MASK);
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
ScalarTypeToLength(Scalar::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case Scalar::Int8:
|
||||
case Scalar::Uint8:
|
||||
case Scalar::Int16:
|
||||
case Scalar::Uint16:
|
||||
case Scalar::Int32:
|
||||
case Scalar::Uint32:
|
||||
case Scalar::Float32:
|
||||
case Scalar::Float64:
|
||||
case Scalar::Uint8Clamped:
|
||||
return 1;
|
||||
case Scalar::Float32x4:
|
||||
case Scalar::Int32x4:
|
||||
return 4;
|
||||
case Scalar::MaxTypedArrayViewType:
|
||||
break;
|
||||
}
|
||||
MOZ_CRASH("unexpected SIMD kind");
|
||||
}
|
||||
|
||||
static inline MIRType
|
||||
SimdTypeToScalarType(MIRType type)
|
||||
{
|
||||
|
|
|
@ -12150,16 +12150,22 @@ class MAsmJSHeapAccess
|
|||
Scalar::Type accessType_;
|
||||
bool needsBoundsCheck_;
|
||||
Label *outOfBoundsLabel_;
|
||||
unsigned numSimdElems_;
|
||||
|
||||
public:
|
||||
MAsmJSHeapAccess(Scalar::Type accessType, bool needsBoundsCheck, Label *outOfBoundsLabel = nullptr)
|
||||
: accessType_(accessType), needsBoundsCheck_(needsBoundsCheck), outOfBoundsLabel_(outOfBoundsLabel)
|
||||
{}
|
||||
MAsmJSHeapAccess(Scalar::Type accessType, bool needsBoundsCheck,
|
||||
Label *outOfBoundsLabel = nullptr, unsigned numSimdElems = 0)
|
||||
: accessType_(accessType), needsBoundsCheck_(needsBoundsCheck),
|
||||
outOfBoundsLabel_(outOfBoundsLabel), numSimdElems_(numSimdElems)
|
||||
{
|
||||
MOZ_ASSERT(numSimdElems <= ScalarTypeToLength(accessType));
|
||||
}
|
||||
|
||||
Scalar::Type accessType() const { return accessType_; }
|
||||
bool needsBoundsCheck() const { return needsBoundsCheck_; }
|
||||
void removeBoundsCheck() { needsBoundsCheck_ = false; }
|
||||
Label *outOfBoundsLabel() const { return outOfBoundsLabel_; }
|
||||
unsigned numSimdElems() const { return numSimdElems_; }
|
||||
};
|
||||
|
||||
class MAsmJSLoadHeap
|
||||
|
@ -12171,9 +12177,10 @@ class MAsmJSLoadHeap
|
|||
MemoryBarrierBits barrierAfter_;
|
||||
|
||||
MAsmJSLoadHeap(Scalar::Type accessType, MDefinition *ptr, bool needsBoundsCheck,
|
||||
Label *outOfBoundsLabel, MemoryBarrierBits before, MemoryBarrierBits after)
|
||||
Label *outOfBoundsLabel, unsigned numSimdElems,
|
||||
MemoryBarrierBits before, MemoryBarrierBits after)
|
||||
: MUnaryInstruction(ptr),
|
||||
MAsmJSHeapAccess(accessType, needsBoundsCheck, outOfBoundsLabel),
|
||||
MAsmJSHeapAccess(accessType, needsBoundsCheck, outOfBoundsLabel, numSimdElems),
|
||||
barrierBefore_(before),
|
||||
barrierAfter_(after)
|
||||
{
|
||||
|
@ -12205,7 +12212,7 @@ class MAsmJSLoadHeap
|
|||
break;
|
||||
case Scalar::Uint8Clamped:
|
||||
case Scalar::MaxTypedArrayViewType:
|
||||
MOZ_CRASH("unexpected uint8clamped load heap in asm.js");
|
||||
MOZ_CRASH("unexpected load heap in asm.js");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12215,11 +12222,12 @@ class MAsmJSLoadHeap
|
|||
static MAsmJSLoadHeap *New(TempAllocator &alloc, Scalar::Type accessType,
|
||||
MDefinition *ptr, bool needsBoundsCheck,
|
||||
Label *outOfBoundsLabel = nullptr,
|
||||
unsigned numSimdElems = 0,
|
||||
MemoryBarrierBits barrierBefore = MembarNobits,
|
||||
MemoryBarrierBits barrierAfter = MembarNobits)
|
||||
{
|
||||
return new(alloc) MAsmJSLoadHeap(accessType, ptr, needsBoundsCheck, outOfBoundsLabel,
|
||||
barrierBefore, barrierAfter);
|
||||
numSimdElems, barrierBefore, barrierAfter);
|
||||
}
|
||||
|
||||
MDefinition *ptr() const { return getOperand(0); }
|
||||
|
@ -12242,9 +12250,10 @@ class MAsmJSStoreHeap
|
|||
MemoryBarrierBits barrierAfter_;
|
||||
|
||||
MAsmJSStoreHeap(Scalar::Type accessType, MDefinition *ptr, MDefinition *v, bool needsBoundsCheck,
|
||||
Label *outOfBoundsLabel, MemoryBarrierBits before, MemoryBarrierBits after)
|
||||
Label *outOfBoundsLabel, unsigned numSimdElems,
|
||||
MemoryBarrierBits before, MemoryBarrierBits after)
|
||||
: MBinaryInstruction(ptr, v),
|
||||
MAsmJSHeapAccess(accessType, needsBoundsCheck, outOfBoundsLabel),
|
||||
MAsmJSHeapAccess(accessType, needsBoundsCheck, outOfBoundsLabel, numSimdElems),
|
||||
barrierBefore_(before),
|
||||
barrierAfter_(after)
|
||||
{
|
||||
|
@ -12258,11 +12267,12 @@ class MAsmJSStoreHeap
|
|||
static MAsmJSStoreHeap *New(TempAllocator &alloc, Scalar::Type accessType,
|
||||
MDefinition *ptr, MDefinition *v, bool needsBoundsCheck,
|
||||
Label *outOfBoundsLabel = nullptr,
|
||||
unsigned numSimdElems = 0,
|
||||
MemoryBarrierBits barrierBefore = MembarNobits,
|
||||
MemoryBarrierBits barrierAfter = MembarNobits)
|
||||
{
|
||||
return new(alloc) MAsmJSStoreHeap(accessType, ptr, v, needsBoundsCheck, outOfBoundsLabel,
|
||||
barrierBefore, barrierAfter);
|
||||
numSimdElems, barrierBefore, barrierAfter);
|
||||
}
|
||||
|
||||
MDefinition *ptr() const { return getOperand(0); }
|
||||
|
|
Загрузка…
Ссылка в новой задаче