Introduce llvm.test.set.loop.iterations which sets the loop counter and also produces an i1 after testing that the count is not zero.
Details
Diff Detail
Event Timeline
Just a first look, some questions inline.
include/llvm/IR/Intrinsics.td | ||
---|---|---|
1195 | Perhaps it's blindingly obvious, but maybe a comment that this is useful for while-do hardware kind of loops? | |
lib/CodeGen/HardwareLoops.cpp | ||
264 | Is there always a preheader? Can we dereference a nullptr here? | |
271 | perhaps silly question, I guess the assumption here is that is if this is a conditional then it must be the loop check, but is that always true? |
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
264 | Just before landing here we create a preheader if one doesn't exist. | |
271 | Well it certainly is controlling whether the loop is entered or not... I had the same thought tbh but I reasoned that any other condition of entering a loop would be handled before the iteration condition - i will add some tests along these lines though. |
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
271 | My assumption was totally wrong :) so I'll revert to what I did originally: check for an icmp ne 0 so that the semantics don't change. I think we should be able to handle other icmp later by transforming them, if it's profitable. |
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
271 | cheers, sounds like a good plan |
Added a check that we're replacing the conditional with an equivalent statement... The intrinsic tests for a non-zero value for the trip count, so we now ensure that the loop entry is guarded by icmp ne %trip.count, 0. This has meant the code has been moved around a bit from the previous patch.
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
284 | A nit, and more a style preference, so please ignore if you disagree! | |
303 | Another nit: I think this could be nice candidate for a lambda to share code, i.e. the checks are the same in the if-clause and else-if clause, just the indexes are swapped. | |
329 | I am now actually wondering if we are checking here if the loop is particular kind of loop, i.e. a Single-Entry Single-Exit loop? Or, do we e.g. get this 'guarantee' from SCEV, because otherwise we can't calculate an iteration count? But what happens here if there are multiple predecessors? |
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
329 | There can be multiple exits, but the search for the given exit block is quite odd in my opinion... the exit block that forms the loop has to be executed on every iteration - dominating all other exit blocks. The trip count is given for that exit block. Multiple predecessors of what...? For the loop preheader, we just don't try to guard the entry and place the normal set.loop.iteration counter in the preheader. I'm wondering whether we could actually use the test.set.loop.iterations in the case of multiple preheader predecessors by placing the intrinsic in all those predecessors.... Something to look at later. |
- CanGenerateTest is its own function - also containing a lambda to check the icmp.
- Also using isLoopGuardedByCond to try to avoid the loop count being expanded before its required.
Last question I guess, I know it defaults to false, and hope I didn't miss it, but perhaps good to have a test too that explicitly sets -force-hardware-loop-guard=false?
lib/CodeGen/HardwareLoops.cpp | ||
---|---|---|
329 | Ok, got it, thanks! |
- Added a test line for -force-hardware-loop-guard=false.
- Also added a test line for -force-hardware-loop-phi=true for some extra coverage.
Looks good to me!
Perhaps wait a day with committing just in case someone has more comments.
Perhaps it's blindingly obvious, but maybe a comment that this is useful for while-do hardware kind of loops?