36#include <gtest/gtest.h>
58 function.
name =
"choose";
65 flag.
kind = Compiler_IR_Slot_Kind::Parameter;
71 value.kind = Compiler_IR_Slot_Kind::Local;
77 entry.
label =
"entry";
80 zero.
kind = Compiler_IR_Instruction_Kind::Constant;
103 exit.predecessors.append(3);
110 one.
kind = Compiler_IR_Instruction_Kind::Constant;
121 then_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
135 join_block.terminator.kind = Compiler_IR_Terminator_Kind::Return;
146 two.
kind = Compiler_IR_Instruction_Kind::Constant;
157 else_block.terminator.kind = Compiler_IR_Terminator_Kind::Jump;
161 function.
blocks.append(entry);
173 function.
name =
"loop";
180 flag.
kind = Compiler_IR_Slot_Kind::Parameter;
186 i_slot.kind = Compiler_IR_Slot_Kind::Local;
192 entry.
label =
"entry";
195 zero.
kind = Compiler_IR_Instruction_Kind::Constant;
210 exit.predecessors.append(4);
214 header.
label =
"while.cond.0";
231 body.
label =
"while.body.0";
234 load_i.
kind = Compiler_IR_Instruction_Kind::Load;
240 one.
kind = Compiler_IR_Instruction_Kind::Constant;
246 add.kind = Compiler_IR_Instruction_Kind::Binary;
248 add.op = Compiler_Operator_Kind::Plus;
249 add.operands.append(3);
250 add.operands.append(4);
254 store_i.
kind = Compiler_IR_Instruction_Kind::Store;
273 end_block.terminator.kind = Compiler_IR_Terminator_Kind::Return;
275 end_block.terminator.successors.append(1);
278 function.
blocks.append(entry);
280 function.
blocks.append(header);
281 function.
blocks.append(body);
294 module.functions.append(&source);
298 const auto & function = *
ssa->functions.access(0);
304 EXPECT_EQ(function.dominance.immediate_dominators.access(2), 0u);
305 EXPECT_EQ(function.dominance.immediate_dominators.access(4), 0u);
306 EXPECT_EQ(function.dominance.immediate_dominators.access(3), 0u);
307 EXPECT_EQ(function.dominance.immediate_dominators.access(1), 3u);
308 ASSERT_EQ(function.dominance.dominance_frontiers.access(2).size(), 1u);
309 EXPECT_EQ(function.dominance.dominance_frontiers.access(2).access(0), 3u);
310 ASSERT_EQ(function.dominance.dominance_frontiers.access(4).size(), 1u);
311 EXPECT_EQ(function.dominance.dominance_frontiers.access(4).access(0), 3u);
321 module.functions.append(&source);
324 const auto & function = *
ssa->functions.access(0);
329 ASSERT_EQ(function.parameters.size(), 1u);
330 EXPECT_EQ(function.parameters.access(0).slot_id, 0u);
332 const auto & entry = function.
blocks.access(0);
335 Compiler_SSA_Instruction_Kind::Constant);
339 const auto &
join = function.
blocks.access(3);
344 EXPECT_EQ(
join.terminator.kind, Compiler_IR_Terminator_Kind::Return);
358 module.functions.append(&source);
361 const auto & function = *
ssa->functions.access(0);
367 const auto & header = function.
blocks.access(2);
369 EXPECT_EQ(header.phis.access(0).slot_id, 1u);
370 ASSERT_EQ(header.phis.access(0).operands.size(), 2u);
371 EXPECT_NE(header.phis.access(0).operands.access(0), 0u);
372 EXPECT_NE(header.phis.access(0).operands.access(1), 0u);
376 const auto & body = function.
blocks.access(3);
379 Compiler_SSA_Instruction_Kind::Constant);
381 Compiler_SSA_Instruction_Kind::Binary);
383 const auto & end = function.
blocks.access(4);
385 EXPECT_EQ(end.terminator.kind, Compiler_IR_Terminator_Kind::Return);
386 EXPECT_EQ(end.terminator.return_value, header.phis.access(0).result_id);
Static single assignment form over Compiler_IR.H.
size_t size_t int32_t value
Arena-backed ownership context for SSA functions and modules.
Lowers non-SSA IR to SSA form for all reachable blocks.
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.
Compiler_SSA_Validation_Report validate_ssa_function(const Compiler_SSA_Function &function, const Compiler_SSA_Module *module=nullptr)
Validates one SSA function structurally and semantically.
void exit(const char *file, int line, const char *format,...)
Print a message and exit the program.
constexpr size_t compiler_ssa_invalid_id() noexcept
Returns the sentinel invalid SSA id.
std::string compiler_dump_ssa_function(const Compiler_SSA_Function *function, const Compiler_SSA_Module *module=nullptr, const Compiler_Type_Context *types=nullptr)
Dumps one SSA function deterministically.
std::ostream & join(const C &c, const std::string &sep, std::ostream &out)
Join elements of an Aleph-style container into a stream.
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_Block_Id > predecessors
Predecessor block ids.
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.
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.
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_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.