halide/Halide — pull request #419 by kree-colemcalughlin (2014-08-11 22:07:19+00:00)
Title: Deinterleave Powers of 2

I've added some functionality to the deinterleave mutator to handle powers of 2. The motivation for this is to generate efficient assembly code for converting from planar to interleaved data in the case of RGBA data, for example. With these changes we can write Halide code like:

```
Func output("output");
output(x, c) = input(x, c);

// Set extent and stride so that we convert from planar to interleaved.
output.output_buffer()
.set_min(1, 0)
.set_stride(0, 4)
.set_stride(1, 1)
.set_extent(1, 4);

// Schedule
Var cx("cx");
output
.bound(c, 0, 4)
.reorder(c, x)
.fuse(c, x, cx)
.vectorize(cx, 64);
```

And we will generate a decent block of punpck*** and mov*** calls on SSE architectures, e.g.:

```
vmovdqu	(%rsi,%rax), %xmm0
movq	40(%rsp), %rcx # 8-byte Reload
movslq	%ecx, %rcx
leaq	(%rcx,%rax), %rdx
vmovdqu	1(%rsi,%rdx), %xmm1
vpunpcklbw	%xmm1, %xmm0, %xmm2
vpunpckhbw	%xmm1, %xmm0, %xmm0
leaq	(%rax,%rcx,2), %rdx
vmovdqu	2(%rsi,%rdx), %xmm1
leaq	(%rcx,%rcx,2), %rcx
addq	%rax, %rcx
vmovdqu	3(%rsi,%rcx), %xmm3
vpunpcklbw	%xmm3, %xmm1, %xmm4
vpunpckhbw	%xmm3, %xmm1, %xmm1
vpunpcklwd	%xmm1, %xmm0, %xmm3
vpunpckhwd	%xmm1, %xmm0, %xmm0
vpunpcklwd	%xmm4, %xmm2, %xmm1
vpunpckhwd	%xmm4, %xmm2, %xmm2
movq	56(%rsp), %rax # 8-byte Reload
cltq
movq	8(%rsp), %rcx # 8-byte Reload
vmovdqu	%xmm2, 16(%rcx,%rax)
vmovdqu	%xmm1, (%rcx,%rax)
vmovdqu	%xmm0, 48(%rcx,%rax)
vmovdqu	%xmm3, 32(%rcx,%rax)
```