23 Pass(
"IROptimizer", debug)
34 [](
const Entities entities,
const std::size_t start_idx) {
35 return start_idx == 0 && entities[5].inst() ==
RET;
41 [](
const Entities entities,
const std::size_t start_idx) {
42 return start_idx == 0 && entities[7].inst() ==
RET;
48 [](
const Entities entities,
const std::size_t start_idx) {
49 return start_idx == 0 && entities[9].inst() ==
RET;
244 for (
const auto& one : math_ops)
246 for (
const auto& two : math_ops)
248 for (
const auto& three : math_ops)
253 for (
const auto& one : math_ops)
255 for (
const auto& two : math_ops)
262 void IROptimizer::process(
const std::vector<IR::Block>& pages,
const std::vector<std::string>& symbols,
const std::vector<ValTableElem>& values)
268 for (
const auto& block : pages)
274 const std::size_t end = block.size();
280 block.begin() +
static_cast<IR::Block::difference_type
>(i),
284 if (maybe_compacted.has_value())
286 auto [entity, offset] = maybe_compacted.value();
287 current_block.emplace_back(entity);
292 current_block.emplace_back(block[i]);
306 bool IROptimizer::match(
const std::vector<Instruction>& expected_insts,
const std::span<const IR::Entity> entities)
const
308 if (expected_insts.size() > entities.size())
312 while (i < expected_insts.size())
314 if (expected_insts[i] != entities[i].inst())
326 return std::ranges::none_of(
327 entities | std::ranges::views::take(window_size),
335 for (
const auto& [expected, condition, createReplacement] :
m_ruleset)
337 if (
match(expected, entities) && condition(entities, position_in_block))
339 const std::size_t window_size = expected.size();
343 auto output = createReplacement(entities);
345 if (
const auto it = std::ranges::find_if(entities, [](
const auto& entity) {
346 return entity.hasValidSourceLocation();
348 it != entities.end())
349 output.setSourceLocation(it->filename(), it->sourceLine());
362 const double val = std::get<double>(
m_values[
id].value);
365 static_cast<double>(
static_cast<long>(val)) == val;
377 static_cast<double>(
static_cast<long>(val)) == val;
386 const double val = std::get<double>(
m_values[
id].value);
387 return static_cast<double>(
static_cast<long>(val)) == val &&
388 static_cast<int>(val) == number;
395 return static_cast<uint16_t
>(std::get<double>(
m_values[
id].value));
Host the declaration of all the ArkScript builtins.
Optimize IR based on IR entity grouped by 2 (or more)
std::vector< ValTableElem > m_values
bool isSmallerNumberInlinable(uint16_t id) const
std::optional< EntityWithOffset > replaceWithRules(std::span< const IR::Entity > entities, const std::size_t position_in_block)
bool isPositiveNumberInlinable(uint16_t id) const
std::vector< IR::Block > m_ir
IROptimizer(unsigned debug)
Create a new IROptimizer.
uint16_t numberAsArg(uint16_t id) const
bool canBeOptimizedSafely(std::span< const IR::Entity > entities, std::size_t window_size) const
std::span< const IR::Entity > Entities
const std::vector< IR::Block > & intermediateRepresentation() const noexcept
Return the IR blocks (one per scope)
std::vector< Rule > m_ruleset
void process(const std::vector< IR::Block > &pages, const std::vector< std::string > &symbols, const std::vector< ValTableElem > &values)
Turn a given IR into bytecode.
std::vector< std::string > m_symbols
bool match(const std::vector< Instruction > &expected_insts, std::span< const IR::Entity > entities) const
uint16_t smallerNumberAsArg(uint16_t id) const
bool isNumberEqualTo(uint16_t id, int number) const
static Entity GotoWithArg(const Entity &label, Instruction inst, uint16_t primary_arg)
uint16_t primaryArg() const
void debug(const Logger::MessageAndLocation &data, Args &&... args)
Write a debug level log using fmtlib.
void traceStart(std::string &&trace_name)
An interface to describe compiler passes.
constexpr uint16_t MaxValueForSmallNumber
std::vector< Entity > Block
constexpr uint16_t MaxValueForDualArg
The maximum value an argument can have when an IR entity has two arguments.
IR::Entity fuseMathOps3(const std::span< const IR::Entity > e)
IR::Entity fuseMathOps2(const std::span< const IR::Entity > e)
@ GET_FIELD_FROM_SYMBOL_INDEX
@ APPEND_IN_PLACE_SYM_INDEX
@ EQ_SYM_INDEX_JUMP_IF_TRUE
@ LT_LEN_SYM_JUMP_IF_FALSE
@ CALL_BUILTIN_WITHOUT_RETURN_ADDRESS