authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-02-13 20:40:51+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-02-13 23:24:26+01:00
logf5068107cdf54f143a150feb5d500962ba98e963
tree659d8cbad3f6fe798eb11fc47c7a579172fed543
parent5f50980880181774de83dab3294ddeb0a121d6f2

stage2 regalloc: track Inst instead of ?Inst in register mapping

The information whether a register is allocated to an instruction is already encoded in the free_registers "bitmap". Duplicating that information in the registers map is unnecessary and may lead to performance degradations.

1 files changed, 10 insertions(+), 9 deletions(-)

src/register_manager.zig+10-9
......@@ -33,11 +33,12 @@ pub fn RegisterManager(
3333 assert(callee_preserved_regs.len > 0); // see note above
3434
3535 return struct {
36 /// Tracks the AIR instruction allocated to every register or
37 /// `null` if no instruction is allocated to a register
36 /// Tracks the AIR instruction allocated to every register. If
37 /// no instruction is allocated to a register (i.e. the
38 /// register is free), the value in that slot is undefined.
3839 ///
3940 /// The key must be canonical register.
40 registers: [callee_preserved_regs.len]?Air.Inst.Index = [_]?Air.Inst.Index{null} ** callee_preserved_regs.len,
41 registers: [callee_preserved_regs.len]Air.Inst.Index = undefined,
4142 /// Tracks which registers are free (in which case the
4243 /// corresponding bit is set to 1)
4344 free_registers: FreeRegInt = math.maxInt(FreeRegInt),
......@@ -201,14 +202,14 @@ pub fn RegisterManager(
201202 if (self.isRegFree(reg)) {
202203 self.markRegUsed(reg);
203204 } else {
204 const spilled_inst = self.registers[index].?;
205 const spilled_inst = self.registers[index];
205206 try self.getFunction().spillInstruction(reg, spilled_inst);
206207 }
207208 self.registers[index] = inst;
208209 } else {
209210 // Don't track the register
210211 if (!self.isRegFree(reg)) {
211 const spilled_inst = self.registers[index].?;
212 const spilled_inst = self.registers[index];
212213 try self.getFunction().spillInstruction(reg, spilled_inst);
213214 self.freeReg(reg);
214215 }
......@@ -241,7 +242,7 @@ pub fn RegisterManager(
241242 if (!self.isRegFree(reg)) {
242243 // Move the instruction that was previously there to a
243244 // stack allocation.
244 const spilled_inst = self.registers[index].?;
245 const spilled_inst = self.registers[index];
245246 self.registers[index] = tracked_inst;
246247 try self.getFunction().spillInstruction(reg, spilled_inst);
247248 } else {
......@@ -251,7 +252,7 @@ pub fn RegisterManager(
251252 if (!self.isRegFree(reg)) {
252253 // Move the instruction that was previously there to a
253254 // stack allocation.
254 const spilled_inst = self.registers[index].?;
255 const spilled_inst = self.registers[index];
255256 try self.getFunction().spillInstruction(reg, spilled_inst);
256257 self.freeReg(reg);
257258 }
......@@ -265,7 +266,7 @@ pub fn RegisterManager(
265266 const index = reg.allocIndex() orelse return;
266267 self.markRegAllocated(reg);
267268
268 assert(self.registers[index] == null);
269 assert(self.isRegFree(reg));
269270 self.registers[index] = inst;
270271 self.markRegUsed(reg);
271272 }
......@@ -275,7 +276,7 @@ pub fn RegisterManager(
275276 const index = reg.allocIndex() orelse return;
276277 log.debug("freeing register {}", .{reg});
277278
278 self.registers[index] = null;
279 self.registers[index] = undefined;
279280 self.markRegFree(reg);
280281 }
281282 };