ArkScript
A small, lisp-inspired, functional scripting language
IRInliner.hpp
Go to the documentation of this file.
1/**
2 * @file IRInliner.hpp
3 * @author Lexy Plateau (lexplt.dev@gmail.com)
4 * @brief Try to inline IR blocks
5 * @date 2026-07-11
6 *
7 * @copyright Copyright (c) 2026
8 *
9 */
10
11#ifndef ARK_COMPILER_INTERMEDIATEREPRESENTATION_IRINLINER_HPP
12#define ARK_COMPILER_INTERMEDIATEREPRESENTATION_IRINLINER_HPP
13
15#include <Ark/Compiler/Pass.hpp>
18
19#include <utility>
20#include <vector>
21#include <string>
22
23namespace Ark::internal
24{
25 struct BlockInfo
26 {
28 std::size_t addr;
29 std::string name;
30 std::optional<std::size_t> symbol_id;
31 };
32
34 {
35 std::string name;
36 std::size_t declarations_count;
37 std::size_t use_count;
38 };
39
40 class ARK_API IRInliner final : public Pass
41 {
42 public:
43 /**
44 * @brief Create a new IRInliner
45 *
46 * @param debug debug level
47 */
48 explicit IRInliner(unsigned debug);
49
50 /**
51 * @brief Attempt to inline IR blocks to avoid function calls when possible
52 *
53 * @param pages list of lists of IR entities generated by the compiler
54 * @param symbols symbol table generated by the compiler
55 * @param values value table generated by the compiler
56 * @param last_label last label generated by the AST lowerer
57 */
58 void process(const std::vector<IR::Block>& pages, const std::vector<std::string>& symbols, const std::vector<ValTableElem>& values, IR::label_t last_label);
59
60 /**
61 * @brief Return the IR blocks (one per scope)
62 *
63 * @return const std::vector<Block>&
64 */
65 [[nodiscard]] const std::vector<IR::Block>& intermediateRepresentation() const noexcept;
66
67 private:
68 std::vector<IR::Block> m_ir;
69 std::vector<std::string> m_symbols;
70 std::vector<ValTableElem> m_values;
71 std::vector<BlockInfo> m_funcs;
72 std::unordered_map<long, SymbolData> m_symbols_data;
74
75 enum class CallKind
76 {
77 Symbol,
79 };
80
81 /**
82 * @brief Check if a block can be inlined in another one
83 *
84 * @param candidate block to inline
85 * @param source where the inlining will take place
86 * @param argc argument count in source to candidate
87 * @return true if the candidate can be inlined
88 */
89 [[nodiscard]] static bool canBeInlined(const IR::Block& candidate, const IR::Block& source, std::size_t argc) noexcept;
90
91 /**
92 * @brief See if a block can be inlined in the current call site
93 *
94 * @param kind kind of call instruction being used (by symbol or constant)
95 * @param pages
96 * @param maybe_id optional identifier of a block (constant id or symbol id)
97 * @param current current block where inlining could take place
98 * @param argc argument count in source to candidate
99 * @return std::optional<BlockInfo> candidate to inlining
100 */
101 [[nodiscard]] std::optional<BlockInfo> blockToInlineInCall(CallKind kind, const std::vector<IR::Block>& pages, std::optional<uint16_t> maybe_id, const IR::Block& current, std::size_t argc) const noexcept;
102
103 /**
104 * @brief Check if an IR block represents a builtin proxy, and return its CALL instruction if it is
105 *
106 * @param block IR block
107 * @return std::optional<IR::Entity>
108 */
109 [[nodiscard]] static std::optional<IR::Entity> isBuiltinProxy(const IR::Block& block);
110
111 /**
112 * @brief Perform the inlining
113 *
114 * @param inlinee IR block to inline
115 * @param destination new IR block to write instructions to
116 */
117 void inlineBlock(const IR::Block& inlinee, IR::Block& destination);
118
119 /**
120 * @brief Extract metadata from the IR entities pages, to have a name, constant id, and potentially symbol id per page
121 *
122 * @param pages pages of IR entities
123 */
124 void extractPagesMetadata(const std::vector<IR::Block>& pages);
125
126 /**
127 * @brief Search for a block by one of its IDs
128 *
129 * @param kind kind of call instruction being used (by symbol or constant)
130 * @param id
131 * @return std::optional<BlockInfo>
132 */
133 [[nodiscard]] std::optional<BlockInfo> findBlockBy(CallKind kind, uint16_t id) const noexcept;
134 };
135}
136
137#endif // ARK_COMPILER_INTERMEDIATEREPRESENTATION_IRINLINER_HPP
An entity in the IR is a bundle of information.
CallKind
Definition Formatter.hpp:16
#define ARK_API
Definition Module.hpp:22
Interface for a compiler pass.
ArkScript configuration macros.
The basic value type handled by the compiler.
std::vector< IR::Block > m_ir
Definition IRInliner.hpp:68
IR::label_t m_current_label
Definition IRInliner.hpp:73
std::vector< ValTableElem > m_values
Definition IRInliner.hpp:70
std::vector< BlockInfo > m_funcs
Definition IRInliner.hpp:71
std::vector< std::string > m_symbols
Definition IRInliner.hpp:69
std::unordered_map< long, SymbolData > m_symbols_data
Definition IRInliner.hpp:72
An interface to describe compiler passes.
Definition Pass.hpp:24
std::size_t label_t
Definition Entity.hpp:35
std::optional< std::size_t > symbol_id
Definition IRInliner.hpp:30
Block of IR entities, with attached metadata.
Definition Entity.hpp:241
std::size_t declarations_count
Definition IRInliner.hpp:36