This source file includes following definitions.
- insert_func_wrapper_helper
- wrap_func_calls
#include "WrapCalls.h"
#include <set>
namespace Halide{
namespace Internal {
using std::map;
using std::pair;
using std::set;
using std::string;
using std::vector;
typedef map<Function, Function, Function::Compare> SubstitutionMap;
namespace {
void insert_func_wrapper_helper(map<Function, SubstitutionMap, Function::Compare> &func_wrappers_map,
const Function &in_func, const Function &wrapped_func,
const Function &wrapper) {
internal_assert(in_func.get_contents().defined() && wrapped_func.get_contents().defined() &&
wrapper.get_contents().defined());
internal_assert(func_wrappers_map[in_func].count(wrapped_func) == 0)
<< "Should only have one wrapper for each function call in a Func\n";
SubstitutionMap &wrappers_map = func_wrappers_map[in_func];
for (auto iter = wrappers_map.begin(); iter != wrappers_map.end(); ++iter) {
if (iter->second.same_as(wrapped_func)) {
debug(4) << "Merging wrapper of " << in_func.name() << " [" << iter->first.name()
<< ", " << iter->second.name() << "] with [" << wrapped_func.name() << ", "
<< wrapper.name() << "]\n";
iter->second = wrapper;
return;
} else if (wrapper.same_as(iter->first)) {
debug(4) << "Merging wrapper of " << in_func.name() << " [" << wrapped_func.name()
<< ", " << wrapper.name() << "] with [" << iter->first.name() << ", "
<< iter->second.name() << "]\n";
wrappers_map.emplace(wrapped_func, iter->second);
wrappers_map.erase(iter);
return;
}
}
wrappers_map[wrapped_func] = wrapper;
}
}
map<string, Function> wrap_func_calls(const map<string, Function> &env) {
map<string, Function> wrapped_env;
map<Function, SubstitutionMap, Function::Compare> func_wrappers_map;
for (const auto &iter : env) {
wrapped_env.emplace(iter.first, iter.second);
func_wrappers_map[iter.second];
}
for (const auto &it : env) {
string wrapped_fname = it.first;
const Function &wrapped_func = it.second;
const auto &wrappers = wrapped_func.schedule().wrappers();
set<string> all_func_wrappers;
for (const auto &iter : wrappers) {
all_func_wrappers.insert(Function(iter.second).name());
}
for (const auto &iter : wrappers) {
string in_func = iter.first;
const Function &wrapper = Function(iter.second);
if (in_func.empty()) {
for (const auto &wrapped_env_iter : wrapped_env) {
in_func = wrapped_env_iter.first;
if ((wrapper.name() == in_func) || (all_func_wrappers.find(in_func) != all_func_wrappers.end())) {
debug(4) << "Skip over replacing \"" << in_func << "\" with \"" << wrapper.name() << "\"\n";
continue;
}
if (wrappers.count(in_func)) {
continue;
}
debug(4) << "Global wrapper: replacing reference of \""
<< wrapped_fname << "\" in \"" << in_func
<< "\" with \"" << wrapper.name() << "\"\n";
insert_func_wrapper_helper(func_wrappers_map, wrapped_env_iter.second, wrapped_func, wrapper);
}
} else {
debug(4) << "Custom wrapper: replacing reference of \""
<< wrapped_fname << "\" in \"" << in_func << "\" with \""
<< wrapper.name() << "\"\n";
const auto &in_func_iter = wrapped_env.find(in_func);
if (in_func_iter == wrapped_env.end()) {
debug(4) << " skip custom wrapper for " << in_func << " [" << wrapped_fname
<< " -> " << wrapper.name() << "] since it's not in the pipeline\n";
continue;
}
insert_func_wrapper_helper(func_wrappers_map, wrapped_env[in_func], wrapped_func, wrapper);
}
}
}
for (auto &iter : wrapped_env) {
const auto &substitutions = func_wrappers_map[iter.second];
if (!substitutions.empty()) {
iter.second.substitute_calls(substitutions);
}
}
return wrapped_env;
}
}
}