Enable DeviceMemoryTest for control flow models

Also corrects some wordings related to control flow.

Bug: 149693818
Test: NNT_Static
Change-Id: If16eee0613f9166f0688b4289f68a389e92e6e2f
Merged-In: If16eee0613f9166f0688b4289f68a389e92e6e2f
(cherry picked from commit 4c6e1c89566f46e0a1fc824f18523080c33ea7d2)
diff --git a/runtime/ExecutionPlan.cpp b/runtime/ExecutionPlan.cpp
index 91ef6b1..868e99e 100644
--- a/runtime/ExecutionPlan.cpp
+++ b/runtime/ExecutionPlan.cpp
@@ -1495,14 +1495,14 @@
     callback(mPreparedModel.get(), IOType::OUTPUT, index);
 }
 
-// Map an input role of the parent model to the input/output roles in the step models:
-// - An input role of the parent model may be used as an input of multiple step-models.
-// - An input role of the parent model should not be used as an output of any step-model.
+// Map an input role of the main model to the input/output roles in the step models:
+// - An input role of the main model may be used as an input of multiple step models.
+// - An input role of the main model should not be used as an output of any step model.
 void ExecutionPlan::CompoundBody::forEachStepRoleOfInput(uint32_t index,
                                                          const StepRoleCallback& callback) const {
     for (const auto& logicalStep : mSteps) {
         if (const ExecutionStep* step = logicalStep->tryExecutionStep()) {
-            // Model input as step-model input.
+            // Model input as step model input.
             const auto& inputMapping = step->getInputIndexStepModelToMainModel();
             for (uint32_t i = 0; i < inputMapping.size(); i++) {
                 if (inputMapping[i] == index) {
@@ -1513,15 +1513,15 @@
     }
 }
 
-// Map an output role of the parent model to the input/output roles in the step models:
-// - An output role of the parent model may only be used as one output of one single step-model.
-// - An output role of the parent model may be used as an input of multiple step-models.
+// Map an output role of the main model to the input/output roles in the step models:
+// - An output role of the main model may only be used as one output of one single step model.
+// - An output role of the main model may be used as an input of multiple step models.
 void ExecutionPlan::CompoundBody::forEachStepRoleOfOutput(uint32_t index,
                                                           const StepRoleCallback& callback) const {
     bool found = false;
     for (const auto& logicalStep : mSteps) {
         if (const ExecutionStep* step = logicalStep->tryExecutionStep()) {
-            // Model output as step-model output.
+            // Model output as step model output.
             if (!found) {
                 const auto& outputMapping = step->getOutputIndexStepModelToMainModel();
                 for (uint32_t i = 0; i < outputMapping.size(); i++) {
@@ -1532,7 +1532,7 @@
                     }
                 }
             }
-            // Model output as step-model input.
+            // Model output as step model input.
             const auto& inputToOutputMapping = step->getOutputsAsStepModelInputsIndexToMainModel();
             for (uint32_t i = 0; i < inputToOutputMapping.size(); i++) {
                 if (inputToOutputMapping[i] == index) {
diff --git a/runtime/Memory.cpp b/runtime/Memory.cpp
index 80a4f99..6c48d87 100644
--- a/runtime/Memory.cpp
+++ b/runtime/Memory.cpp
@@ -422,7 +422,7 @@
     LOG(INFO) << "    Zero point: " << toString(operand.zeroPoint);
     LOG(INFO) << "    Extra params: " << toString(operand.extraParams);
     LOG(INFO) << "    Dimensions: " << toString(desc.dimensions);
-    LOG(INFO) << "    Submodels [" << desc.preparedModels.size() << "]:";
+    LOG(INFO) << "    Prepared models [" << desc.preparedModels.size() << "]:";
     for (const auto* preparedModel : desc.preparedModels) {
         LOG(INFO) << "        service = " << preparedModel->getDevice()->getName();
     }
@@ -457,7 +457,10 @@
         logMemoryDescriptorToInfo(mDesc, mOperand.value());
     }
     std::set<const Device*> devices = getDevices(mDesc);
-    if (devices.size() == 1) {
+    if (devices.empty()) {
+        // This can happen with interpreted control flow.
+        mAllocator = nullptr;
+    } else if (devices.size() == 1) {
         mAllocator = *devices.begin();
         VLOG(MEMORY) << "Using " << mAllocator->getName() << " as allocator.";
     } else {
diff --git a/runtime/test/TestGenerated.cpp b/runtime/test/TestGenerated.cpp
index 5dafcd5..0e90113 100644
--- a/runtime/test/TestGenerated.cpp
+++ b/runtime/test/TestGenerated.cpp
@@ -455,10 +455,6 @@
 });
 
 INSTANTIATE_GENERATED_TEST(DeviceMemoryTest, [](const TestModel& testModel) {
-    if (!testModel.referenced.empty()) {
-        // TODO(b/149693818): Add control flow support to DeviceMemoryTest.
-        return false;
-    }
     return !testModel.expectFailure &&
            std::all_of(testModel.main.outputIndexes.begin(), testModel.main.outputIndexes.end(),
                        [&testModel](uint32_t index) {