more JIT refactoring
This re-enables AVX2 JIT with simultaneous register assignment and instruction selection. You can see it working in a very basic way in how we choose instructions and registers for Op::mad_f32. Constants are still broadcast, here inside the loop instead of hoisted. I think it'll probably end up best to use constants directly from memory (as in vpshufb's masks), falling back to these in-loop broadcasts when that can't work. Change-Id: If17d51b9960f08da3612e51ac04424e996bf83d4 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/228366 Commit-Queue: Mike Klein <mtklein@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
869a3e81ea
commit
558b639225
1047
src/core/SkVM.cpp
1047
src/core/SkVM.cpp
File diff suppressed because it is too large
Load Diff
@ -260,7 +260,7 @@ namespace skvm {
|
||||
int death; // Index of last live instruction taking this input; live if != 0.
|
||||
};
|
||||
|
||||
Program done();
|
||||
Program done(const char* debug_name = nullptr);
|
||||
|
||||
// Declare a varying argument with given stride.
|
||||
Arg arg(int stride);
|
||||
@ -302,7 +302,7 @@ namespace skvm {
|
||||
I32 shr(I32 x, int bits);
|
||||
I32 sra(I32 x, int bits);
|
||||
|
||||
I32 extract(I32 x, int bits, I32 z); // (x >> bits) & z
|
||||
I32 extract(I32 x, int bits, I32 y); // (x >> bits) & y
|
||||
I32 pack (I32 x, I32 y, int bits); // x | (y << bits)
|
||||
|
||||
// Shuffle the bytes in x according to each nibble of control, as if
|
||||
@ -366,11 +366,10 @@ namespace skvm {
|
||||
union { Reg z; int imm; };
|
||||
};
|
||||
|
||||
Program(std::vector<Instruction>, int regs, int loop, std::vector<int> strides);
|
||||
Program() : Program({}, 0, 0, {}) {}
|
||||
|
||||
Program(const std::vector<Builder::Instruction>& instructions,
|
||||
const std::vector<int> & strides);
|
||||
const std::vector<int> & strides,
|
||||
const char* debug_name);
|
||||
Program() : Program({}, {}, nullptr) {}
|
||||
|
||||
~Program();
|
||||
Program(Program&&);
|
||||
@ -394,14 +393,20 @@ namespace skvm {
|
||||
private:
|
||||
void eval(int n, void* args[]) const;
|
||||
|
||||
void setupInterpreter(const std::vector<Builder::Instruction>&);
|
||||
void setupJIT (const std::vector<Builder::Instruction>&, const char* debug_name);
|
||||
bool jit (const std::vector<Builder::Instruction>&, Assembler*) const;
|
||||
|
||||
// Dump jit-*.dump files for perf inject.
|
||||
void dumpJIT(const char* debug_name) const;
|
||||
|
||||
std::vector<Instruction> fInstructions;
|
||||
int fRegs;
|
||||
int fLoop;
|
||||
std::vector<int> fStrides;
|
||||
|
||||
void* fJITBuf = nullptr; // Raw mmap'd buffer.
|
||||
size_t fJITSize = 0; // Size of buf in bytes.
|
||||
void (*fJITEntry)() = nullptr; // Entry point, offset into buf.
|
||||
void* fJITBuf = nullptr;
|
||||
size_t fJITSize = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -284,6 +284,9 @@ DEF_TEST(SkVM, r) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint8_t d = got & 0xff,
|
||||
w = want & 0xff;
|
||||
if (abs(d-w) >= 2) {
|
||||
SkDebugf("d %02x, w %02x\n", d,w);
|
||||
}
|
||||
REPORTER_ASSERT(r, abs(d-w) < 2);
|
||||
got >>= 8;
|
||||
want >>= 8;
|
||||
@ -292,10 +295,10 @@ DEF_TEST(SkVM, r) {
|
||||
});
|
||||
};
|
||||
|
||||
test_8888(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::RGBA_8888}.done());
|
||||
test_8888(SrcoverBuilder_I32_Naive{}.done());
|
||||
test_8888(SrcoverBuilder_I32{}.done());
|
||||
test_8888(SrcoverBuilder_I32_SWAR{}.done());
|
||||
test_8888(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::RGBA_8888}.done("srcover_f32"));
|
||||
test_8888(SrcoverBuilder_I32_Naive{}.done("srcover_i32_naive"));
|
||||
test_8888(SrcoverBuilder_I32{}.done("srcover_i32"));
|
||||
test_8888(SrcoverBuilder_I32_SWAR{}.done("srcover_i32_SWAR"));
|
||||
|
||||
test_jit_and_interpreter(SrcoverBuilder_F32{Fmt::RGBA_8888, Fmt::G8}.done(),
|
||||
[&](const skvm::Program& program) {
|
||||
|
Loading…
Reference in New Issue
Block a user