Common target specific load/store intrinsics in Early CSE. Currently, only a few AArch64 load/store intrinsics are supported (ld2, st2, etc). Updated patch based on Pete and Hal's reviews. Uploading to Phabricator this time.
Thanks,
Sanjin
Differential D7121
Commoning of target specific load/store intrinsics in Early CSE ssijaric on Jan 22 2015, 12:48 AM. Authored by
Details
Diff Detail Event TimelineComment Actions Thanks for fixing all my prior comments. The patch LGTM with just the few additional comments I made. I'm no expert on this part of the compiler though, so it would be best if Hal or someone else can give the final LGTM. Thanks,
Comment Actions Thanks for the review, Pete. New patch uploaded.
Comment Actions Thanks for the review, Hal.
Comment Actions Okay (there was no need to repost this for just the whitespace change); feel free to commit. Comment Actions Sorry to reopen a long dead review thread, but I had a reason to look at EarlyCSE today and just noticed the changes. I feel the introduction of the ParseMemoryInst class has badly obscured the logic of this transform. I get that you wanted to abstract over the existence of both normal loads and stores and target specific loads and stores, but the extra layer of abstraction makes this code substantially harder to follow. Particular areas of concern include:
A potentially clearer design would have been to introduce a helper class for each type of operation: load, and store. Like CallSite, each helper class could simply proxy to the underlying instruction/information based on the type of the instruction so contained. Comment Actions Can you please provide an example of what you mean?
There is a comment in the TTI header explaining what this does: // Same Id is set by the target for corresponding load/store intrinsics. unsigned short MatchingId; and there is a comment in the implementation too: // For regular (non-intrinsic) loads/stores, this is set to -1. For // intrinsic loads/stores, the id is retrieved from the corresponding // field in the MemIntrinsicInfo structure. That field contains // non-negative values only. int MatchingId;
I assume you're talking about this: Vol = !LI->isSimple(); FWIW, I don't believe there was a behavioral change here. We can certainly re-name these variables.
I'm not sure. There is common behavior between load intrinsics and loads, store intrinsics and stores, etc. Comment Actions If you write You are pretty much guaranteed that LI is in fact a load. With ParseMemoryInst(I).isLoad() there's no self check. You could see a path being added that set Load=true, but forgot to actually save the instruction, or similar things. To be clear, I am *not* stating the current impl is buggy, just that its more error prone going forward.
Neither of these comments describe the *semantics*. What is *meaning* or *usage* of the matching id? Does it effect must aliasing rules? (Serious question here, I can't tell what it actually means.)
Thanks. A rename is definitely appropriate.
I think you're misreading my suggestion. Here's some psuedo code: Instruction *Inst; LoadSite(Instruction* I); operator bool() const; bool isSimple() { if(LoadInst *LI = dyn_cast<LoadInst>) return LI->isSimple(); assert is target intrinsic return TTI->getTarget...().isVolatile; } if (LoadSite LS = I) { if (StoreSite SS = I) Having the abstraction is fine, it should just be minimal. In particular, the abstraction itself shouldn't be stateful. Given there's little shared between loads (of any type) and stores (of any type), I think these should be separate. Comment Actions Hi Philip, Thanks for the review. Just to briefly add onto Hal's comment. Yes, this should be renamed to avoid confusion. There is no behavioral change, as Hal noted.
The reason for MatchingId is to identify matching loads and stores for target specific intrinsics. For example, the pointer type on different target specific intrinsic calls may be i8*, and MatchingId is there to make sure that only matching intrinsics get commoned (e.g. test case test_nocse3). This comment could be clearer.
I thought about introducing new classes to deal with both regular loads and target specific intrinsic loads (same for stores and target specific intrinsic stores). This was only needed for EarlyCSE, so I kept it localized. Looking back, it may have been cleaner to introduce these new classes, as they can be reused elsewhere (GVN?). If everyone agrees, I can come up with a new patch to do away with ParseMemInst. Thanks, Comment Actions Okay, please do so.
I think the way to state this is that the action of a target-specific memory intrinsic is not uniquely identified by the pointer type. We need to make sure that magic permuting load of type 1 is only matched with magic permuting store of type 1, magic permuting load of type 1 is only matched with magic permuting store of type 2, etc.
I think this is worth trying.
|
Please use \brief here instead of 'MemIntrinsicInfo -'