Thorin 1.9.0
The Higher ORder INtermediate representation
Loading...
Searching...
No Matches
plugin.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <string>
5#include <vector>
6
7#include <absl/container/btree_map.h>
8#include <absl/container/flat_hash_map.h>
9
10#include "thorin/config.h"
11#include "thorin/def.h"
12
13namespace thorin {
14
15class PipelineBuilder;
16
17/// @name Plugin Interface
18///@{
19using Normalizers = absl::flat_hash_map<flags_t, NormalizeFn>;
20/// `axiom ↦ (pipeline part) × (axiom application) → ()` <br/>
21/// The function should inspect App%lication to construct the Pass/Phase and add it to the pipeline.
22using Passes = absl::flat_hash_map<flags_t, std::function<void(World&, PipelineBuilder&, const Def*)>>;
23using Backends = absl::btree_map<std::string, void (*)(World&, std::ostream&)>;
24///@}
25
26extern "C" {
27/// Basic info and registration function pointer to be returned from a specific plugin.
28/// Use Driver to load such a plugin.
29struct Plugin {
30 using Handle = std::unique_ptr<void, void (*)(void*)>;
31
32 const char* plugin_name; ///< Name of the Plugin.
33
34 /// Callback for registering the mapping from axiom ids to normalizer functions in the given @p normalizers map.
35 void (*register_normalizers)(Normalizers& normalizers);
36 /// Callback for registering the Plugin's callbacks for the pipeline extension points.
37 void (*register_passes)(Passes& passes);
38 /// Callback for registering the mapping from backend names to emission functions in the given @p backends map.
39 void (*register_backends)(Backends& backends);
40};
41
42/// @name Plugin Interface
43///@{
44/// @see Plugin
45
46/// To be implemented and exported by a plugin.
47/// @returns a filled Plugin.
49///@}
50}
51
52/// Holds info about an entity defined within a Plugin (called *Annex*).
53struct Annex {
55 : plugin(plugin)
56 , tag(tag)
57 , tag_id(tag_id) {}
58
59 Sym plugin;
60 Sym tag;
62 std::deque<std::deque<Sym>> subs; ///< List of subs which is a list of aliases.
64 bool pi = false;
65
66 /// @name Mangling Plugin Name
67 ///@{
68 static constexpr size_t Max_Plugin_Size = 8;
69 static constexpr plugin_t Global_Plugin = 0xffff'ffff'ffff'0000_u64;
70
71 /// Mangles @p s into a dense 48-bit representation.
72 /// The layout is as follows:
73 /// ```
74 /// |---7--||---6--||---5--||---4--||---3--||---2--||---1--||---0--|
75 /// 7654321076543210765432107654321076543210765432107654321076543210
76 /// Char67Char66Char65Char64Char63Char62Char61Char60|---reserved---|
77 /// ```
78 /// The `reserved` part is used for the Axiom::tag and the Axiom::sub.
79 /// Each `Char6x` is 6-bit wide and hence a plugin name has at most Axiom::Max_Plugin_Size = 8 chars.
80 /// It uses this encoding:
81 /// | `Char6` | ASCII |
82 /// |---------|---------|
83 /// | 1: | `_` |
84 /// | 2-27: | `a`-`z` |
85 /// | 28-53: | `A`-`Z` |
86 /// | 54-63: | `0`-`9` |
87 /// The 0 is special and marks the end of the name if the name has less than 8 chars.
88 /// @returns `std::nullopt` if encoding is not possible.
89 static std::optional<plugin_t> mangle(Sym s);
90
91 /// Reverts an Axiom::mangle%d string to a Sym.
92 /// Ignores lower 16-bit of @p u.
93 static Sym demangle(World&, plugin_t u);
94
95 static std::array<Sym, 3> split(World&, Sym);
96 ///@}
97
98 /// @name Annex Name
99 /// @anchor annex_name
100 ///@{
101 /// Anatomy of an Annex name:
102 /// ```
103 /// %plugin.tag.sub
104 /// | 48 | 8 | 8 | <-- Number of bits per field.
105 /// ```
106 /// * Def::name() retrieves the full name as Sym.
107 /// * Def::flags() retrieves the full name as Axiom::mangle%d 64-bit integer.
108
109 /// Yields the `plugin` part of the name as integer.
110 /// It consists of 48 relevant bits that are returned in the highest 6 bytes of a 64-bit integer.
111 static plugin_t flags2plugin(flags_t f) { return f & Global_Plugin; }
112
113 /// Yields the `tag` part of the name as integer.
114 static tag_t flags2tag(flags_t f) { return tag_t((f & 0x0000'0000'0000'ff00_u64) >> 8_u64); }
115
116 /// Yields the `sub` part of the name as integer.
117 static sub_t flags2sub(flags_t f) { return sub_t(f & 0x0000'0000'0000'00ff_u64); }
118
119 /// Includes Axiom::plugin() and Axiom::tag() but **not** Axiom::sub.
120 static flags_t flags2base(flags_t f) { return f & ~0xff_u64; }
121 ///@}
122
123 /// @name Helpers for Matching
124 ///@{
125 /// These are set via template specialization.
126
127 /// Number of Axiom::sub%tags.
128 template<class Id> static constexpr size_t Num = size_t(-1);
129
130 /// @see Axiom::base.
131 template<class Id> static constexpr flags_t Base = flags_t(-1);
132 ///@}
133};
134
135} // namespace thorin
Base class for all Defs.
Definition def.h:222
The World represents the whole program and manages creation of Thorin nodes (Defs).
Definition world.h:35
#define THORIN_EXPORT
Definition config.h:16
Definition cfg.h:11
u8 sub_t
Definition types.h:49
absl::flat_hash_map< flags_t, std::function< void(World &, PipelineBuilder &, const Def *)> > Passes
axiom ↦ (pipeline part) × (axiom application) → () The function should inspect Application to const...
Definition plugin.h:22
THORIN_EXPORT thorin::Plugin thorin_get_plugin()
To be implemented and exported by a plugin.
absl::flat_hash_map< flags_t, NormalizeFn > Normalizers
Definition plugin.h:19
absl::btree_map< std::string, void(*)(World &, std::ostream &)> Backends
Definition plugin.h:23
u8 tag_t
Definition types.h:48
u64 plugin_t
Definition types.h:47
u64 flags_t
Definition types.h:46
Holds info about an entity defined within a Plugin (called Annex).
Definition plugin.h:53
flags_t tag_id
Definition plugin.h:61
Annex(Sym plugin, Sym tag, flags_t tag_id)
Definition plugin.h:54
static tag_t flags2tag(flags_t f)
Yields the tag part of the name as integer.
Definition plugin.h:114
static constexpr plugin_t Global_Plugin
Definition plugin.h:69
static sub_t flags2sub(flags_t f)
Yields the sub part of the name as integer.
Definition plugin.h:117
static Sym demangle(World &, plugin_t u)
Reverts an Axiom::mangled string to a Sym.
Definition plugin.cpp:37
static plugin_t flags2plugin(flags_t f)
Yields the plugin part of the name as integer.
Definition plugin.h:111
static flags_t flags2base(flags_t f)
Includes Axiom::plugin() and Axiom::tag() but not Axiom::sub.
Definition plugin.h:120
static constexpr size_t Num
Number of Axiom::subtags.
Definition plugin.h:128
static std::optional< plugin_t > mangle(Sym s)
Mangles s into a dense 48-bit representation.
Definition plugin.cpp:9
static constexpr flags_t Base
Definition plugin.h:131
static std::array< Sym, 3 > split(World &, Sym)
Definition plugin.cpp:58
static constexpr size_t Max_Plugin_Size
Definition plugin.h:68
Sym normalizer
Definition plugin.h:63
std::deque< std::deque< Sym > > subs
List of subs which is a list of aliases.
Definition plugin.h:62
Basic info and registration function pointer to be returned from a specific plugin.
Definition plugin.h:29
const char * plugin_name
Name of the Plugin.
Definition plugin.h:32
void(* register_backends)(Backends &backends)
Callback for registering the mapping from backend names to emission functions in the given backends m...
Definition plugin.h:39
void(* register_normalizers)(Normalizers &normalizers)
Callback for registering the mapping from axiom ids to normalizer functions in the given normalizers ...
Definition plugin.h:35
void(* register_passes)(Passes &passes)
Callback for registering the Plugin's callbacks for the pipeline extension points.
Definition plugin.h:37
std::unique_ptr< void, void(*)(void *)> Handle
Definition plugin.h:30