1 //===- SideEffectUtils.cpp - Side Effect Utils ------------------*- C++ -*-===//
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 #include "mlir/Transforms/SideEffectUtils.h"
10 #include "mlir/IR/Operation.h"
11 #include "mlir/Interfaces/SideEffectInterfaces.h"
12 
13 using namespace mlir;
14 
isSideEffectFree(Operation * op)15 bool mlir::isSideEffectFree(Operation *op) {
16   if (auto memInterface = dyn_cast<MemoryEffectOpInterface>(op)) {
17     // If the op has side-effects, it cannot be moved.
18     if (!memInterface.hasNoEffect())
19       return false;
20     // If the op does not have recursive side effects, then it can be moved.
21     if (!op->hasTrait<OpTrait::HasRecursiveSideEffects>())
22       return true;
23   } else if (!op->hasTrait<OpTrait::HasRecursiveSideEffects>()) {
24     // Otherwise, if the op does not implement the memory effect interface and
25     // it does not have recursive side effects, then it cannot be known that the
26     // op is moveable.
27     return false;
28   }
29 
30   // Recurse into the regions and ensure that all nested ops can also be moved.
31   for (Region &region : op->getRegions())
32     for (Operation &op : region.getOps())
33       if (!isSideEffectFree(&op))
34         return false;
35   return true;
36 }
37