[LLVMdev] [Patches] Some LazyValueInfo and related patches
Olivier Goffart
olivier at woboq.com
Tue Jan 21 05:21:43 PST 2014
Hi.
Attached you will find a set of patches which I did while I was trying to solve
two problems.
I did not manage to solve fully what i wanted to improve, but I think it is
still a step in the right direction.
The patches are hopefully self-explanatory.
The biggest change here is that LazyValueInfo do not maintain a separate stack
of work to do,
but do the work directly recursively.
The test included in the patch 4 also test the patch 2.
The first problem I was trying to solve is to be let the code give hint on the
range of the values.
Imagine, in a library:
class CopyOnWrite {
char *stuff;
int ref_count;
void detach_internal();
inline void detach() {
if (ref_count > 1) {
detach_internal();
/* ref_count = 1; */
}
}
public:
char &operator[](int i) { detach(); return stuff[i]; }
};
Then, in code like this:
int doStuffWithStuff(CoptOnWrite &stuff) {
return stuff[0] + stuff[1] * stuff[2];
}
The generated code will contains three test of ref_count, and three call to
detach_internal
Is there a way to tell the compiler that ref_count is actually smaller or
equal to 1 after a call to detach_internal?
Having the "ref_count=1" explicit in the code help (with my patches), but then
the operation itself is in the code, and I don't want that.
Something like
if (ref_count>1)
__builtin_unreachable()
Works fine in GCC, but does not work with LLVM.
Well, it almost work. but the problem is that the whole condition is removed
before the inlining is done.
So what can be done for that to work? Either delay the removal of
__builtin_unreachable() to after inlining (when?)
Another way could be, while removing branches because they are unreachable,
somehow leave the range information kept.
I was thinking about a !range metadata, but I don't know where to put it.
The other problem was that i was analyzing code like this:
void toLatin1(uchar *dst, const ushort *src, int length)
{
if (length) {
#if defined(__SSE2__)
if (length >= 16) {
for (int i = 0; i < length >> 4; ++i) {
/* skipped code using SSE2 intrinsics */
src += 16; dst += 16;
}
length = length % 16;
}
#endif
while (length--) {
*dst++ = (*src>0xff) ? '?' : (uchar) *src;
++src;
}
}
}
I was wondering, if compiling with AVX, would clang/LLVM be able to even
vectorize more the SSE2 intrinsics to wider vectors? Or would the non
intrinsics branch be better?
It turns out the result is not great. LLVM leaves the intrinsics code
unchanged (that's ok), but tries to also vectorize the second loop. (And the
result of this vectorisation is quite horrible.)
Shouldn't the compiler see that length is never bigger than 16 and hence
deduce that there is no point in vectorizing? This is why I implemented the
srem and urem in LVI.
But then, maybe some other pass a loop pass should use LVI to see than a loop
never enters, or loop vectorizer could use LVI to avoid creating the loop in
the first place.
--
Olivier
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-SCCP-Do-not-transform-load-of-a-null-pointer-into-0.patch
Type: text/x-patch
Size: 1003 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-LVI-Be-able-to-optimize-the-condition-with-and-and-o.patch
Type: text/x-patch
Size: 7857 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0003-LVI-Re-order-the-check-that-the-second-operand-is-co.patch
Type: text/x-patch
Size: 2949 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0004-LVI-Look-recursively-the-dependencies-for-finding-ra.patch
Type: text/x-patch
Size: 3152 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0003.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0007-LVI-Support-range-detection-of-srem-and-urem.patch
Type: text/x-patch
Size: 8355 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0004.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0005-LVI-simplify-a-bit-by-not-having-a-separate-stack.patch
Type: text/x-patch
Size: 12836 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0005.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0008-CVP-Look-for-LVI-information-when-there-is-a-compari.patch
Type: text/x-patch
Size: 7736 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0006.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0006-LVI-simplify-remove-hasBlockValue-and-solve-from-get.patch
Type: text/x-patch
Size: 6095 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140121/f4ef0d84/attachment-0007.bin>
More information about the llvm-dev
mailing list