MLIR 22.0.0git
TemplatingUtils.h
Go to the documentation of this file.
1//===- TemplatingUtils.h - Templater for text templates -----------------===//
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#ifndef MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
10#define MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
11
12#include "llvm/ADT/SmallString.h"
13#include "llvm/ADT/StringMap.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/ErrorHandling.h"
16#include "llvm/Support/raw_ostream.h"
17#include <variant>
18#include <vector>
19
21
22/// A dictionary stores a mapping of template variable names to their assigned
23/// string values.
24using dictionary = llvm::StringMap<llvm::SmallString<8>>;
25
26/// Template Code as used by IRDL-to-Cpp.
27///
28/// For efficiency, produces a bytecode representation of an input template.
29/// - LiteralToken: A contiguous stream of characters to be printed
30/// - ReplacementToken: A template variable that will be replaced
31class Template {
32public:
33 Template(llvm::StringRef str) {
34 bool processingReplacementToken = false;
35 while (!str.empty()) {
36 auto [token, remainder] = str.split("__");
37
38 if (processingReplacementToken) {
39 assert(!token.empty() && "replacement name cannot be empty");
40 bytecode.emplace_back(ReplacementToken{token});
41 } else {
42 if (!token.empty())
43 bytecode.emplace_back(LiteralToken{token});
44 }
45
46 processingReplacementToken = !processingReplacementToken;
47 str = remainder;
48 }
49 }
50
51 /// Render will apply a dictionary to the Template and send the rendered
52 /// result to the specified output stream.
53 void render(llvm::raw_ostream &out, const dictionary &replacements) const {
54 for (auto instruction : bytecode) {
55 if (auto *inst = std::get_if<LiteralToken>(&instruction)) {
56 out << inst->text;
57 continue;
58 }
59
60 if (auto *inst = std::get_if<ReplacementToken>(&instruction)) {
61 auto replacement = replacements.find(inst->keyName);
62#ifndef NDEBUG
63 if (replacement == replacements.end()) {
64 llvm::errs() << "Missing template key: " << inst->keyName << "\n";
65 llvm_unreachable("Missing template key");
66 }
67#endif
68 out << replacement->second;
69 continue;
70 }
71
72 llvm_unreachable("non-exhaustive bytecode visit");
73 }
74 }
75
76private:
77 struct LiteralToken {
78 llvm::StringRef text;
79 };
80
81 struct ReplacementToken {
82 llvm::StringRef keyName;
83 };
84
85 std::vector<std::variant<LiteralToken, ReplacementToken>> bytecode;
86};
87
88} // namespace mlir::irdl::detail
89
90#endif // MLIR_LIB_TARGET_IRDLTOCPP_TEMPLATINGUTILS_H
*if copies could not be generated due to yet unimplemented cases *copyInPlacementStart and copyOutPlacementStart in copyPlacementBlock *specify the insertion points where the incoming copies and outgoing should be the output argument nBegin is set to its * replacement(set to `begin` if no invalidation happens). Since outgoing *copies could have been inserted at `end`
void render(llvm::raw_ostream &out, const dictionary &replacements) const
Render will apply a dictionary to the Template and send the rendered result to the specified output s...
Template(llvm::StringRef str)
llvm::StringMap< llvm::SmallString< 8 > > dictionary
A dictionary stores a mapping of template variable names to their assigned string values.