1//===- DIExpressionRewriter.cpp - Rewriter for DIExpression operators -----===//
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/Dialect/LLVMIR/Transforms/DIExpressionRewriter.h"
10#include "llvm/Support/Debug.h"
11
12using namespace mlir;
13using namespace LLVM;
14
15#define DEBUG_TYPE "llvm-di-expression-simplifier"
16
17//===----------------------------------------------------------------------===//
18// DIExpressionRewriter
19//===----------------------------------------------------------------------===//
20
21void DIExpressionRewriter::addPattern(
22 std::unique_ptr<ExprRewritePattern> pattern) {
23 patterns.emplace_back(Args: std::move(pattern));
24}
25
26DIExpressionAttr
27DIExpressionRewriter::simplify(DIExpressionAttr expr,
28 std::optional<uint64_t> maxNumRewrites) const {
29 ArrayRef<OperatorT> operators = expr.getOperations();
30
31 // `inputs` contains the unprocessed postfix of operators.
32 // `result` contains the already finalized prefix of operators.
33 // Invariant: concat(result, inputs) is equivalent to `operators` after some
34 // application of the rewrite patterns.
35 // Using a deque for inputs so that we have efficient front insertion and
36 // removal. Random access is not necessary for patterns.
37 std::deque<OperatorT> inputs(operators.begin(), operators.end());
38 SmallVector<OperatorT> result;
39
40 uint64_t numRewrites = 0;
41 while (!inputs.empty() &&
42 (!maxNumRewrites || numRewrites < *maxNumRewrites)) {
43 bool foundMatch = false;
44 for (const std::unique_ptr<ExprRewritePattern> &pattern : patterns) {
45 ExprRewritePattern::OpIterT matchEnd = pattern->match(inputs);
46 if (matchEnd == inputs.begin())
47 continue;
48
49 foundMatch = true;
50 SmallVector<OperatorT> replacement =
51 pattern->replace(llvm::make_range(x: inputs.cbegin(), y: matchEnd));
52 inputs.erase(first: inputs.begin(), last: matchEnd);
53 inputs.insert(position: inputs.begin(), first: replacement.begin(), last: replacement.end());
54 ++numRewrites;
55 break;
56 }
57
58 if (!foundMatch) {
59 // If no match, pass along the current operator.
60 result.push_back(Elt: inputs.front());
61 inputs.pop_front();
62 }
63 }
64
65 if (maxNumRewrites && numRewrites >= *maxNumRewrites) {
66 LLVM_DEBUG(llvm::dbgs()
67 << "LLVMDIExpressionSimplifier exceeded max num rewrites ("
68 << maxNumRewrites << ")\n");
69 // Skip rewriting the rest.
70 result.append(in_start: inputs.begin(), in_end: inputs.end());
71 }
72
73 return LLVM::DIExpressionAttr::get(context: expr.getContext(), operations: result);
74}
75

source code of mlir/lib/Dialect/LLVMIR/Transforms/DIExpressionRewriter.cpp