1//===- LoopInvariantCodeMotion.cpp - Code to perform loop fusion-----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements loop invariant code motion.
10//
11//===----------------------------------------------------------------------===//
12
13#include "mlir/Transforms/Passes.h"
14
15#include "mlir/IR/PatternMatch.h"
16#include "mlir/Interfaces/LoopLikeInterface.h"
17#include "mlir/Transforms/LoopInvariantCodeMotionUtils.h"
18
19namespace mlir {
20#define GEN_PASS_DEF_LOOPINVARIANTCODEMOTION
21#define GEN_PASS_DEF_LOOPINVARIANTSUBSETHOISTING
22#include "mlir/Transforms/Passes.h.inc"
23} // namespace mlir
24
25using namespace mlir;
26
27namespace {
28/// Loop invariant code motion (LICM) pass.
29struct LoopInvariantCodeMotion
30 : public impl::LoopInvariantCodeMotionBase<LoopInvariantCodeMotion> {
31 void runOnOperation() override;
32};
33
34struct LoopInvariantSubsetHoisting
35 : public impl::LoopInvariantSubsetHoistingBase<
36 LoopInvariantSubsetHoisting> {
37 void runOnOperation() override;
38};
39} // namespace
40
41void LoopInvariantCodeMotion::runOnOperation() {
42 // Walk through all loops in a function in innermost-loop-first order. This
43 // way, we first LICM from the inner loop, and place the ops in
44 // the outer loop, which in turn can be further LICM'ed.
45 getOperation()->walk(
46 callback: [&](LoopLikeOpInterface loopLike) { moveLoopInvariantCode(loopLike); });
47}
48
49void LoopInvariantSubsetHoisting::runOnOperation() {
50 IRRewriter rewriter(getOperation()->getContext());
51 // Walk through all loops in a function in innermost-loop-first order. This
52 // way, we first hoist from the inner loop, and place the ops in the outer
53 // loop, which in turn can be further hoisted from.
54 getOperation()->walk(callback: [&](LoopLikeOpInterface loopLike) {
55 (void)hoistLoopInvariantSubsets(rewriter, loopLike);
56 });
57}
58
59std::unique_ptr<Pass> mlir::createLoopInvariantCodeMotionPass() {
60 return std::make_unique<LoopInvariantCodeMotion>();
61}
62
63std::unique_ptr<Pass> mlir::createLoopInvariantSubsetHoistingPass() {
64 return std::make_unique<LoopInvariantSubsetHoisting>();
65}
66

source code of mlir/lib/Transforms/LoopInvariantCodeMotion.cpp