36#include <gtest/gtest.h>
59 function.
name =
"add_one";
66 param.kind = Compiler_IR_Slot_Kind::Parameter;
72 local.
kind = Compiler_IR_Slot_Kind::Local;
78 entry.
label =
"entry";
87 store.
kind = Compiler_IR_Instruction_Kind::Store;
93 load_x.
kind = Compiler_IR_Instruction_Kind::Load;
105 add.kind = Compiler_IR_Instruction_Kind::Binary;
107 add.op = Compiler_Operator_Kind::Plus;
108 add.operands.append(2);
109 add.operands.append(3);
117 exit.predecessors.append(0);
119 function.
blocks.append(entry);
129 function.
name =
"choose";
136 flag.
kind = Compiler_IR_Slot_Kind::Parameter;
142 value.kind = Compiler_IR_Slot_Kind::Local;
143 value.name =
"value";
148 entry.
label =
"entry";
151 zero.
kind = Compiler_IR_Instruction_Kind::Constant;
174 exit.predecessors.append(3);
181 one.
kind = Compiler_IR_Instruction_Kind::Constant;
192 then_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
206 join_block.terminator.kind = Compiler_IR_Terminator_Kind::Return;
217 two.
kind = Compiler_IR_Instruction_Kind::Constant;
228 else_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
232 function.
blocks.append(entry);
247 global.kind = Compiler_IR_Slot_Kind::Global;
249 module.global_slots.append(global);
252 module.functions.append(function);
256 top->name =
"<top-level>";
257 top->entry_block = 0;
259 top->next_value_id = 3;
263 entry.
label =
"entry";
278 call.
kind = Compiler_IR_Instruction_Kind::Call;
294 exit.predecessors.append(0);
296 top->blocks.append(entry);
297 top->blocks.append(
exit);
298 module.top_level = top;
310 module.functions.append(&source);
314 const auto & function = *
bytecode->functions.access(0);
319 ASSERT_EQ(function.constants.size(), 1u);
320 EXPECT_EQ(function.constants.access(0).kind,
321 Compiler_Bytecode_Constant_Kind::Integer);
322 EXPECT_EQ(function.constants.access(0).integer_value, 1);
325 EXPECT_EQ(function.code.access(0).opcode,
326 Compiler_Bytecode_Opcode::Load_Constant);
327 EXPECT_EQ(function.code.access(1).opcode,
328 Compiler_Bytecode_Opcode::Store_Local);
329 EXPECT_EQ(function.code.access(2).opcode,
330 Compiler_Bytecode_Opcode::Load_Local);
331 EXPECT_EQ(function.code.access(4).opcode,
332 Compiler_Bytecode_Opcode::Binary);
333 EXPECT_EQ(function.code.access(5).opcode,
334 Compiler_Bytecode_Opcode::Return);
344 module.functions.append(&source);
347 const auto & function = *
bytecode->functions.access(0);
358 const auto &
then_jump = function.code.access(function.
blocks.access(2).end_pc - 1);
368 auto module = make_module_with_top_level_call();
377 const auto & top = *
bytecode->top_level;
379 EXPECT_EQ(top.code.access(0).opcode, Compiler_Bytecode_Opcode::Load_Function);
380 EXPECT_EQ(top.code.access(1).opcode, Compiler_Bytecode_Opcode::Load_Constant);
381 EXPECT_EQ(top.code.access(2).opcode, Compiler_Bytecode_Opcode::Call);
382 EXPECT_EQ(top.code.access(3).opcode, Compiler_Bytecode_Opcode::Store_Global);
383 EXPECT_EQ(top.code.access(4).opcode, Compiler_Bytecode_Opcode::Jump);
390 delete module.functions.access(0);
391 delete module.top_level;
Reusable bytecode format and lowering from Compiler_IR_Model.H.
size_t size_t int32_t value
Arena-backed ownership context for bytecode functions and modules.
Lowers explicit IR into register-based bytecode.
T & append()
Allocate a new entry to the end of array.
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Compiler_SSA_Block & block(Compiler_SSA_Function &function, const Compiler_SSA_Block_Id id)
Main namespace for Aleph-w library functions.
void exit(const char *file, int line, const char *format,...)
Print a message and exit the program.
std::string compiler_dump_bytecode_module(const Compiler_Bytecode_Module *module, const Compiler_Type_Context *types=nullptr)
Dumps all lowered bytecode in one module deterministically.
constexpr size_t compiler_ir_invalid_id() noexcept
Returns the sentinel invalid IR id.
Compiler_Bytecode_Validation_Report validate_bytecode_function(const Compiler_Bytecode_Function &function, const Compiler_Bytecode_Module *module=nullptr)
Validates one lowered bytecode function structurally.
Compiler_Bytecode_Validation_Report validate_bytecode_module(const Compiler_Bytecode_Module &module)
Validates all bytecode functions in one module.
double add(double a, double b)
One basic block of IR instructions.
std::string label
Deterministic debug label.
Compiler_IR_Terminator terminator
Explicit block terminator.
DynArray< Compiler_IR_Instruction > instructions
Linear instruction list.
Compiler_IR_Block_Id id
Stable block id.
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.
std::string name
Debug or source-level name.
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.
Compiler_IR_Function_Id id
Stable function id within the module.
One instruction producing an optional explicit result value.
std::string text
Constant spelling or debug payload.
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.
Compiler_IR_Local_Slot_Id local_slot_id
Referenced local/parameter slot, when relevant.
Lowered IR module with shared global slots and functions.
One storage slot used by the IR.
std::string name
Debug name of the slot.
size_t id
Stable slot id within its storage space.
Compiler_IR_Slot_Kind kind
Slot storage category.
Compiler_IR_Terminator_Kind kind
Terminator category.
DynArray< Compiler_IR_Block_Id > successors
Successor blocks in deterministic order.
Compiler_IR_Value_Id condition_value
Branch condition value, if any.
Compiler_IR_Value_Id return_value
Return value, if any.
Compiler_SSA_Block_Id id
Dense SSA block id.
std::string label
Deterministic debug label.
Compiler_SSA_Terminator terminator
Explicit block terminator.
Compiler_IR_Terminator_Kind kind
Terminator category.