[llvm-commits] [llvm] r151093 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/constantfold-initializers.ll

Nick Lewycky nicholas at mxc.ca
Wed Feb 22 23:34:39 PST 2012


Chris Lattner wrote:
>
> On Feb 21, 2012, at 10:25 PM, Nick Lewycky wrote:
>
>> Chris Lattner wrote:
>>>
>>> On Feb 21, 2012, at 2:08 PM, Nick Lewycky wrote:
>>>
>>>> Author: nicholas
>>>> Date: Tue Feb 21 16:08:06 2012
>>>> New Revision: 151093
>>>>
>>>> URL: http://llvm.org/viewvc/llvm-project?rev=151093&view=rev
>>>> Log:
>>>> Use the target-aware constant folder on expressions to improve the chance
>>>> they'll be simple enough to simulate, and to reduce the chance we'll encounter
>>>> equal but different simple pointer constants.
>>>>
>>>> This removes the symptoms from PR11352 but is not a full fix. A proper fix would
>>>> either require a guarantee that two constant objects we simulate are folded
>>>> when equal, or a different way of handling equal pointers (ie., trying a
>>>> constantexpr icmp on them to see whether we know they're equal or non-equal or
>>>> unsure).
>>>
>>> I think it should be enough to consider two constants the same if they are pointer equal and neither is a ConstantExpr.
>>
>> Sure that's sufficient, but we'd like to handle ConstantExpr's, such as an all-zero GEP.
>>
>> Yep, the non-TD constant folder can't pick one of:
>>   getelementptr inbounds (%closure* @f, i32 0, i32 0)
>>   getelementptr inbounds (%closure* @f, i64 0, i32 0)
>> . Oops, and that breaks GlobalOpt. Double-oops.
>>
>> Really, I'd rather figure out some way to constant fold those into the same Constant* rather than teach globalopt anything new.
>
> The simplest way is to use ConstantExpr::getICmp(EQ, a, b) and see if the result is a ConstantInt.
>
> However, you really have a three way comparison here:
>
> 1. If the Constant*'s are the same, you know they are equal.
> 2. If the Constant*'s are not constant exprs, you know they are non-equal.
> 3. Otherwise you don't know.

Right, exactly. Then we're taking the pointers and putting them in a 
MutableMemory[Ptr1] for stores and looking them up with 
MutableMemory[Ptr2] for loads. It isn't easy to write a correct 
operator< because it may happen that on lookup(p4) where p4 is deeply 
equal to p2, and by simple pointer comparison p1 < p2 < p3 < p4, the 
binary search will discard p1 and p2 as candidates first so we'll never 
see the equality.

We could make a vector of the constant-expr's, but that's O(n^2). I 
suspect there's an efficient solution to this, I just haven't thought 
about it enough to figure out what it is.

Off the cuff ideas include canonicalizing GEP indices down to the 
smallest legal bitwidth that doesn't discard information. That fixes the 
problem across the board and might even improve optz'n to boot. Another 
idea is to make GlobalOpt rewrite GEPs internally into base + 
byte-offset form.

Nick



More information about the llvm-commits mailing list