summaryrefslogtreecommitdiff
path: root/compiler/optimizing/select_generator.h
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-08-04 16:29:42 +0100
committer Santiago Aboy Solanes <solanes@google.com> 2022-08-09 11:31:33 +0000
commit6981ef9238ce2d4ea3f7a86d3faf5d720c8c4641 (patch)
treeb48a079d3e4a6fea14c1942ad07db4ebd72b4341 /compiler/optimizing/select_generator.h
parentcaf9b6583272b90fc522cd445172ae97520dbe18 (diff)
Generate selects for nested ternary operators
After an R8 update, the generated dex instructions are different which means that the structure of the graph is different and we weren't recognizing a possibility of select generation. We now recognize it and can update the graph on the fly, generating the corresponding selects. Bug: 239385201 Fixes: 239385201 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I07644f0a69369e809994b4dd39bdd95c2cc7dc6c
Diffstat (limited to 'compiler/optimizing/select_generator.h')
-rw-r--r--compiler/optimizing/select_generator.h39
1 files changed, 39 insertions, 0 deletions
diff --git a/compiler/optimizing/select_generator.h b/compiler/optimizing/select_generator.h
index 30ac8a86eb..4f13917ba3 100644
--- a/compiler/optimizing/select_generator.h
+++ b/compiler/optimizing/select_generator.h
@@ -57,7 +57,9 @@
#ifndef ART_COMPILER_OPTIMIZING_SELECT_GENERATOR_H_
#define ART_COMPILER_OPTIMIZING_SELECT_GENERATOR_H_
+#include "base/scoped_arena_containers.h"
#include "optimization.h"
+#include "optimizing/nodes.h"
namespace art {
@@ -72,6 +74,43 @@ class HSelectGenerator : public HOptimization {
static constexpr const char* kSelectGeneratorPassName = "select_generator";
private:
+ bool TryGenerateSelectSimpleDiamondPattern(HBasicBlock* block,
+ ScopedArenaSafeMap<HInstruction*, HSelect*>* cache);
+
+ // When generating code for nested ternary operators (e.g. `return (x > 100) ? 100 : ((x < -100) ?
+ // -100 : x);`), a dexer can generate a double diamond pattern but it is not a clear cut one due
+ // to the merging of the blocks. `TryFixupDoubleDiamondPattern` recognizes that pattern and fixes
+ // up the graph to have a clean double diamond that `TryGenerateSelectSimpleDiamondPattern` can
+ // use to generate selects.
+ //
+ // In ASCII, it turns:
+ //
+ // 1 (outer if)
+ // / \
+ // 2 3 (inner if)
+ // | / \
+ // | 4 5
+ // \/ |
+ // 6 |
+ // \ |
+ // 7
+ // |
+ // 8
+ // into:
+ // 1 (outer if)
+ // / \
+ // 2 3 (inner if)
+ // | / \
+ // | 4 5
+ // \/ /
+ // 6
+ // |
+ // 8
+ //
+ // In short, block 7 disappears and we merge 6 and 7. Now we have a diamond with {3,4,5,6}, and
+ // when that gets resolved we get another one with the outer if.
+ HBasicBlock* TryFixupDoubleDiamondPattern(HBasicBlock* block);
+
DISALLOW_COPY_AND_ASSIGN(HSelectGenerator);
};