This is an archive of the discontinued LLVM Phabricator instance.

[IR] Redesign the case iterator in SwitchInst to actually be an iterator and to expose a handle to represent the actual case rather than having the iterator return a reference to itself.
ClosedPublic

Authored by chandlerc on Mar 31 2017, 1:49 PM.

Details

Summary

All of this allows the iterator to be used with common STL facilities,
standard algorithms, etc.

Doing this exposed some missing facilities in the iterator facade that
I've fixed and required some work to the actual iterator to fully
support the necessary API.

Diff Detail

Repository
rL LLVM

Event Timeline

chandlerc created this revision.Mar 31 2017, 1:49 PM
chandlerc updated this revision to Diff 94463.Apr 6 2017, 5:15 PM

Rebase, enhance with better testing of const iterators, fix a couple of minor
issues, and re-clang-format everything.

Also, ping. I'd love to get this landed.

dblaikie accepted this revision.Apr 10 2017, 11:30 AM
dblaikie added a subscriber: dblaikie.

Looks great to me, FWIW. Love getting rid of these weird pseudo iterators (or iterators with extra features in this case).

include/llvm/ADT/iterator.h
175 ↗(On Diff #94463)

Is there a reason these operators are written out explicitly like this, rather than as:

*static_cast<DerivedT*>(this) + n

? I guess it makes it clearer this is calling into a function implemented by the derived class? *shrug* no worries.

include/llvm/IR/Instructions.h
3181–3182 ↗(On Diff #94463)

Why protected? This class isn't derived from anywhere that I can see.

3185 ↗(On Diff #94463)

Is this necessary? Or could you use the injected class name for example:

static CaseIteratorT fromSuccessorIndex(...
3237–3238 ↗(On Diff #94463)

Could the adapter help avoid the need for writing both of these? (by implementing the non-const version with the const version and a const_cast of the result)

3327–3329 ↗(On Diff #94463)

Could potentially use range-based llvm::find_if here.

If you have a way to make a CaseIt from a ConstCaseIt (even if it's private/implementation detail) - you could implement the non-const one in terms of the const one to remove duplicate code) - looks pretty plausible given the underlying representation's the same (a pointer to the SwitchInst and the index into its cases)

But both of these are more cleanups that are only tangential to your change.

3346–3352 ↗(On Diff #94463)

This loop visits all elements when if there were a duplicate it could stop after it found the first one. Two calls to find_if might be nicer... maybe not. (& again, tangential refactoring not key to this change)

3347 ↗(On Diff #94463)

Early continue rather than nesting, maybe.

3349–3350 ↗(On Diff #94463)

else after return

This revision is now accepted and ready to land.Apr 10 2017, 11:30 AM
chandlerc marked 3 inline comments as done.Apr 12 2017, 12:39 AM

Thanks for the review. Mostly done, landing with those updates. Couple of things left, but you indicated they could be follow-ups. Questions on exactly what to do with them below.

include/llvm/ADT/iterator.h
175 ↗(On Diff #94463)

What you said. I didn't want to play overload resolution games or anything. Otherwise you sometimes get a pretty awful error message listing all the candidates that didn't help and not explaining that DerivedT needs to provide something.

include/llvm/IR/Instructions.h
3181–3182 ↗(On Diff #94463)

Just leftover from when it was a base class. Removed.

3185 ↗(On Diff #94463)

This was in the old iterator class and I just didn't remove it. Nuked.

3237–3238 ↗(On Diff #94463)

Interesting idea. This will impact other iterators though so I'd like to save it for a subsequent change.

3327–3329 ↗(On Diff #94463)

Since I'm here and making these iterators work like iterators with things like range based algos, the find_if makes total sense, done.

I'd like to save using the const to implement both for a subsequent change. I'm not 100% comfortable with the const casting stuff there, but I think it is probably worthwhile.

3346–3352 ↗(On Diff #94463)

I don't follow. When we find the duplicate we return rather than continuing to consider all cases?

Anyways, happy to clean this up in a follow-up if there is something here.

This revision was automatically updated to reflect the committed changes.
chandlerc marked an inline comment as done.