1 //===- TestConstantFold.cpp - Pass to test constant folding ---------------===// 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/Pass/Pass.h" 10 #include "mlir/Transforms/FoldUtils.h" 11 12 using namespace mlir; 13 14 namespace { 15 /// Simple constant folding pass. 16 struct TestConstantFold 17 : public PassWrapper<TestConstantFold, OperationPass<>> { 18 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestConstantFold) 19 20 StringRef getArgument() const final { return "test-constant-fold"; } 21 StringRef getDescription() const final { 22 return "Test operation constant folding"; 23 } 24 // All constants in the operation post folding. 25 SmallVector<Operation *> existingConstants; 26 27 void foldOperation(Operation *op, OperationFolder &helper); 28 void runOnOperation() override; 29 }; 30 } // namespace 31 32 void TestConstantFold::foldOperation(Operation *op, OperationFolder &helper) { 33 auto processGeneratedConstants = [this](Operation *op) { 34 existingConstants.push_back(op); 35 }; 36 37 // Attempt to fold the specified operation, including handling unused or 38 // duplicated constants. 39 (void)helper.tryToFold(op, processGeneratedConstants); 40 } 41 42 void TestConstantFold::runOnOperation() { 43 existingConstants.clear(); 44 45 // Collect and fold the operations within the operation. 46 SmallVector<Operation *, 8> ops; 47 getOperation()->walk([&](Operation *op) { ops.push_back(op); }); 48 49 // Fold the constants in reverse so that the last generated constants from 50 // folding are at the beginning. This creates somewhat of a linear ordering to 51 // the newly generated constants that matches the operation order and improves 52 // the readability of test cases. 53 OperationFolder helper(&getContext()); 54 for (Operation *op : llvm::reverse(ops)) 55 foldOperation(op, helper); 56 57 // By the time we are done, we may have simplified a bunch of code, leaving 58 // around dead constants. Check for them now and remove them. 59 for (auto *cst : existingConstants) { 60 if (cst->use_empty()) 61 cst->erase(); 62 } 63 } 64 65 namespace mlir { 66 namespace test { 67 void registerTestConstantFold() { PassRegistration<TestConstantFold>(); } 68 } // namespace test 69 } // namespace mlir 70