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(...@@ -33,11 +33,12 @@ pub fn RegisterManager(
33 assert(callee_preserved_regs.len > 0); // see note above33 assert(callee_preserved_regs.len > 0); // see note above
3434
35 return struct {35 return struct {
36 /// Tracks the AIR instruction allocated to every register or36 /// Tracks the AIR instruction allocated to every register. If
37 /// `null` if no instruction is allocated to a register37 /// no instruction is allocated to a register (i.e. the
38 /// register is free), the value in that slot is undefined.
38 ///39 ///
39 /// The key must be canonical register.40 /// 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,
41 /// Tracks which registers are free (in which case the42 /// Tracks which registers are free (in which case the
42 /// corresponding bit is set to 1)43 /// corresponding bit is set to 1)
43 free_registers: FreeRegInt = math.maxInt(FreeRegInt),44 free_registers: FreeRegInt = math.maxInt(FreeRegInt),
...@@ -201,14 +202,14 @@ pub fn RegisterManager(...@@ -201,14 +202,14 @@ pub fn RegisterManager(
201 if (self.isRegFree(reg)) {202 if (self.isRegFree(reg)) {
202 self.markRegUsed(reg);203 self.markRegUsed(reg);
203 } else {204 } else {
204 const spilled_inst = self.registers[index].?;205 const spilled_inst = self.registers[index];
205 try self.getFunction().spillInstruction(reg, spilled_inst);206 try self.getFunction().spillInstruction(reg, spilled_inst);
206 }207 }
207 self.registers[index] = inst;208 self.registers[index] = inst;
208 } else {209 } else {
209 // Don't track the register210 // Don't track the register
210 if (!self.isRegFree(reg)) {211 if (!self.isRegFree(reg)) {
211 const spilled_inst = self.registers[index].?;212 const spilled_inst = self.registers[index];
212 try self.getFunction().spillInstruction(reg, spilled_inst);213 try self.getFunction().spillInstruction(reg, spilled_inst);
213 self.freeReg(reg);214 self.freeReg(reg);
214 }215 }
...@@ -241,7 +242,7 @@ pub fn RegisterManager(...@@ -241,7 +242,7 @@ pub fn RegisterManager(
241 if (!self.isRegFree(reg)) {242 if (!self.isRegFree(reg)) {
242 // Move the instruction that was previously there to a243 // Move the instruction that was previously there to a
243 // stack allocation.244 // stack allocation.
244 const spilled_inst = self.registers[index].?;245 const spilled_inst = self.registers[index];
245 self.registers[index] = tracked_inst;246 self.registers[index] = tracked_inst;
246 try self.getFunction().spillInstruction(reg, spilled_inst);247 try self.getFunction().spillInstruction(reg, spilled_inst);
247 } else {248 } else {
...@@ -251,7 +252,7 @@ pub fn RegisterManager(...@@ -251,7 +252,7 @@ pub fn RegisterManager(
251 if (!self.isRegFree(reg)) {252 if (!self.isRegFree(reg)) {
252 // Move the instruction that was previously there to a253 // Move the instruction that was previously there to a
253 // stack allocation.254 // stack allocation.
254 const spilled_inst = self.registers[index].?;255 const spilled_inst = self.registers[index];
255 try self.getFunction().spillInstruction(reg, spilled_inst);256 try self.getFunction().spillInstruction(reg, spilled_inst);
256 self.freeReg(reg);257 self.freeReg(reg);
257 }258 }
...@@ -265,7 +266,7 @@ pub fn RegisterManager(...@@ -265,7 +266,7 @@ pub fn RegisterManager(
265 const index = reg.allocIndex() orelse return;266 const index = reg.allocIndex() orelse return;
266 self.markRegAllocated(reg);267 self.markRegAllocated(reg);
267268
268 assert(self.registers[index] == null);269 assert(self.isRegFree(reg));
269 self.registers[index] = inst;270 self.registers[index] = inst;
270 self.markRegUsed(reg);271 self.markRegUsed(reg);
271 }272 }
...@@ -275,7 +276,7 @@ pub fn RegisterManager(...@@ -275,7 +276,7 @@ pub fn RegisterManager(
275 const index = reg.allocIndex() orelse return;276 const index = reg.allocIndex() orelse return;
276 log.debug("freeing register {}", .{reg});277 log.debug("freeing register {}", .{reg});
277278
278 self.registers[index] = null;279 self.registers[index] = undefined;
279 self.markRegFree(reg);280 self.markRegFree(reg);
280 }281 }
281 };282 };