summaryrefslogtreecommitdiff
path: root/compiler/optimizing/execution_subgraph_test.cc
diff options
context:
space:
mode:
authorAlex Light <allight@google.com>2021-01-22 14:05:13 +0000
committerAlex Light <allight@google.com>2021-01-22 07:15:51 -0800
commitfc1ce4e8be0d977e3d41699f5ec746d68f63c024 (patch)
treeb656aa7c9e62aa181dfbf7fd4f2a0d32b8bf0704 /compiler/optimizing/execution_subgraph_test.cc
parentc6da1be58086e873c9695f8c4c1a3a8ca718696e (diff)
Revert^2 "Partial Load Store Elimination"
This reverts commit 47ac53100303e7e864b7f6d65f17b23088ccf1d6. There was a bug in LSE where we would incorrectly record the shadow$_monitor_ field as not having a default initial value. This caused partial LSE to be unable to compile the Object.identityHashCode function, causing crashes. This issue was fixed in a parent CL. Also updated all Offsets in LSE_test to be outside of the object header regardless of configuration. Test: ./test.py --host Bug: 67037140 Reason for revert: Fixed issue with shadow$_monitor_ field and offsets Change-Id: I4fb2afff4d410da818db38ed833927dfc0f6be33
Diffstat (limited to 'compiler/optimizing/execution_subgraph_test.cc')
-rw-r--r--compiler/optimizing/execution_subgraph_test.cc144
1 files changed, 144 insertions, 0 deletions
diff --git a/compiler/optimizing/execution_subgraph_test.cc b/compiler/optimizing/execution_subgraph_test.cc
index 1fc00d9f6b..98e642f1a7 100644
--- a/compiler/optimizing/execution_subgraph_test.cc
+++ b/compiler/optimizing/execution_subgraph_test.cc
@@ -425,6 +425,150 @@ TEST_F(ExecutionSubgraphTest, PropagationLoop3) {
ASSERT_TRUE(contents.find(blks.Get("exit")) != contents.end());
}
+// ┌───────┐ ┌──────────────┐
+// │ right │ ◀── │ entry │
+// └───────┘ └──────────────┘
+// │ │
+// │ │
+// ▼ ▼
+// ┌────┐ ┌───────┐ ┌──────────────┐
+// │ l2 │ ──▶ │ exit │ ┌─ │ l1 │ ◀┐
+// └────┘ └───────┘ │ └──────────────┘ │
+// ▲ │ │ │
+// └───────────────────┘ │ │
+// ▼ │
+// ┌──────────────┐ │ ┌──────────────┐
+// ┌─ │ l1loop │ │ │ l1loop_right │ ◀┐
+// │ └──────────────┘ │ └──────────────┘ │
+// │ │ │ │ │
+// │ │ │ │ │
+// │ ▼ │ │ │
+// │ ┌−−−−−−−−−−−−−−−−−−┐ │ │ │
+// │ ╎ removed ╎ │ │ │
+// │ ╎ ╎ │ │ │
+// │ ╎ ┌──────────────┐ ╎ │ │ │
+// │ ╎ │ l1loop_left │ ╎ │ │ │
+// │ ╎ └──────────────┘ ╎ │ │ │
+// │ ╎ ╎ │ │ │
+// │ └−−−−−−−−−−−−−−−−−−┘ │ │ │
+// │ │ │ │ │
+// │ │ │ │ │
+// │ ▼ │ │ │
+// │ ┌──────────────┐ │ │ │
+// │ │ l1loop_merge │ ─┘ │ │
+// │ └──────────────┘ │ │
+// │ ▲ │ │
+// │ └──────────────────────┘ │
+// │ │
+// │ │
+// └─────────────────────────────────────────────┘
+
+TEST_F(ExecutionSubgraphTest, PropagationLoop4) {
+ AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
+ "exit",
+ {{"entry", "l1"},
+ {"l1", "l2"},
+ {"l1", "l1loop"},
+ {"l1loop", "l1loop_left"},
+ {"l1loop", "l1loop_right"},
+ {"l1loop_left", "l1loop_merge"},
+ {"l1loop_right", "l1loop_merge"},
+ {"l1loop_merge", "l1"},
+ {"l2", "exit"},
+ {"entry", "right"},
+ {"right", "exit"}}));
+ ASSERT_TRUE(ExecutionSubgraph::CanAnalyse(graph_));
+ ExecutionSubgraph esg(graph_, /*analysis_possible=*/true, GetScopedAllocator());
+ esg.RemoveBlock(blks.Get("l1loop_left"));
+ esg.Finalize();
+ ASSERT_TRUE(esg.IsValid());
+ ASSERT_TRUE(IsValidSubgraph(esg));
+ std::unordered_set<const HBasicBlock*> contents(esg.ReachableBlocks().begin(),
+ esg.ReachableBlocks().end());
+
+ ASSERT_EQ(contents.size(), 3u);
+
+ // Not present, no path through. If we got to l1 loop then we must merge back
+ // with l1 and l2 so they're bad too.
+ ASSERT_TRUE(contents.find(blks.Get("l1loop")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1loop_left")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1loop_right")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1loop_merge")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l2")) == contents.end());
+
+ // present, path through.
+ ASSERT_TRUE(contents.find(blks.Get("right")) != contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("entry")) != contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("exit")) != contents.end());
+}
+
+// +------------------------------------------------------+
+// | |
+// | +--------------+ +-------------+ |
+// | | right | <-- | entry | |
+// | +--------------+ +-------------+ |
+// | | | |
+// | | | |
+// | v v |
+// | +--------------+ +--------------------+ +----+
+// +> | exit | +> | l1 | --> | l2 |
+// +--------------+ | +--------------------+ +----+
+// | | ^
+// +---------------+ | |
+// | v |
+// +--------------+ +-------------+ |
+// | l1loop_right | <-- | l1loop | |
+// +--------------+ +-------------+ |
+// | |
+// | |
+// v |
+// + - - - - - - - - + |
+// ' removed ' |
+// ' ' |
+// ' +-------------+ ' |
+// ' | l1loop_left | ' -+
+// ' +-------------+ '
+// ' '
+// + - - - - - - - - +
+TEST_F(ExecutionSubgraphTest, PropagationLoop5) {
+ AdjacencyListGraph blks(SetupFromAdjacencyList("entry",
+ "exit",
+ {{"entry", "l1"},
+ {"l1", "l2"},
+ {"l1", "l1loop"},
+ {"l1loop", "l1loop_left"},
+ {"l1loop", "l1loop_right"},
+ {"l1loop_left", "l1"},
+ {"l1loop_right", "l1"},
+ {"l2", "exit"},
+ {"entry", "right"},
+ {"right", "exit"}}));
+ ASSERT_TRUE(ExecutionSubgraph::CanAnalyse(graph_));
+ ExecutionSubgraph esg(graph_, /*analysis_possible=*/true, GetScopedAllocator());
+ esg.RemoveBlock(blks.Get("l1loop_left"));
+ esg.Finalize();
+ ASSERT_TRUE(esg.IsValid());
+ ASSERT_TRUE(IsValidSubgraph(esg));
+ std::unordered_set<const HBasicBlock*> contents(esg.ReachableBlocks().begin(),
+ esg.ReachableBlocks().end());
+
+ ASSERT_EQ(contents.size(), 3u);
+
+ // Not present, no path through. If we got to l1 loop then we must merge back
+ // with l1 and l2 so they're bad too.
+ ASSERT_TRUE(contents.find(blks.Get("l1loop")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1loop_left")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l1loop_right")) == contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("l2")) == contents.end());
+
+ // present, path through.
+ ASSERT_TRUE(contents.find(blks.Get("right")) != contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("entry")) != contents.end());
+ ASSERT_TRUE(contents.find(blks.Get("exit")) != contents.end());
+}
+
TEST_F(ExecutionSubgraphTest, Invalid) {
AdjacencyListGraph blks(SetupFromAdjacencyList(
"entry",