From 2892bd97319012fe00da26f645f2725bbc35cdc8 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Wed, 15 Jan 2025 15:12:37 +0000 Subject: Optimizing: Test for `HSelect` in irreducible loop. Test: m test-art-host-gtest Test: testrunner.py --host --optimizing Change-Id: I32e0ef7956cabb436a1759934e24a1c0f4b7ea2d --- compiler/optimizing/optimizing_unit_test.h | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'compiler/optimizing/optimizing_unit_test.h') 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`: + // + // + // | + // 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 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); -- cgit v1.2.3-59-g8ed1b