ir: don't emit constants in function instructions
This aims to improve register allocation
This commit is contained in:
parent
da07fd5ca4
commit
5dceac7720
@ -853,10 +853,13 @@ pub const Builder = struct {
|
|||||||
.type = try builder.translateType(integer_value.type),
|
.type = try builder.translateType(integer_value.type),
|
||||||
};
|
};
|
||||||
assert(integer.type.isInteger());
|
assert(integer.type.isInteger());
|
||||||
const load_integer = try builder.append(.{
|
const instruction_allocation = try builder.ir.instructions.append(builder.allocator, .{
|
||||||
.load_integer = integer,
|
.load_integer = integer,
|
||||||
});
|
});
|
||||||
return load_integer;
|
// const load_integer = try builder.append(.{
|
||||||
|
// .load_integer = integer,
|
||||||
|
// });
|
||||||
|
return instruction_allocation.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn processSyscall(builder: *Builder, sema_syscall_index: Compilation.Syscall.Index) anyerror!Instruction.Index {
|
fn processSyscall(builder: *Builder, sema_syscall_index: Compilation.Syscall.Index) anyerror!Instruction.Index {
|
||||||
|
@ -1147,21 +1147,33 @@ const InstructionSelection = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const instruction = mir.ir.instructions.get(ir_instruction_index);
|
const instruction = mir.ir.instructions.get(ir_instruction_index);
|
||||||
if (instruction.* != .stack or !instruction_selection.stack_map.contains(ir_instruction_index)) {
|
const defer_materialization = switch (instruction.*) {
|
||||||
|
.stack => !instruction_selection.stack_map.contains(ir_instruction_index),
|
||||||
|
.load_integer => false,
|
||||||
|
else => true,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (defer_materialization) {
|
||||||
const ir_type = getIrType(mir.ir, ir_instruction_index);
|
const ir_type = getIrType(mir.ir, ir_instruction_index);
|
||||||
const value_type = resolveType(ir_type);
|
const value_type = resolveType(ir_type);
|
||||||
const register_class = register_classes.get(value_type);
|
const register_class = register_classes.get(value_type);
|
||||||
const new_register = try mir.createVirtualRegister(register_class);
|
const new_register = try mir.createVirtualRegister(register_class);
|
||||||
try instruction_selection.value_map.putNoClobber(mir.allocator, ir_instruction_index, new_register);
|
try instruction_selection.value_map.putNoClobber(mir.allocator, ir_instruction_index, new_register);
|
||||||
return new_register;
|
return new_register;
|
||||||
}
|
} else {
|
||||||
|
const new_register = switch (instruction.*) {
|
||||||
|
.load_integer => try instruction_selection.materializeInteger(mir, ir_instruction_index),
|
||||||
|
else => unreachable,
|
||||||
|
};
|
||||||
|
try instruction_selection.local_value_map.put(mir.allocator, ir_instruction_index, new_register);
|
||||||
|
|
||||||
unreachable;
|
return new_register;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moving an immediate to a register
|
// Moving an immediate to a register
|
||||||
fn materializeInteger(instruction_selection: *InstructionSelection, mir: *MIR, ir_instruction_index: ir.Instruction.Index) !void {
|
fn materializeInteger(instruction_selection: *InstructionSelection, mir: *MIR, ir_instruction_index: ir.Instruction.Index) !Register {
|
||||||
const destination_register = try instruction_selection.getRegisterForValue(mir, ir_instruction_index);
|
// const destination_register = try instruction_selection.getRegisterForValue(mir, ir_instruction_index);
|
||||||
const integer = mir.ir.instructions.get(ir_instruction_index).load_integer;
|
const integer = mir.ir.instructions.get(ir_instruction_index).load_integer;
|
||||||
const value_type = resolveType(integer.type);
|
const value_type = resolveType(integer.type);
|
||||||
// const destination_register_class = register_classes.get(value_type);
|
// const destination_register_class = register_classes.get(value_type);
|
||||||
@ -1184,6 +1196,8 @@ const InstructionSelection = struct {
|
|||||||
else => |t| @panic(@tagName(t)),
|
else => |t| @panic(@tagName(t)),
|
||||||
};
|
};
|
||||||
const instruction_descriptor = instruction_descriptors.get(instruction_id);
|
const instruction_descriptor = instruction_descriptors.get(instruction_id);
|
||||||
|
const register_class = register_classes.get(value_type);
|
||||||
|
const destination_register = try mir.createVirtualRegister(register_class);
|
||||||
const operand_id = instruction_descriptor.operands[0].id;
|
const operand_id = instruction_descriptor.operands[0].id;
|
||||||
// const register_class = register_classes.get(operand_id);
|
// const register_class = register_classes.get(operand_id);
|
||||||
const destination_operand = Operand{
|
const destination_operand = Operand{
|
||||||
@ -1197,7 +1211,10 @@ const InstructionSelection = struct {
|
|||||||
const xor = try mir.buildInstruction(instruction_selection, instruction_id, &.{
|
const xor = try mir.buildInstruction(instruction_selection, instruction_id, &.{
|
||||||
destination_operand,
|
destination_operand,
|
||||||
});
|
});
|
||||||
|
|
||||||
try instruction_selection.instruction_cache.append(mir.allocator, xor);
|
try instruction_selection.instruction_cache.append(mir.allocator, xor);
|
||||||
|
|
||||||
|
return destination_register;
|
||||||
},
|
},
|
||||||
false => {
|
false => {
|
||||||
const instruction_id: Instruction.Id = switch (value_type) {
|
const instruction_id: Instruction.Id = switch (value_type) {
|
||||||
@ -1216,6 +1233,8 @@ const InstructionSelection = struct {
|
|||||||
|
|
||||||
const instruction_descriptor = instruction_descriptors.get(instruction_id);
|
const instruction_descriptor = instruction_descriptors.get(instruction_id);
|
||||||
const operand_id = instruction_descriptor.operands[0].id;
|
const operand_id = instruction_descriptor.operands[0].id;
|
||||||
|
const register_class = register_classes.get(value_type);
|
||||||
|
const destination_register = try mir.createVirtualRegister(register_class);
|
||||||
|
|
||||||
const destination_operand = Operand{
|
const destination_operand = Operand{
|
||||||
.id = operand_id,
|
.id = operand_id,
|
||||||
@ -1239,6 +1258,8 @@ const InstructionSelection = struct {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try instruction_selection.instruction_cache.append(mir.allocator, instr);
|
try instruction_selection.instruction_cache.append(mir.allocator, instr);
|
||||||
|
|
||||||
|
return destination_register;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2199,7 +2220,7 @@ pub const MIR = struct {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.load_integer => try instruction_selection.materializeInteger(mir, ir_instruction_index),
|
.load_integer => unreachable,
|
||||||
.@"unreachable" => try instruction_selection.instruction_cache.append(mir.allocator, try mir.buildInstruction(instruction_selection, .ud2, &.{})),
|
.@"unreachable" => try instruction_selection.instruction_cache.append(mir.allocator, try mir.buildInstruction(instruction_selection, .ud2, &.{})),
|
||||||
.syscall => |ir_syscall_index| {
|
.syscall => |ir_syscall_index| {
|
||||||
const ir_syscall = mir.ir.syscalls.get(ir_syscall_index);
|
const ir_syscall = mir.ir.syscalls.get(ir_syscall_index);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user