diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index b6e8651481..7a19fc043b 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -18,7 +18,7 @@ ExternalProject_Add(llvm GIT_SHALLOW 1 GIT_TAG - b1e6cc762cd729de01f1b4f3c0f6d9a493635ae0 + release_50 CMAKE_ARGS -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=NO diff --git a/include/glow/Optimizer/Optimizer.h b/include/glow/Optimizer/Optimizer.h new file mode 100644 index 0000000000..c6983152b4 --- /dev/null +++ b/include/glow/Optimizer/Optimizer.h @@ -0,0 +1,12 @@ +#ifndef GLOW_OPTIMIZER_OPTIMIZER_H +#define GLOW_OPTIMIZER_OPTIMIZER_H + +namespace glow { + +class Module; + +void optimize(Module &M); + +} // namespace glow + +#endif // GLOW_OPTIMIZER_OPTIMIZER_H diff --git a/src/glow/CMakeLists.txt b/src/glow/CMakeLists.txt index 6a767d3a72..08ad071c56 100644 --- a/src/glow/CMakeLists.txt +++ b/src/glow/CMakeLists.txt @@ -1,8 +1,9 @@ +add_subdirectory(IR) add_subdirectory(Importer) add_subdirectory(Interpreter) -add_subdirectory(IR) add_subdirectory(Models) add_subdirectory(Network) +add_subdirectory(Optimizer) add_subdirectory(Support) diff --git a/src/glow/Optimizer/CMakeLists.txt b/src/glow/Optimizer/CMakeLists.txt new file mode 100644 index 0000000000..ec38ceb6e9 --- /dev/null +++ b/src/glow/Optimizer/CMakeLists.txt @@ -0,0 +1,8 @@ + +add_library(Optimizer + Optimizer.cpp) + +target_link_libraries(Optimizer + PRIVATE + IR) + diff --git a/src/glow/Optimizer/Optimizer.cpp b/src/glow/Optimizer/Optimizer.cpp new file mode 100644 index 0000000000..1a6ceb008c --- /dev/null +++ b/src/glow/Optimizer/Optimizer.cpp @@ -0,0 +1,54 @@ +#include "glow/Optimizer/Optimizer.h" +#include "glow/IR/IR.h" +#include "glow/IR/Instrs.h" +#include "glow/Support/Casting.h" + +#include + +using namespace glow; + +/// Hoists Dealloc instructions right after their last use. +static void hoistDealloc(Module &M) { + using iterator = Module::InstListTy::iterator; + // Maps activation instructions to their last non-dealloc user. + std::unordered_map lastUser; + auto &instrs = M.getInstrs(); + + // Record the last use of each dealloc. + for (auto it = instrs.begin(), e = instrs.end(); it != e; ++it) { + if (isa(*it)) + continue; + + for (int i = 0, e = (*it)->getNumOperands(); i < e; i++) { + auto op = (*it)->getOperand(i).first; + if (auto alloc = dyn_cast(op)) { + lastUser[alloc] = it; + } + } + } + + // Now that we've found the last user we can hoist the instruction. + for (auto it = instrs.begin(), e = instrs.end(); it != e; /* increment below */) { + iterator curr = it; + auto *da = dyn_cast(*curr); + if (!da) { + ++it; + continue; + } + + auto *alloc = cast(da->getOperand(0).first); + + it = instrs.erase(curr); + auto &where = lastUser[alloc]; + where++; + instrs.insert(where, da); + } +} + +void glow::optimize(Module &M) { + M.verify(); + + hoistDealloc(M); + + M.verify(); +}