|
|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright 2015-2020 Arm Limited
|
|
|
+ * Copyright 2015-2021 Arm Limited
|
|
|
*
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
@@ -2829,7 +2829,8 @@ const SPIRConstant &Compiler::get_constant(ConstantID id) const
|
|
|
return get<SPIRConstant>(id);
|
|
|
}
|
|
|
|
|
|
-static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, const unordered_set<uint32_t> &blocks)
|
|
|
+static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, const unordered_set<uint32_t> &blocks,
|
|
|
+ unordered_set<uint32_t> &visit_cache)
|
|
|
{
|
|
|
// This block accesses the variable.
|
|
|
if (blocks.find(block) != end(blocks))
|
|
|
@@ -2841,8 +2842,14 @@ static bool exists_unaccessed_path_to_return(const CFG &cfg, uint32_t block, con
|
|
|
|
|
|
// If any of our successors have a path to the end, there exists a path from block.
|
|
|
for (auto &succ : cfg.get_succeeding_edges(block))
|
|
|
- if (exists_unaccessed_path_to_return(cfg, succ, blocks))
|
|
|
- return true;
|
|
|
+ {
|
|
|
+ if (visit_cache.count(succ) == 0)
|
|
|
+ {
|
|
|
+ if (exists_unaccessed_path_to_return(cfg, succ, blocks, visit_cache))
|
|
|
+ return true;
|
|
|
+ visit_cache.insert(succ);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
@@ -2899,7 +2906,8 @@ void Compiler::analyze_parameter_preservation(
|
|
|
// void foo(int &var) { if (cond) var = 10; }
|
|
|
// Using read/write counts, we will think it's just an out variable, but it really needs to be inout,
|
|
|
// because if we don't write anything whatever we put into the function must return back to the caller.
|
|
|
- if (exists_unaccessed_path_to_return(cfg, entry.entry_block, itr->second))
|
|
|
+ unordered_set<uint32_t> visit_cache;
|
|
|
+ if (exists_unaccessed_path_to_return(cfg, entry.entry_block, itr->second, visit_cache))
|
|
|
arg.read_count++;
|
|
|
}
|
|
|
}
|