summaryrefslogtreecommitdiff
path: root/compiler/optimizing/optimizing_unit_test.h
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2025-01-22 04:28:26 -0800
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-01-22 04:28:26 -0800
commit00fa290d94a6f77ec1893f2bcf93c8d4bb222082 (patch)
treef51e443b0cae682e23b72f19c509befafb6d7aea /compiler/optimizing/optimizing_unit_test.h
parent3700032db52ec1cf78982ab2bef631f2b8a34011 (diff)
parent2892bd97319012fe00da26f645f2725bbc35cdc8 (diff)
Optimizing: Test for `HSelect` in irreducible loop. am: 2892bd9731
Original change: https://android-review.googlesource.com/c/platform/art/+/3453278 Change-Id: I7243391ca2c843b14f8fcadddf093ed2e15787e2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'compiler/optimizing/optimizing_unit_test.h')
-rw-r--r--compiler/optimizing/optimizing_unit_test.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler/optimizing/optimizing_unit_test.h b/compiler/optimizing/optimizing_unit_test.h
index 018ffce196..8115ea035d 100644
--- a/compiler/optimizing/optimizing_unit_test.h
+++ b/compiler/optimizing/optimizing_unit_test.h
@@ -389,6 +389,56 @@ class OptimizingUnitTestHelper {
return {pre_header, loop};
}
+ // Insert blocks for an irreducible loop before the `loop_exit`:
+ //
+ // <loop_exit's old predecessor>
+ // |
+ // split
+ // / \
+ // left_preheader right_preheader
+ // | |
+ // left_header <------- right_header <-+
+ // | | |
+ // | +------------> body ------------+
+ // |
+ // loop_exit
+ //
+ // Note that `left_preheader`, `right_preheader` and `body` are needed to avoid critical edges.
+ //
+ // `HGoto` instructions are added to `left_preheader`, `right_preheader`, `body`
+ // and `right_header`. To complete the control flow, the caller should add `HIf`
+ // to `split` and `left_header`.
+ //
+ // Returns `{split, left_header, right_header, body}`.
+ std::tuple<HBasicBlock*, HBasicBlock*, HBasicBlock*, HBasicBlock*> CreateIrreducibleLoop(
+ HBasicBlock* loop_exit) {
+ HBasicBlock* split = AddNewBlock();
+ HBasicBlock* left_preheader = AddNewBlock();
+ HBasicBlock* right_preheader = AddNewBlock();
+ HBasicBlock* left_header = AddNewBlock();
+ HBasicBlock* right_header = AddNewBlock();
+ HBasicBlock* body = AddNewBlock();
+
+ HBasicBlock* predecessor = loop_exit->GetSinglePredecessor();
+ predecessor->ReplaceSuccessor(loop_exit, split);
+
+ split->AddSuccessor(left_preheader); // true successor
+ split->AddSuccessor(right_preheader); // false successor
+ left_preheader->AddSuccessor(left_header);
+ right_preheader->AddSuccessor(right_header);
+ left_header->AddSuccessor(loop_exit); // true successor
+ left_header->AddSuccessor(body); // false successor
+ body->AddSuccessor(right_header);
+ right_header->AddSuccessor(left_header);
+
+ MakeGoto(left_preheader);
+ MakeGoto(right_preheader);
+ MakeGoto(body);
+ MakeGoto(right_header);
+
+ return {split, left_header, right_header, body};
+ }
+
HBasicBlock* AddNewBlock() {
HBasicBlock* block = new (GetAllocator()) HBasicBlock(graph_);
graph_->AddBlock(block);