23 m_logger(
"IROptimizer", debug)
34 [](
const Entities entities,
const std::size_t start_idx) {
35 return Builtins::builtins[entities[3].primaryArg()].second.isFunction() && start_idx == 0;
41 [](
const Entities entities,
const std::size_t start_idx) {
42 return Builtins::builtins[entities[5].primaryArg()].second.isFunction() && start_idx == 0;
48 [](
const Entities entities,
const std::size_t start_idx) {
49 return Builtins::builtins[entities[7].primaryArg()].second.isFunction() && start_idx == 0;
249 for (
const auto& one : math_ops)
251 for (
const auto& two : math_ops)
253 for (
const auto& three : math_ops)
258 for (
const auto& one : math_ops)
260 for (
const auto& two : math_ops)
267 void IROptimizer::process(
const std::vector<IR::Block>& pages,
const std::vector<std::string>& symbols,
const std::vector<ValTableElem>& values)
273 for (
const auto& block : pages)
279 const std::size_t end = block.size();
285 block.begin() +
static_cast<IR::Block::difference_type
>(i),
289 if (maybe_compacted.has_value())
291 auto [entity, offset] = maybe_compacted.value();
292 current_block.emplace_back(entity);
297 current_block.emplace_back(block[i]);
311 bool IROptimizer::match(
const std::vector<Instruction>& expected_insts,
const std::span<const IR::Entity> entities)
const
313 if (expected_insts.size() > entities.size())
316 for (std::size_t i = 0; i < expected_insts.size(); ++i)
318 if (expected_insts[i] != entities[i].inst())
328 return std::ranges::none_of(
329 entities | std::ranges::views::take(window_size),
337 for (
const auto& [expected, condition, createReplacement] :
m_ruleset)
339 if (
match(expected, entities) && condition(entities, position_in_block))
341 const std::size_t window_size = expected.size();
345 auto output = createReplacement(entities);
347 if (
const auto it = std::ranges::find_if(entities, [](
const auto& entity) {
348 return entity.hasValidSourceLocation();
350 it != entities.end())
351 output.setSourceLocation(it->filename(), it->sourceLine());
364 const double val = std::get<double>(
m_values[
id].value);
367 static_cast<double>(
static_cast<long>(val)) == val;
379 static_cast<double>(
static_cast<long>(val)) == val;
388 const double val = std::get<double>(
m_values[
id].value);
389 return static_cast<double>(
static_cast<long>(val)) == val &&
390 static_cast<int>(val) == number;
397 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)
ARK_API const std::vector< std::pair< std::string, Value > > builtins
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