IR if statements WIP
parent
77ae3442ef
commit
ce3c52471d
|
@ -1409,13 +1409,17 @@ enum AtomicOrder {
|
|||
struct IrBasicBlock {
|
||||
ZigList<IrInstruction *> instruction_list;
|
||||
IrBasicBlock *other;
|
||||
const char *name_hint;
|
||||
size_t debug_id;
|
||||
};
|
||||
|
||||
enum IrInstructionId {
|
||||
IrInstructionIdInvalid,
|
||||
IrInstructionIdBr,
|
||||
IrInstructionIdCondBr,
|
||||
IrInstructionIdSwitchBr,
|
||||
IrInstructionIdPhi,
|
||||
IrInstructionIdUnOp,
|
||||
IrInstructionIdBinOp,
|
||||
IrInstructionIdLoadVar,
|
||||
IrInstructionIdStoreVar,
|
||||
|
@ -1442,9 +1446,15 @@ struct IrInstruction {
|
|||
struct IrInstructionCondBr {
|
||||
IrInstruction base;
|
||||
|
||||
// If cond_inst_index == SIZE_MAX, then this is an unconditional branch.
|
||||
size_t cond_inst_index;
|
||||
size_t dest_basic_block_index;
|
||||
IrInstruction *condition;
|
||||
IrBasicBlock *then_block;
|
||||
IrBasicBlock *else_block;
|
||||
};
|
||||
|
||||
struct IrInstructionBr {
|
||||
IrInstruction base;
|
||||
|
||||
IrBasicBlock *dest_block;
|
||||
};
|
||||
|
||||
struct IrInstructionSwitchBrCase {
|
||||
|
@ -1464,11 +1474,35 @@ struct IrInstructionSwitchBr {
|
|||
struct IrInstructionPhi {
|
||||
IrInstruction base;
|
||||
|
||||
size_t incoming_block_count;
|
||||
size_t incoming_count;
|
||||
IrBasicBlock **incoming_blocks;
|
||||
IrInstruction **incoming_values;
|
||||
};
|
||||
|
||||
enum IrUnOp {
|
||||
IrUnOpInvalid,
|
||||
IrUnOpBoolNot,
|
||||
IrUnOpBinNot,
|
||||
IrUnOpNegation,
|
||||
IrUnOpNegationWrap,
|
||||
IrUnOpAddressOf,
|
||||
IrUnOpConstAddressOf,
|
||||
IrUnOpDereference,
|
||||
IrUnOpError,
|
||||
IrUnOpMaybe,
|
||||
IrUnOpUnwrapError,
|
||||
IrUnOpUnwrapMaybe,
|
||||
IrUnOpErrorReturn,
|
||||
IrUnOpMaybeReturn,
|
||||
};
|
||||
|
||||
struct IrInstructionUnOp {
|
||||
IrInstruction base;
|
||||
|
||||
IrUnOp op_id;
|
||||
IrInstruction *value;
|
||||
};
|
||||
|
||||
enum IrBinOp {
|
||||
IrBinOpInvalid,
|
||||
IrBinOpBoolOr,
|
||||
|
@ -1529,8 +1563,7 @@ struct IrInstructionCall {
|
|||
struct IrInstructionBuiltinCall {
|
||||
IrInstruction base;
|
||||
|
||||
BuiltinFnId fn_id;
|
||||
size_t arg_count;
|
||||
BuiltinFnEntry *fn;
|
||||
IrInstruction **args;
|
||||
};
|
||||
|
||||
|
|
1307
src/analyze.cpp
1307
src/analyze.cpp
File diff suppressed because it is too large
Load Diff
|
@ -2808,11 +2808,13 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
|
|||
case IrInstructionIdCast:
|
||||
return ir_render_cast(g, executable, (IrInstructionCast *)instruction);
|
||||
case IrInstructionIdCondBr:
|
||||
case IrInstructionIdBr:
|
||||
case IrInstructionIdSwitchBr:
|
||||
case IrInstructionIdPhi:
|
||||
case IrInstructionIdStoreVar:
|
||||
case IrInstructionIdCall:
|
||||
case IrInstructionIdBuiltinCall:
|
||||
case IrInstructionIdUnOp:
|
||||
zig_panic("TODO render more IR instructions to LLVM");
|
||||
}
|
||||
zig_unreachable();
|
||||
|
|
1487
src/ir.cpp
1487
src/ir.cpp
File diff suppressed because it is too large
Load Diff
110
src/ir_print.cpp
110
src/ir_print.cpp
|
@ -46,10 +46,17 @@ static void ir_print_const(IrPrint *irp, IrInstructionConst *const_instruction)
|
|||
case TypeTableEntryIdMetaType:
|
||||
fprintf(irp->f, "%s\n", buf_ptr(&const_instruction->base.static_value.data.x_type->name));
|
||||
break;
|
||||
case TypeTableEntryIdInt:
|
||||
{
|
||||
BigNum *bignum = &const_instruction->base.static_value.data.x_bignum;
|
||||
assert(bignum->kind == BigNumKindInt);
|
||||
const char *negative_str = bignum->is_negative ? "-" : "";
|
||||
fprintf(irp->f, "%s%llu\n", negative_str, bignum->data.x_uint);
|
||||
}
|
||||
break;
|
||||
case TypeTableEntryIdVar:
|
||||
case TypeTableEntryIdBool:
|
||||
case TypeTableEntryIdUnreachable:
|
||||
case TypeTableEntryIdInt:
|
||||
case TypeTableEntryIdFloat:
|
||||
case TypeTableEntryIdPointer:
|
||||
case TypeTableEntryIdArray:
|
||||
|
@ -127,6 +134,47 @@ static const char *ir_bin_op_id_str(IrBinOp op_id) {
|
|||
zig_unreachable();
|
||||
}
|
||||
|
||||
static const char *ir_un_op_id_str(IrUnOp op_id) {
|
||||
switch (op_id) {
|
||||
case IrUnOpInvalid:
|
||||
zig_unreachable();
|
||||
case IrUnOpBoolNot:
|
||||
return "!";
|
||||
case IrUnOpBinNot:
|
||||
return "~";
|
||||
case IrUnOpNegation:
|
||||
return "-";
|
||||
case IrUnOpNegationWrap:
|
||||
return "-%";
|
||||
case IrUnOpAddressOf:
|
||||
return "&";
|
||||
case IrUnOpConstAddressOf:
|
||||
return "&const";
|
||||
case IrUnOpDereference:
|
||||
return "*";
|
||||
case IrUnOpMaybe:
|
||||
return "?";
|
||||
case IrUnOpError:
|
||||
return "%";
|
||||
case IrUnOpUnwrapError:
|
||||
return "%%";
|
||||
case IrUnOpUnwrapMaybe:
|
||||
return "??";
|
||||
case IrUnOpMaybeReturn:
|
||||
return "?return";
|
||||
case IrUnOpErrorReturn:
|
||||
return "%return";
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
static void ir_print_un_op(IrPrint *irp, IrInstructionUnOp *un_op_instruction) {
|
||||
ir_print_prefix(irp, &un_op_instruction->base);
|
||||
fprintf(irp->f, "%s #%zu\n",
|
||||
ir_un_op_id_str(un_op_instruction->op_id),
|
||||
un_op_instruction->value->debug_id);
|
||||
}
|
||||
|
||||
static void ir_print_bin_op(IrPrint *irp, IrInstructionBinOp *bin_op_instruction) {
|
||||
ir_print_prefix(irp, &bin_op_instruction->base);
|
||||
fprintf(irp->f, "#%zu %s #%zu\n",
|
||||
|
@ -160,6 +208,47 @@ static void ir_print_call(IrPrint *irp, IrInstructionCall *call_instruction) {
|
|||
fprintf(irp->f, ")\n");
|
||||
}
|
||||
|
||||
static void ir_print_builtin_call(IrPrint *irp, IrInstructionBuiltinCall *call_instruction) {
|
||||
ir_print_prefix(irp, &call_instruction->base);
|
||||
fprintf(irp->f, "@%s(", buf_ptr(&call_instruction->fn->name));
|
||||
for (size_t i = 0; i < call_instruction->fn->param_count; i += 1) {
|
||||
IrInstruction *arg = call_instruction->args[i];
|
||||
if (i != 0)
|
||||
fprintf(irp->f, ", ");
|
||||
fprintf(irp->f, "#%zu", arg->debug_id);
|
||||
}
|
||||
fprintf(irp->f, ")\n");
|
||||
}
|
||||
|
||||
|
||||
static void ir_print_cond_br(IrPrint *irp, IrInstructionCondBr *cond_br_instruction) {
|
||||
ir_print_prefix(irp, &cond_br_instruction->base);
|
||||
fprintf(irp->f, "if #%zu then $%s_%zu else $%s_%zu\n",
|
||||
cond_br_instruction->condition->debug_id,
|
||||
cond_br_instruction->then_block->name_hint, cond_br_instruction->then_block->debug_id,
|
||||
cond_br_instruction->else_block->name_hint, cond_br_instruction->else_block->debug_id);
|
||||
}
|
||||
|
||||
static void ir_print_br(IrPrint *irp, IrInstructionBr *br_instruction) {
|
||||
ir_print_prefix(irp, &br_instruction->base);
|
||||
fprintf(irp->f, "goto $%s_%zu\n",
|
||||
br_instruction->dest_block->name_hint, br_instruction->dest_block->debug_id);
|
||||
}
|
||||
|
||||
static void ir_print_phi(IrPrint *irp, IrInstructionPhi *phi_instruction) {
|
||||
ir_print_prefix(irp, &phi_instruction->base);
|
||||
for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) {
|
||||
IrBasicBlock *incoming_block = phi_instruction->incoming_blocks[i];
|
||||
IrInstruction *incoming_value = phi_instruction->incoming_values[i];
|
||||
if (i != 0)
|
||||
fprintf(irp->f, " ");
|
||||
fprintf(irp->f, "$%s_%zu:#%zu",
|
||||
incoming_block->name_hint, incoming_block->debug_id,
|
||||
incoming_value->debug_id);
|
||||
}
|
||||
fprintf(irp->f, "\n");
|
||||
}
|
||||
|
||||
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
||||
switch (instruction->id) {
|
||||
case IrInstructionIdInvalid:
|
||||
|
@ -182,11 +271,23 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
|
|||
case IrInstructionIdCall:
|
||||
ir_print_call(irp, (IrInstructionCall *)instruction);
|
||||
break;
|
||||
case IrInstructionIdUnOp:
|
||||
ir_print_un_op(irp, (IrInstructionUnOp *)instruction);
|
||||
break;
|
||||
case IrInstructionIdCondBr:
|
||||
case IrInstructionIdSwitchBr:
|
||||
case IrInstructionIdPhi:
|
||||
case IrInstructionIdStoreVar:
|
||||
ir_print_cond_br(irp, (IrInstructionCondBr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdBr:
|
||||
ir_print_br(irp, (IrInstructionBr *)instruction);
|
||||
break;
|
||||
case IrInstructionIdBuiltinCall:
|
||||
ir_print_builtin_call(irp, (IrInstructionBuiltinCall *)instruction);
|
||||
break;
|
||||
case IrInstructionIdPhi:
|
||||
ir_print_phi(irp, (IrInstructionPhi *)instruction);
|
||||
break;
|
||||
case IrInstructionIdSwitchBr:
|
||||
case IrInstructionIdStoreVar:
|
||||
zig_panic("TODO print more IR instructions");
|
||||
}
|
||||
}
|
||||
|
@ -200,6 +301,7 @@ void ir_print(FILE *f, IrExecutable *executable, int indent_size) {
|
|||
|
||||
for (size_t bb_i = 0; bb_i < executable->basic_block_list.length; bb_i += 1) {
|
||||
IrBasicBlock *current_block = executable->basic_block_list.at(bb_i);
|
||||
fprintf(irp->f, "%s_%zu:\n", current_block->name_hint, current_block->debug_id);
|
||||
for (size_t instr_i = 0; instr_i < current_block->instruction_list.length; instr_i += 1) {
|
||||
IrInstruction *instruction = current_block->instruction_list.at(instr_i);
|
||||
ir_print_instruction(irp, instruction);
|
||||
|
|
Loading…
Reference in New Issue