//===- DIExpressionRewriter.cpp - Rewriter for DIExpression operators -----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/Dialect/LLVMIR/Transforms/DIExpressionRewriter.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "llvm/Support/Debug.h" using namespace mlir; using namespace LLVM; #define DEBUG_TYPE "llvm-di-expression-simplifier" //===----------------------------------------------------------------------===// // DIExpressionRewriter //===----------------------------------------------------------------------===// void DIExpressionRewriter::addPattern( std::unique_ptr pattern) { patterns.emplace_back(std::move(pattern)); } DIExpressionAttr DIExpressionRewriter::simplify(DIExpressionAttr expr, std::optional maxNumRewrites) const { ArrayRef operators = expr.getOperations(); // `inputs` contains the unprocessed postfix of operators. // `result` contains the already finalized prefix of operators. // Invariant: concat(result, inputs) is equivalent to `operators` after some // application of the rewrite patterns. // Using a deque for inputs so that we have efficient front insertion and // removal. Random access is not necessary for patterns. std::deque inputs(operators.begin(), operators.end()); SmallVector result; uint64_t numRewrites = 0; while (!inputs.empty() && (!maxNumRewrites || numRewrites < *maxNumRewrites)) { bool foundMatch = false; for (const std::unique_ptr &pattern : patterns) { ExprRewritePattern::OpIterT matchEnd = pattern->match(inputs); if (matchEnd == inputs.begin()) continue; foundMatch = true; SmallVector replacement = pattern->replace(llvm::make_range(inputs.cbegin(), matchEnd)); inputs.erase(inputs.begin(), matchEnd); inputs.insert(inputs.begin(), replacement.begin(), replacement.end()); ++numRewrites; break; } if (!foundMatch) { // If no match, pass along the current operator. result.push_back(inputs.front()); inputs.pop_front(); } } if (maxNumRewrites && numRewrites >= *maxNumRewrites) { LLVM_DEBUG(llvm::dbgs() << "LLVMDIExpressionSimplifier exceeded max num rewrites (" << maxNumRewrites << ")\n"); // Skip rewriting the rest. result.append(inputs.begin(), inputs.end()); } return LLVM::DIExpressionAttr::get(expr.getContext(), result); }