Bug 1113338: Generalize AsmJS{Load,Store}Heap to handle partial loads; r=luke

--HG--
extra : rebase_source : 14f1292bcaef32933e4a13136165973657cabeec
This commit is contained in:
Benjamin Bouvier 2015-01-28 13:30:32 +01:00
Родитель de9ea0eeeb
Коммит 26252ed8ba
3 изменённых файлов: 88 добавлений и 23 удалений

Просмотреть файл

@ -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); }