7#include <initializer_list>
15#include <ankerl/unordered_dense.h>
27using Normalizers = ankerl::unordered_dense::map<flags_t, NormalizeFn>;
30using Flags2Phases = ankerl::unordered_dense::map<flags_t, std::function<std::unique_ptr<Phase>(
World&)>>;
54#define MIM_PLUGIN_SYM(f) \
55 PluginSym { #f, (void*)&f }
64inline std::optional<std::string_view> arg_split(std::string_view arg, std::string_view key) {
65 if (!arg.starts_with(key))
return {};
66 auto val = arg.substr(key.size());
67 if (val.empty())
return val;
68 if (val.front() ==
'=')
return val.substr(1);
74template<
class...
Keys>
75std::optional<std::string_view>
arg_value(fe::View<std::string> args,
Keys... keys) {
76 std::optional<std::string_view> res;
77 for (std::string_view arg : args)
78 for (std::string_view key : {std::string_view(keys)...})
79 if (
auto val = detail::arg_split(arg, key); val && !val->empty()) res = val;
84inline std::optional<bool>
arg_bool(fe::View<std::string> args,
85 std::initializer_list<std::string_view> on,
86 std::initializer_list<std::string_view> off) {
87 std::optional<bool> res;
88 for (std::string_view arg : args) {
90 if (arg == key) res =
true;
92 if (arg == key) res =
false;
98template<
class...
Keys>
100 for (std::string_view arg : args)
101 for (std::string_view key : {std::string_view(keys)...})
102 if (arg == key)
return true;
113 : name_(std::move(
name)) {}
115 std::string&
name() {
return name_; }
120 if (name_.empty())
return nullptr;
121 if (name_ ==
"-")
return &std::cout;
122 if (!ofs_.is_open()) {
124 if (!ofs_) fe::throwf(
"cannot open output file `{}`", name_);
142 auto cmp = std::tie(
major,
minor) <=> std::tie(other.major, other.minor);
143 if (cmp != 0)
return cmp;
145 return std::strcmp(
suffix, other.suffix) <=> 0;
150 return major == other.major &&
minor == other.minor && std::strcmp(
suffix, other.suffix) == 0;
161 Version { MIM_VER_MAJOR, MIM_VER_MINOR, MIM_VER_SUFFIX, MIM_GIT_HASH }
166 using Handle = std::unique_ptr<void, void (*)(
void*)>;
196#ifdef MIM_STATIC_PLUGINS
197# define MIM_PLUGIN_ENTRY_NAME(p) mim_get_plugin_##p
199# define MIM_PLUGIN_ENTRY_NAME(p) mim_get_plugin
206#define MIM_PLUGIN_ENTRY(p) \
207 static void mim_plugin_##p(mim::Plugin&); \
208 extern "C" MIM_EXPORT mim::Plugin MIM_PLUGIN_ENTRY_NAME(p)() { \
209 auto plugin = mim::Plugin{}; \
211 plugin.version = MIM_VERSION; \
212 mim_plugin_##p(plugin); \
215 static void mim_plugin_##p([[maybe_unused]] mim::Plugin& plugin)
244 static std::optional<plugin_t>
mangle(std::string_view plugin);
283 template<
class Id>
static constexpr size_t Num = size_t(-1);
285 template<
class Id>
static consteval size_t num () {
return Num <Id>; }
294template<>
struct std::formatter<
mim::Version> : fe::ostream_formatter {};
Some "global" variables needed all over the place.
std::string & name()
Bound to a fe::Cli option, e.g. --output-mim.
std::ostream * os()
The stream to write to; nullptr if this output was not requested, std::cout for "-".
A Phase performs one self-contained task over the whole World.
The World represents the whole program and manages creation of MimIR nodes (Defs).
const char * descr
What it does; one sentence of Markdown, but no links: the terminal help prints it as is.
bool arg_flag(fe::View< std::string > args, Keys... keys)
Whether any of keys occurs.
ankerl::unordered_dense::map< flags_t, NormalizeFn > Normalizers
mim::Plugin mim_get_plugin()
const char * name
Name of the symbol, e.g. "mim_ll_convert".
fe::SymTab< ast::Tok::Tag, ast::Num_Keys+ast::Num_Subst > Keys
The reserved words the ast::Lexer looks up, keyed by the Sym it has just interned.
const char * descr
What it does; one sentence of Markdown, but no links: the terminal help prints it as is.
const char * name
Name of the variable, e.g. "CUDA_HOME".
void * ptr
Address of the symbol.
const char * syntax
How to spell the argument, e.g. "o=<file>, output=<file>".
std::optional< bool > arg_bool(fe::View< std::string > args, std::initializer_list< std::string_view > on, std::initializer_list< std::string_view > off)
An on key ↦ true, an off key ↦ false; std::nullopt if neither occurs.
std::optional< std::string_view > arg_value(fe::View< std::string > args, Keys... keys)
Value of <key>=<value>; std::nullopt if none of keys carries one.
ankerl::unordered_dense::map< flags_t, std::function< std::unique_ptr< Phase >(World &)> > Flags2Phases
Maps an axiom of a Phase to a function that creates one.
One -X <plugin>:<arg> a Plugin understands; see Arguments.
One environment variable a Plugin reads; see Environment Variables.
One symbol a Plugin offers to other Plugins; see Driver::get_fun_ptr.
static constexpr flags_t flags(plugin_t p, tag_t t, sub_t s=0)
Assembles the full flags from its plugin, tag, and sub fields.
static constexpr plugin_t Global_Plugin
static std::string demangle(plugin_t plugin)
Reverts an Axm::mangled plugin back to its name; never longer than Annex::Max_Plugin_Size.
static std::optional< plugin_t > mangle(std::string_view plugin)
Mangles s into a dense 48-bit representation.
static constexpr tag_t flags2tag(flags_t f)
Yields the tag part of the name as integer.
static constexpr size_t Max_Plugin_Size
static constexpr sub_t flags2sub(flags_t f)
Yields the sub part of the name as integer.
static constexpr plugin_t flags2plugin(flags_t f)
static consteval size_t num()
static constexpr size_t Num
Number of Axm::subtags.
static consteval flags_t base()
static constexpr flags_t Base
static constexpr flags_t flags2base(flags_t f)
Includes Axm::plugin() and Axm::tag() but not Axm::sub.
Basic info and registration function pointer to be returned from a specific plugin.
const PluginEnv * envs
The environment variables this Plugin reads; see PluginEnv.
size_t num_syms
Number of Plugin::syms.
size_t num_envs
Number of Plugin::envs.
size_t num_args
Number of Plugin::args.
const PluginSym * syms
The symbols other Plugins may look up; see PluginSym.
const PluginArg * args
The -X arguments this Plugin understands; see PluginArg.
void(*) register_normalizers(Normalizers &)
Callback for registering the mapping from axm ids to normalizer functions in the given normalizers ma...
std::unique_ptr< void, void(*)(void *)> Handle
const char * name
Name of the Plugin.
void(*) register_phases(Flags2Phases &)
Callback for registering the Plugin's callbacks for Phases.
Version version
Version of the Plugin.
friend std::ostream & operator<<(std::ostream &os, const Version &v)
constexpr bool operator==(const Version &other) const noexcept
Compares major/minor/suffix, ignores hash.
constexpr auto operator<=>(const Version &other) const noexcept
Compares major/minor/suffix, ignores hash.