impl load32
This means we can write a memset32 (load32 -> store32), tested explicitly with the new unit test. Slightly changes to the type protocol, - load and splat now generate scalars or vectors depending on how `scalar` is set - store should no longer have to pay attention to `scalar`; it's input values will already be the right size Clean up some of the type declarations where we don't actually need the subclass types, holding llvm::Type* instead. This makes using ?: easier. Change-Id: I2f98701ebdeead0513d355b2666b024794b90193 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/273781 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
15c98cbfef
commit
11efa18eca
@ -1912,12 +1912,12 @@ namespace skvm {
|
||||
K = 16;
|
||||
}
|
||||
|
||||
llvm::Type *ptr = llvm::Type::getInt8Ty(ctx)->getPointerTo();
|
||||
//llvm::Type *f32 = llvm::Type::getFloatTy(ctx);
|
||||
llvm::IntegerType *i32 = llvm::Type::getInt32Ty(ctx),
|
||||
*i64 = llvm::Type::getInt64Ty(ctx);
|
||||
//llvm::VectorType *I32 = llvm::VectorType::get(i32, K),
|
||||
// *F32 = llvm::VectorType::get(f32, K);
|
||||
llvm::Type *ptr = llvm::Type::getInt8Ty(ctx)->getPointerTo(),
|
||||
*i64 = llvm::Type::getInt64Ty(ctx),
|
||||
// *f32 = llvm::Type::getFloatTy(ctx),
|
||||
// *F32 = llvm::VectorType::get(f32, K),
|
||||
*i32 = llvm::Type::getInt32Ty(ctx),
|
||||
*I32 = llvm::VectorType::get(i32, K);
|
||||
|
||||
std::vector<llvm::Type*> arg_types = { i64 };
|
||||
for (size_t i = 0; i < fStrides.size(); i++) {
|
||||
@ -1950,21 +1950,28 @@ namespace skvm {
|
||||
SkDebugf("can't llvm %s (%d)\n", name(op), op);
|
||||
return false;
|
||||
|
||||
case Op::store32: {
|
||||
llvm::Value* v = vals[x];
|
||||
if (scalar) {
|
||||
v = b->CreateExtractElement(v, (uint64_t)0);
|
||||
}
|
||||
case Op::load32: {
|
||||
llvm::Value* ptr = b->CreateBitCast(args[immy],
|
||||
v->getType()->getPointerTo());
|
||||
vals[i] = b->CreateAlignedStore(v, ptr, 1);
|
||||
(scalar ? i32 : I32)->getPointerTo());
|
||||
vals[i] = b->CreateAlignedLoad(ptr, 1);
|
||||
} break;
|
||||
|
||||
// Ops below this line shouldn't need to consider `scalar`... they're Just Math.
|
||||
|
||||
case Op::splat:
|
||||
vals[i] = llvm::ConstantVector::getSplat(K, llvm::ConstantInt::get(i32, immy));
|
||||
case Op::splat: {
|
||||
llvm::ConstantInt* imm = b->getInt32(immy);
|
||||
vals[i] = scalar ? imm
|
||||
: llvm::ConstantVector::getSplat(K, imm);
|
||||
break;
|
||||
}
|
||||
|
||||
case Op::store32: {
|
||||
llvm::Value* ptr = b->CreateBitCast(args[immy],
|
||||
vals[x]->getType()->getPointerTo());
|
||||
vals[i] = b->CreateAlignedStore(vals[x], ptr, 1);
|
||||
} break;
|
||||
|
||||
|
||||
|
||||
// Ops below this line shouldn't need to consider `scalar`... they're Just Math.
|
||||
|
||||
}
|
||||
return true;
|
||||
|
@ -281,7 +281,7 @@ DEF_TEST(SkVM_Pointless, r) {
|
||||
}
|
||||
|
||||
#if defined(SKVM_LLVM)
|
||||
DEF_TEST(SkVM_LLVM, r) {
|
||||
DEF_TEST(SkVM_LLVM_memset, r) {
|
||||
skvm::Builder b;
|
||||
b.store32(b.varying<int>(), b.splat(42));
|
||||
|
||||
@ -297,6 +297,28 @@ DEF_TEST(SkVM_LLVM, r) {
|
||||
}
|
||||
REPORTER_ASSERT(r, buf[17] == 47);
|
||||
}
|
||||
|
||||
DEF_TEST(SkVM_LLVM_memcpy, r) {
|
||||
skvm::Builder b;
|
||||
{
|
||||
auto src = b.varying<int>(),
|
||||
dst = b.varying<int>();
|
||||
b.store32(dst, b.load32(src));
|
||||
}
|
||||
|
||||
skvm::Program p = b.done();
|
||||
REPORTER_ASSERT(r, p.hasJIT());
|
||||
|
||||
int src[] = {1,2,3,4,5,6,7,8,9},
|
||||
dst[] = {0,0,0,0,0,0,0,0,0};
|
||||
|
||||
p.eval(SK_ARRAY_COUNT(src)-1, src, dst);
|
||||
for (size_t i = 0; i < SK_ARRAY_COUNT(src)-1; i++) {
|
||||
REPORTER_ASSERT(r, dst[i] == src[i]);
|
||||
}
|
||||
size_t i = SK_ARRAY_COUNT(src)-1;
|
||||
REPORTER_ASSERT(r, dst[i] == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
DEF_TEST(SkVM_LoopCounts, r) {
|
||||
|
Loading…
Reference in New Issue
Block a user