[PATCH] Global merge on constants
Quentin Colombet
qcolombet at apple.com
Thu Mar 14 16:53:50 PDT 2013
Thanks Bill, I appreciate even if it’s "a bit self-serving" :).
On Mar 14, 2013, at 4:24 PM, Bill Wendling <wendling at apple.com> wrote:
> On Mar 14, 2013, at 4:02 PM, Quentin Colombet <qcolombet at apple.com> wrote:
>
>> Hi,
>>
>> I’ve updated the patch for Global merge constants so that it implements the last proposal.
>>
>> Thanks for your reviews,
>>
> It's a bit self-serving for me to review this, given that I suggested it, but here we go. :-) Overall, this looks good. I would be interested to know how this affects compile time --- specifically at '-O0'. I ask because of looping over the uses of a global in a program can take a while for something that's used a lot. Could you run the test-suite to see if there are any significant slowdowns?
Will do. However, this pass is obviously not run at O0.
>
> There are a few nits:
>
> +/// Check whether the uses of the given value can be replaced by GEP.
>
> Should this start with a '\brief’?
Good question…
doxygen can interpret the first line of such comments as a brief, but it depends on how it is configured so I don’t know.
Anyway, it does not hurt to add one in that case :).
> +/// This function also checks transitively the uses made after a bitcast of the
> +/// given value.
> +/// Currently we consider that this is not possible when at least one of the
> +/// use is one of these kind:
> +/// - Intrinsic
> +/// - Landing pad
> +/// - Inline asm
> +/// \pre Val is a GlobalVariable or a bitcast of a GlobalVariable or a bitcast
> +/// of a bitcast of a GlobalVariable and so on.
> +static bool areUsesAcceptGEP(const Value *Val) {
>
> Do you mean 'areUsesExceptGEP’?
No, I want to check if all the uses can have a GEP as one of their operand, i.e., it won’t break the IR if we turn one of their operand into a GEP.
Maybe doUsesAcceptGEP is more correct?
If you have something else in mind, I’m sure it will be better!
>
> + for (Value::const_use_iterator UseIt = Val->use_begin(),
> + EndIt = Val->use_end(); UseIt != EndIt; ++UseIt) {
> + // Do not mess with Intrinsic or LandingPad
> + if (isa<const LandingPadInst>(*UseIt) ||
> + isa<const IntrinsicInst>(*UseIt))
>
> You don't need the 'const' in the 'isa<>' statement.
Okay.
>
> + return false;
> + // Same for InlineAsm
> + const CallInst *CI = dyn_cast<const CallInst>(*UseIt);
>
> Same here, re 'const' in the 'dyn_cast<>' statement.
Okay.
>
> + if (CI && isa<const InlineAsm>(CI->getCalledValue()))
> + return false;
> + // Check transitively uses done after a bitcasts
> + const BitCastInst *BI = dyn_cast<const BitCastInst>(*UseIt);
> + // FIXME: Is it possible to have a cycle with bitcasts uses, i.e.,
> + // value1 bitcasted to value2 and value2 bitcasted to value1 without
> + // anything in between?
>
> I don't think it's possible with SSA. I'm assuming you mean something like this?
That’s what I think too: because of SSA and because you cannot change the address of a global variable.
I can remove this comment then!
For the record, I had in mind something like this (which is syntactically wrong):
@g = i32*
@h = float*
define @foo() {
@h = bitcast i32* @g to float*
}
define @bar() {
@g = bitcast float* @h to i32*
}
>
> @g = i32* ...
>
> define void @foo() {
> %tmp1 = bitcast i32* @g to i8*
> %tmp2 = bitcast i8* %tmp1 to i32*
> }
>
> + // If yes, we should keep a set of already seen values.
> + if (BI && !areUsesAcceptGEP(BI))
> + return false;
> + }
> + return true;
> +}
>
> -bw
-Quentin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130314/0d3cc31f/attachment.html>
More information about the llvm-commits
mailing list