ArkScript
A small, lisp-inspired, functional scripting language
IROptimizer.hpp
Go to the documentation of this file.
1/**
2 * @file IROptimizer.hpp
3 * @author Alexandre Plateau (lexplt.dev@gmail.com)
4 * @brief Optimize IR based on IR entity grouped by 2 (or more)
5 * @date 2024-10-11
6 *
7 * @copyright Copyright (c) 2024-2025
8 *
9 */
10#ifndef ARK_COMPILER_INTERMEDIATEREPRESENTATION_IROPTIMIZER_HPP
11#define ARK_COMPILER_INTERMEDIATEREPRESENTATION_IROPTIMIZER_HPP
12
13#include <Ark/Platform.hpp>
14#include <Ark/Logger.hpp>
17
18#include <span>
19#include <optional>
20#include <functional>
21
22namespace Ark::internal
23{
25 {
27 std::size_t offset;
28 };
29
30 class ARK_API IROptimizer final
31 {
32 public:
33 /**
34 * @brief Create a new IROptimizer
35 *
36 * @param debug debug level
37 */
38 explicit IROptimizer(unsigned debug);
39
40 /**
41 * @brief Turn a given IR into bytecode
42 *
43 * @param pages list of lists of IR entities generated by the compiler
44 * @param symbols symbol table generated by the compiler
45 * @param values value table generated by the compiler
46 */
47 void process(const std::vector<IR::Block>& pages, const std::vector<std::string>& symbols, const std::vector<ValTableElem>& values);
48
49 /**
50 * @brief Return the IR blocks (one per scope)
51 *
52 * @return const std::vector<Block>&
53 */
54 [[nodiscard]] const std::vector<IR::Block>& intermediateRepresentation() const noexcept;
55
56 private:
57 using Entities = std::span<const IR::Entity>;
58 using Condition_t = std::function<bool(const Entities)>;
59 using Replacement_t = std::function<IR::Entity(const Entities)>;
60
61 struct Rule
62 {
63 std::vector<Instruction> expected;
64 Condition_t condition; ///< Additional condition to match
65 Replacement_t createReplacement; ///< Create the replacement instructions from given context
66
67 constexpr static auto default_cond = [](const Entities) {
68 return true;
69 };
70
71 Rule(std::vector<Instruction>&& input, Instruction replacement, Condition_t&& cond = default_cond) :
72 expected(std::move(input)), condition(std::move(cond))
73 {
74 createReplacement = [replacement](const Entities e) {
75 return IR::Entity(replacement, e[0].primaryArg(), e[1].primaryArg());
76 };
77 }
78
79 Rule(std::vector<Instruction>&& input, Condition_t&& cond, Replacement_t&& repl) :
80 expected(std::move(input)), condition(std::move(cond)), createReplacement(std::move(repl))
81 {}
82
83 Rule(std::vector<Instruction>&& input, Replacement_t&& repl) :
84 expected(std::move(input)), condition(default_cond), createReplacement(std::move(repl))
85 {}
86 };
87
88 std::vector<Rule> m_ruleset;
89
91 std::vector<IR::Block> m_ir;
92 std::vector<std::string> m_symbols;
93 std::vector<ValTableElem> m_values;
94
95 [[nodiscard]] bool match(const std::vector<Instruction>& expected_insts, std::span<const IR::Entity> entities) const;
96 [[nodiscard]] bool canBeOptimizedSafely(std::span<const IR::Entity> entities, std::size_t window_size) const;
97 std::optional<EntityWithOffset> replaceWithRules(const std::vector<Rule>& rules, std::span<const IR::Entity> entities);
98
99 [[nodiscard]] bool isPositiveNumberInlinable(uint16_t id) const;
100 [[nodiscard]] uint16_t numberAsArg(uint16_t id) const;
101 };
102}
103
104#endif // ARK_COMPILER_INTERMEDIATEREPRESENTATION_IROPTIMIZER_HPP
An entity in the IR is a bundle of information.
Internal logger.
#define ARK_API
Definition Module.hpp:28
ArkScript configuration macros.
The basic value type handled by the compiler.
std::vector< ValTableElem > m_values
std::vector< IR::Block > m_ir
std::span< const IR::Entity > Entities
std::function< bool(const Entities)> Condition_t
std::vector< Rule > m_ruleset
std::function< IR::Entity(const Entities)> Replacement_t
std::vector< std::string > m_symbols
Instruction
The different bytecodes are stored here.
Condition_t condition
Additional condition to match.
Rule(std::vector< Instruction > &&input, Replacement_t &&repl)
Rule(std::vector< Instruction > &&input, Instruction replacement, Condition_t &&cond=default_cond)
Replacement_t createReplacement
Create the replacement instructions from given context.
Rule(std::vector< Instruction > &&input, Condition_t &&cond, Replacement_t &&repl)
std::vector< Instruction > expected