51#ifndef COMPILER_IR_MODEL_H
52#define COMPILER_IR_MODEL_H
74 return std::numeric_limits<size_t>::max();
141 return "FunctionRef";
162 return "Unreachable";
282 template <
typename T,
typename...
Args>
289 [](
void *raw)
noexcept
291 static_cast<T *
>(raw)->~
T();
299 for (
size_t i =
owned.size(); i > 0; --i)
301 auto &[ptr, destroy] =
owned.access(i - 1);
302 if (destroy !=
nullptr and ptr !=
nullptr)
318namespace Compiler_IR_Detail {
321 return "B" + std::to_string(
id);
327 for (
size_t i = 0; i <
ids.size(); ++i)
328 if (
ids.access(i) ==
id)
335 return "v" + std::to_string(
id);
340 return "s" + std::to_string(
id);
345 return "g" + std::to_string(
id);
350 return "f" + std::to_string(
id);
355 const std::string
padding(indent,
' ');
357 while (begin < text.size())
359 const auto end = text.find(
'\n', begin);
360 if (end == std::string::npos)
367 out <<
padding << text.substr(begin, end - begin) <<
'\n';
381 auto fail = [&
report](
const std::string &msg)
384 report.errors.append(msg);
387 if (function.
blocks.is_empty())
389 fail(
"IR function '" + function.
name +
"' has no blocks");
394 fail(
"IR function '" + function.
name +
"' has invalid entry block");
396 fail(
"IR function '" + function.
name +
"' has invalid exit block");
400 for (
size_t i = 0; i < function.
blocks.size(); ++i)
402 const auto &block = function.
blocks.access(i);
404 fail(
"IR function '" + function.
name +
"' has mismatched block id at "
408 +
"' is unterminated");
421 + function.
name +
"' must define a result");
425 fail(
"IR instruction references invalid local slot in function '" + function.
name +
"'");
427 and (module ==
nullptr or inst.global_slot_id >= module->global_slots.size()))
428 fail(
"IR instruction references invalid global slot in function '" + function.
name
431 and (module ==
nullptr or inst.function_id >= module->functions.size()))
432 fail(
"IR instruction references invalid function id in function '" + function.
name
441 +
" must have one successor");
446 +
" must reference a condition value");
449 +
" must have two successors");
454 +
" must reference a return value");
457 +
" must point to the exit block");
460 +
" must point to exit block "
465 fail(
"Only the canonical exit block may use Exit in function '" + function.
name +
"'");
477 if (succ >= function.
blocks.size())
484 for (
size_t i = 0; i < function.
blocks.size(); ++i)
491 const auto current =
worklist.pop();
495 const auto &block = function.
blocks.access(current);
504 for (
size_t i = 0; i < function.
blocks.size(); ++i)
507 + function.
name +
"' is unreachable from entry");
521 for (
size_t i = 0; i < child.errors.size(); ++i)
522 report.errors.append(child.errors.access(i));
523 for (
size_t i = 0; i < child.warnings.size(); ++i)
524 report.warnings.append(child.warnings.access(i));
527 for (
size_t i = 0; i <
module.functions.size(); ++i)
540 std::ostringstream
out;
541 if (function ==
nullptr)
543 out <<
"<null-ir-function>\n";
547 out <<
"IRFunction(" << function->
name <<
")";
548 if (types !=
nullptr and function->
type_id != 0)
549 out <<
": " << types->to_string(function->
type_id);
557 for (
size_t i = 0; i < function->
local_slots.size(); ++i)
562 if (types !=
nullptr and slot.type_id != 0)
563 out <<
": " << types->to_string(
slot.type_id);
568 for (
size_t i = 0; i < function->
blocks.size(); ++i)
570 const auto &block = function->
blocks.access(i);
574 out <<
" Instructions: <none>\n";
577 out <<
" Instructions:\n";
582 if (
inst.result_id != 0)
608 out <<
'(' <<
inst.text <<
')';
610 if (
not inst.operands.is_empty())
613 for (
size_t k = 0;
k <
inst.operands.size(); ++
k)
622 if (types !=
nullptr and inst.type_id != 0)
623 out <<
" : " << types->to_string(
inst.type_id);
635 out <<
" Successors:";
642 out << (j == 0 ?
" " :
", ");
656 std::ostringstream
out;
657 if (module ==
nullptr)
659 out <<
"<null-ir-module>\n";
666 out <<
" Globals:\n";
667 for (
size_t i = 0; i <
module->global_slots.size(); ++i)
669 const auto &
slot =
module->global_slots.access(i);
671 if (types !=
nullptr and slot.type_id != 0)
672 out <<
": " << types->to_string(
slot.type_id);
677 for (
size_t i = 0; i <
module->functions.size(); ++i)
Reusable typed high-level IR model independent from any concrete frontend.
Memory arena for fast bulk allocations.
Exception handling system with formatted messages for Aleph-w.
#define ah_runtime_error_unless(C)
Throws std::runtime_error if condition does NOT hold.
size_t size_t int32_t * out
Arena allocator for fast bump-pointer allocation.
void reset() noexcept
Reset arena, making all memory available again.
static constexpr size_t DEFAULT_SIZE
Default arena size (1 MB).
Arena-backed ownership context for IR nodes.
Compiler_IR_Context(const Compiler_IR_Context &)=delete
~Compiler_IR_Context() noexcept
T * make(Args &&...args)
Allocates and constructs one IR object.
void reset() noexcept
Destroys all tracked objects and rewinds the arena.
DynArray< Owned_Object > owned
Compiler_IR_Context(const size_t arena_size=AhArenaAllocator::DEFAULT_SIZE)
Constructs an IR context with arena_size bytes.
Compiler_IR_Context & operator=(const Compiler_IR_Context &)=delete
Context owning all compiler type nodes.
size_t size() const noexcept
Return the current dimension of array.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
T & append()
Allocate a new entry to the end of array.
bool is_empty() const noexcept
Return true if the array is empty.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
std::string local_slot_name(const Compiler_IR_Local_Slot_Id id)
std::string value_name(const Compiler_IR_Value_Id id)
void append_indented_text(std::ostream &out, const std::string &text, const size_t indent)
std::string function_name(const Compiler_IR_Function_Id id)
bool contains_block_id(const DynArray< Compiler_IR_Block_Id > &ids, const Compiler_IR_Block_Id id) noexcept
std::string block_name(const Compiler_IR_Block_Id id)
std::string global_slot_name(const Compiler_IR_Global_Slot_Id id)
Main namespace for Aleph-w library functions.
Compiler_IR_Instruction_Kind
Instruction kinds supported by the MVP IR.
const char * compiler_ir_terminator_kind_name(const Compiler_IR_Terminator_Kind kind) noexcept
Stable debug name for one terminator kind.
@ Unreachable
Marks code paths that should never be executed (e.g., after a break).
@ Exit
Sentinel terminator for the canonical exit block.
@ Binary
dst <- op(lhs, rhs)
@ Return
Return one register value.
@ Call
dst <- callee(args...)
@ Branch
pc <- condition ? true_target : false_target
size_t Compiler_IR_Function_Id
@ Function_Ref
Reference to one bytecode function in the current module.
std::string compiler_dump_ir_module(const Compiler_IR_Module *module, const Compiler_Type_Context *types=nullptr)
Dumps all lowered IR in one module deterministically.
const char * compiler_operator_name(const Compiler_Operator_Kind kind) noexcept
Returns a stable debug name for one operator kind.
Compiler_IR_Validation_Report validate_ir_module(const Compiler_IR_Module &module)
Validates all functions in one lowered IR module.
and
Check uniqueness with explicit hash + equality functors.
std::decay_t< typename HeadC::Item_Type > T
size_t Compiler_IR_Value_Id
constexpr size_t compiler_ir_invalid_id() noexcept
Returns the sentinel invalid IR id.
size_t Compiler_IR_Block_Id
const char * compiler_ir_slot_kind_name(const Compiler_IR_Slot_Kind kind) noexcept
Stable debug name for one slot kind.
Itor3 merge(Itor1 source1Beg, Itor1 source1End, Itor2 source2Beg, Itor2 source2End, Itor3 destBeg)
Merge two sorted ranges.
size_t Compiler_IR_Global_Slot_Id
Compiler_IR_Validation_Report validate_ir_function(const Compiler_IR_Function &function, const Compiler_IR_Module *module=nullptr)
Validates one lowered IR function structurally.
const char * compiler_ir_instruction_kind_name(const Compiler_IR_Instruction_Kind kind) noexcept
Stable debug name for one instruction kind.
Compiler_IR_Terminator_Kind
Terminator kinds supported by the MVP IR.
Compiler_Operator_Kind
Stable operator kinds shared by reusable compiler layers.
size_t Compiler_IR_Local_Slot_Id
Compiler_IR_Slot_Kind
Storage-space classification for slots.
std::string compiler_dump_ir_function(const Compiler_IR_Function *function, const Compiler_IR_Module *module=nullptr, const Compiler_Type_Context *types=nullptr)
Dumps one lowered IR function deterministically.
One basic block of IR instructions.
std::string label
Deterministic debug label.
Compiler_IR_Terminator terminator
Explicit block terminator.
DynArray< Compiler_IR_Block_Id > predecessors
Predecessor block ids.
DynArray< Compiler_IR_Instruction > instructions
Linear instruction list.
Source_Span span
Aggregate span covered by instructions and terminator.
bool is_terminated() const noexcept
Returns whether the block already has a terminator.
void(* destroy)(void *) noexcept
Lowered IR for one function or top-level body.
Compiler_IR_Value_Id next_value_id
Next value id to allocate while lowering.
DynArray< Compiler_IR_Block > blocks
Basic blocks in deterministic id order.
bool is_top_level() const noexcept
Returns whether this IR function represents the top-level body.
std::string name
Debug or source-level name.
Compiler_Type_Id type_id
Full function type, when known.
Compiler_IR_Block_Id exit_block
Canonical exit block.
Compiler_IR_Block_Id entry_block
Canonical entry block.
DynArray< Compiler_IR_Slot > local_slots
Parameter/local slots in stable order.
const Compiler_HIR_Function * source_function
Originating HIR function, or nullptr for top-level.
Source_Span span
Source span of the function/body.
One instruction producing an optional explicit result value.
std::string text
Constant spelling or debug payload.
bool bool_value
Decoded boolean payload for bool constants.
Compiler_IR_Instruction_Kind kind
Instruction category.
Compiler_IR_Value_Id result_id
Produced value id, or 0 for void instructions.
DynArray< Compiler_IR_Value_Id > operands
Input values in deterministic order.
Source_Span span
Source region associated with the instruction.
Compiler_Type_Id type_id
Result type or stored value type.
Compiler_Operator_Kind op
Unary/binary operator kind, when relevant.
Compiler_IR_Local_Slot_Id local_slot_id
Referenced local/parameter slot, when relevant.
Compiler_IR_Function_Id function_id
Referenced function id, when relevant.
Compiler_IR_Global_Slot_Id global_slot_id
Referenced global slot, when relevant.
Lowered IR module with shared global slots and functions.
DynArray< Compiler_IR_Slot > global_slots
Module-wide global slots.
DynArray< Compiler_IR_Function * > functions
Lowered non-top-level functions.
Compiler_IR_Function * top_level
Optional top-level body lowered as a function.
One storage slot used by the IR.
Source_Span span
Declaration span.
std::string name
Debug name of the slot.
Compiler_Type_Id type_id
Declared or inferred slot type.
Compiler_IR_Slot_Kind kind
Slot storage category.
Explicit terminator for one IR basic block.
Compiler_IR_Terminator_Kind kind
Terminator category.
DynArray< Compiler_IR_Block_Id > successors
Successor blocks in deterministic order.
Source_Span span
Source region associated with the terminator.
Compiler_IR_Value_Id condition_value
Branch condition value, if any.
Compiler_IR_Value_Id return_value
Return value, if any.
Structural validation report for one IR module or function.
bool valid
Whether all hard validation checks passed.
DynArray< std::string > warnings
Non-fatal findings such as unreachable blocks.
DynArray< std::string > errors
Hard validation failures.
Compiler_SSA_Block_Id id
Dense SSA block id.
DynArray< Compiler_SSA_Instruction > instructions
Linear SSA instruction list.
std::string label
Deterministic debug label.
Compiler_SSA_Terminator terminator
Explicit block terminator.
Compiler_SSA_Value_Id return_value
Return value, when relevant.
DynArray< Compiler_SSA_Block_Id > successors
Successors in deterministic order.
Compiler_IR_Terminator_Kind kind
Terminator category.
Compiler_SSA_Value_Id condition_value
Branch condition, when relevant.
Represents a missing value.
Half-open byte range inside a source file.
Lazy and scalable dynamic array implementation.