Skip to content

Commit b6b3404

Browse files
authored
Refactoring of qss-compiler tool and configuration to align with LLVM 17 (#217)
This PR is a part of a series of follow-up PR to the LLVM 17 upgrade to support new functionality introduced to MLIR in LLVM 17. Follow-up PRs will: - Incorporation of new MLIR timing mechanisms - Support for bytecode - Refactor the API methods to support library calls directly I should note that I do plan to refactor input/output strings out of the configuration and into the tool calls directly as MLIR opt does but I am leaving this for the follow-up PRs to avoid adding even more to this PR.
1 parent 4b83740 commit b6b3404

File tree

9 files changed

+1036
-524
lines changed

9 files changed

+1036
-524
lines changed

include/Config/CLIConfig.h

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ namespace qssc::config {
2222

2323
/// @brief Get the CLI category for the QSS compiler.
2424
/// @return The reference to the CLI category for the compiler.
25-
llvm::cl::OptionCategory &getQSSCCategory();
25+
llvm::cl::OptionCategory &getQSSCCLCategory();
26+
27+
/// @brief Get the CLI category for the QSS compiler mlir-opt options.
28+
/// @return The reference to the CLI category for the compiler.
29+
llvm::cl::OptionCategory &getQSSOptCLCategory();
2630

2731
/// @brief Build a QSSConfig from input CLI arguments.
2832
///
@@ -32,23 +36,11 @@ llvm::cl::OptionCategory &getQSSCCategory();
3236
///
3337
/// The qss-compiler adds several cli arguments to
3438
/// configure the QSSConfig through the CLIConfigBuilder.
35-
///
36-
/// These currently are:
37-
/// - `--target=<str>`: Sets QSSConfig::targetName.
38-
/// - `--config=<str>`: Sets QSSConfig::targetConfigPath.
39-
/// - `--allow-unregistered-dialect=<bool>`: Sets
40-
/// QSSConfig::allowUnregisteredDialects.
41-
/// - `--add-target-passes=<bool>`: Sets QSSConfig::addTargetPasses.
42-
///
4339
class CLIConfigBuilder : public QSSConfigBuilder {
4440
public:
41+
explicit CLIConfigBuilder();
42+
static void registerCLOptions(mlir::DialectRegistry &registry);
4543
llvm::Error populateConfig(QSSConfig &config) override;
46-
47-
private:
48-
llvm::Error populateConfigurationPath_(QSSConfig &config);
49-
llvm::Error populateTarget_(QSSConfig &config);
50-
llvm::Error populateAllowUnregisteredDialects_(QSSConfig &config);
51-
llvm::Error populateAddTargetPasses_(QSSConfig &config);
5244
};
5345

5446
} // namespace qssc::config

include/Config/QSSConfig.h

Lines changed: 206 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,44 @@
1818
#include "llvm/Support/raw_ostream.h"
1919

2020
#include "mlir/IR/MLIRContext.h"
21+
#include "mlir/Tools/mlir-opt/MlirOptMain.h"
2122

2223
#include <iostream>
2324
#include <optional>
2425
#include <string>
26+
#include <utility>
2527

2628
namespace qssc::config {
2729

30+
enum class EmitAction { None, AST, ASTPretty, MLIR, WaveMem, QEM, QEQEM };
31+
32+
enum class FileExtension {
33+
None,
34+
AST,
35+
ASTPretty,
36+
QASM,
37+
MLIR,
38+
WaveMem,
39+
QEM,
40+
QEQEM
41+
};
42+
43+
enum class InputType { None, QASM, MLIR };
44+
45+
std::string to_string(const EmitAction &inExt);
46+
47+
std::string to_string(const FileExtension &inExt);
48+
49+
std::string to_string(const InputType &inType);
50+
51+
InputType fileExtensionToInputType(const FileExtension &inExt);
52+
53+
EmitAction fileExtensionToAction(const FileExtension &inExt);
54+
55+
FileExtension strToFileExtension(const llvm::StringRef extStr);
56+
57+
FileExtension getExtension(const llvm::StringRef inStr);
58+
2859
/// @brief The QSS configuration data structure that is to be used for global
2960
/// configuration of the QSS infrastructure. This is to be used for static
3061
/// options that are rarely changed for a system and do not need to be
@@ -33,18 +64,164 @@ namespace qssc::config {
3364
/// as CLI, environment variables and possible configuration file formats
3465
/// through QSSConfigBuilder implementations which apply successive views over
3566
/// the configuration to produce the final configuration.
36-
struct QSSConfig {
67+
struct QSSConfig : mlir::MlirOptMainConfig {
68+
69+
public:
70+
friend class CLIConfigBuilder;
71+
friend class EnvVarConfigBuilder;
72+
73+
QSSConfig &setInputSource(std::string source) {
74+
inputSource = std::move(source);
75+
return *this;
76+
}
77+
llvm::StringRef getInputSource() const { return inputSource; }
78+
79+
QSSConfig &directInput(bool flag) {
80+
directInputFlag = flag;
81+
return *this;
82+
}
83+
bool isDirectInput() const { return directInputFlag; }
84+
85+
QSSConfig &setOutputFilePath(std::string path) {
86+
outputFilePath = std::move(path);
87+
return *this;
88+
}
89+
llvm::StringRef getOutputFilePath() const { return outputFilePath; }
90+
91+
QSSConfig &setTargetName(std::string name) {
92+
targetName = std::move(name);
93+
return *this;
94+
}
95+
std::optional<llvm::StringRef> getTargetName() const {
96+
if (targetName.has_value())
97+
return targetName.value();
98+
return std::nullopt;
99+
}
100+
101+
QSSConfig &setTargetConfigPath(std::string path) {
102+
targetConfigPath = std::move(path);
103+
return *this;
104+
}
105+
std::optional<llvm::StringRef> getTargetConfigPath() const {
106+
if (targetConfigPath.has_value())
107+
return targetConfigPath.value();
108+
return std::nullopt;
109+
}
110+
111+
QSSConfig &setInputType(InputType type) {
112+
inputType = type;
113+
return *this;
114+
}
115+
InputType getInputType() const { return inputType; }
116+
117+
QSSConfig &setEmitAction(EmitAction action) {
118+
emitAction = action;
119+
return *this;
120+
}
121+
EmitAction getEmitAction() const { return emitAction; }
122+
123+
QSSConfig &addTargetPasses(bool flag) {
124+
addTargetPassesFlag = flag;
125+
return *this;
126+
}
127+
bool shouldAddTargetPasses() const { return addTargetPassesFlag; }
128+
129+
QSSConfig &showTargets(bool flag) {
130+
showTargetsFlag = flag;
131+
return *this;
132+
}
133+
bool shouldShowTargets() const { return showTargetsFlag; }
134+
135+
QSSConfig &showPayloads(bool flag) {
136+
showPayloadsFlag = flag;
137+
return *this;
138+
}
139+
bool shouldShowPayloads() const { return showPayloadsFlag; }
140+
141+
QSSConfig &showConfig(bool flag) {
142+
showConfigFlag = flag;
143+
return *this;
144+
}
145+
bool shouldShowConfig() const { return showConfigFlag; }
146+
147+
QSSConfig &emitPlaintextPayload(bool flag) {
148+
emitPlaintextPayloadFlag = flag;
149+
return *this;
150+
}
151+
bool shouldEmitPlaintextPayload() const { return emitPlaintextPayloadFlag; }
152+
153+
QSSConfig &includeSource(bool flag) {
154+
includeSourceFlag = flag;
155+
return *this;
156+
}
157+
bool shouldIncludeSource() const { return includeSourceFlag; }
158+
159+
QSSConfig &compileTargetIR(bool flag) {
160+
compileTargetIRFlag = flag;
161+
return *this;
162+
}
163+
bool shouldCompileTargetIR() const { return compileTargetIRFlag; }
164+
165+
QSSConfig &bypassPayloadTargetCompilation(bool flag) {
166+
bypassPayloadTargetCompilationFlag = flag;
167+
return *this;
168+
}
169+
bool shouldBypassPayloadTargetCompilation() const {
170+
return bypassPayloadTargetCompilationFlag;
171+
}
172+
173+
QSSConfig &setPassPlugins(std::vector<std::string> plugins) {
174+
dialectPlugins = std::move(plugins);
175+
return *this;
176+
}
177+
const std::vector<std::string> &getPassPlugins() { return dialectPlugins; }
178+
179+
QSSConfig &setDialectPlugins(std::vector<std::string> plugins) {
180+
dialectPlugins = std::move(plugins);
181+
return *this;
182+
}
183+
const std::vector<std::string> &getDialectPlugins() { return dialectPlugins; }
184+
185+
public:
186+
/// @brief Emit the configuration to stdout.
187+
void emit(llvm::raw_ostream &out) const;
188+
189+
protected:
190+
/// @brief input source (file path or direct input) to compile
191+
std::string inputSource = "-";
192+
/// @brief Whether inputSource directly contains the input source (otherwise
193+
/// it is a file path).
194+
bool directInputFlag = false;
195+
/// @brief Output path for the compiler output if emitting to file.
196+
std::string outputFilePath = "-";
37197
/// @brief The TargetSystem to target compilation for.
38198
std::optional<std::string> targetName = std::nullopt;
39199
/// @brief The path to the TargetSystem configuration information.
40200
std::optional<std::string> targetConfigPath = std::nullopt;
41-
/// @brief Allow unregistered dialects to be used during compilation.
42-
bool allowUnregisteredDialects = false;
201+
/// @brief Source input type
202+
InputType inputType = InputType::None;
203+
/// @brief Output action to take
204+
EmitAction emitAction = EmitAction::None;
43205
/// @brief Register target passes with the compiler.
44-
bool addTargetPasses = true;
45-
46-
/// @brief Emit the configuration to stdout.
47-
void emit(llvm::raw_ostream &out) const;
206+
bool addTargetPassesFlag = true;
207+
/// @brief Should available targets be printed
208+
bool showTargetsFlag = false;
209+
/// @brief Should available payloads be printed
210+
bool showPayloadsFlag = false;
211+
/// @brief Should the current configuration be printed
212+
bool showConfigFlag = false;
213+
/// @brief Should the plaintext payload be emitted
214+
bool emitPlaintextPayloadFlag = false;
215+
/// @brief Should the input source be included in the payload
216+
bool includeSourceFlag = false;
217+
/// @brief Should the IR be compiled for the target
218+
bool compileTargetIRFlag = false;
219+
/// @brief Should target payload generation be bypassed
220+
bool bypassPayloadTargetCompilationFlag = false;
221+
/// @brief Pass plugin paths
222+
std::vector<std::string> passPlugins;
223+
/// @brief Dialect plugin paths
224+
std::vector<std::string> dialectPlugins;
48225
};
49226

50227
llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const QSSConfig &config);
@@ -61,6 +238,16 @@ void setContextConfig(mlir::MLIRContext *context, const QSSConfig &config);
61238
/// @param context The context to lookup the configuration for.
62239
llvm::Expected<const QSSConfig &> getContextConfig(mlir::MLIRContext *context);
63240

241+
/// @brief Load a dynamic dialect plugin
242+
/// @param pluginPath Path to the plugin
243+
/// @param registry Dialect registry to register the plugin dialect with
244+
mlir::LogicalResult loadDialectPlugin(const std::string &pluginPath,
245+
mlir::DialectRegistry &registry);
246+
247+
/// @brief Load a dynamic pass plugin
248+
/// @param pluginPath Path to the plugin
249+
mlir::LogicalResult loadPassPlugin(const std::string &pluginPath);
250+
64251
/// @brief A builder class for the QSSConfig. All standard configuration
65252
/// population should be completed through builders.
66253
class QSSConfigBuilder {
@@ -73,5 +260,17 @@ class QSSConfigBuilder {
73260
virtual ~QSSConfigBuilder() = default;
74261
};
75262

263+
/// Build the default tool configuration
264+
/// @brief Build the QSSConfig using the standard sources and assign to the
265+
/// supplied context.
266+
///
267+
/// The configuration precedence order is
268+
/// 1. Default values
269+
/// 2. Environment variables
270+
/// 3. CLI arguments.
271+
///
272+
/// @return The constructed configuration
273+
llvm::Expected<qssc::config::QSSConfig> buildToolConfig();
274+
76275
} // namespace qssc::config
77276
#endif // QSS_QSSCONFIG_H

0 commit comments

Comments
 (0)