RFR: 8342047: Create Template Assertion Predicates with Halt nodes only instead of uncommon traps

Emanuel Peter epeter at openjdk.org
Wed Nov 13 10:56:11 UTC 2024


On Wed, 13 Nov 2024 10:36:05 GMT, Emanuel Peter <epeter at openjdk.org> wrote:

>> This patch replaces the creation of Template Assertion Predicates with uncommon traps with Halt nodes.
>> 
>> ### Goal of Assertion Predicates
>> #### Initialized Assertion Predicates
>> These predicates ensure that control is properly folded when data is dying. They are **always true by design** and thus can never fail at runtime. We therefore put a halt node on the failing path.
>> 
>> #### Template Assertion Predicates
>> Only serve as templates to create Initialized Assertion Predicates from. They are never executed and are always removed after loop opts are over. Conceptionally, it does not matter whether the failing path uses an UCT or a halt node (or something else completely - I plan to have a separate "no-op" `TemplateAssertionPredicateNode` at some point which only falls through to the next node and does not have a failing path at all).
>> 
>> ### Why Did we Use UCTs for Template Assertion Predicates?
>> When the concept of Assertion Predicates was first introduced, it only covered a few edge cases. It was quite straight forward to reuse existing Loop Predication code which creates new predicates from a Parse Predicate by copying it and merging the UCTs on the failing paths with a region node. This was done with `PhaseIdealLoop::create_new_if_for_predicate()`.
>> 
>> ### Why Do we Need to Use Halt Nodes for Template Assertion Predicates?
>> #### Missing UCTs for Predicates above Loops
>> Over time, we found more cases where we need to create Initialized Assertion Predicates from templates - including locations where we do not have Parse Predicates (and thus no safepoints). For example, when peeling one iteration off a loop with Parse Predicates, they will be kept at the peeled iteration and the remaining loop does not have any Parse Predicates anymore.
>> 
>> #### Missing UCTs to Create Template Assertion Predicates
>> Whenever we split a loop with Template Assertion Predicates, we also need to ensure that they are copied to all split loop versions. Since they rely on using UCTs, we also need to make sure that an UCT/safepoint is available to be used. However, this is not always the case (for example, after peeling an iteration off as described in the last section). As a result, we cannot easily establish new Template Assertion Predicates anywhere. One could think about faking an UCT or doing other special logic. But this seems rather fragile and could introduce quite some complexity - especially since we conceptionally don't even need to use UCTs at all for Te...
>
> src/hotspot/share/opto/loopPredicate.cpp line 362:
> 
>> 360: void PhaseIdealLoop::clone_parse_and_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, Node_List& old_new,
>> 361:                                                                              IfProjNode*& true_path_loop_entry,
>> 362:                                                                              IfProjNode*& false_path_loop_entry) {
> 
> Oh boy... passing pointers by reference... I suppose that was already here like this. Looks adventurous 🙈

Maybe there should be some sort of `UnswitchingResult`, that has the projections and `old_new` mapping? That could then be passed as a result. What do you think? Can be a separate RFE of course.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/22040#discussion_r1839946217


More information about the hotspot-compiler-dev mailing list