public void FreeEntry(int entryIndex) { lock (_bitmap) { _bitmap.Clear(entryIndex); _freeHint = entryIndex; } }
private static void Move(BitMap source, BitMap dest, int bit) { source.Clear(bit); dest.Set(bit); }
private void BuildIntervals(ControlFlowGraph cfg, AllocationContext context) { _blockRanges = new LiveRange[cfg.Blocks.Count]; int mapSize = _intervals.Count; BitMap[] blkLiveGen = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveKill = new BitMap[cfg.Blocks.Count]; // Compute local live sets. foreach (BasicBlock block in cfg.Blocks) { BitMap liveGen = new BitMap(mapSize); BitMap liveKill = new BitMap(mapSize); foreach (Node node in block.Operations) { foreach (Operand source in Sources(node)) { int id = GetOperandId(source); if (!liveKill.IsSet(id)) { liveGen.Set(id); } } foreach (Operand dest in Destinations(node)) { liveKill.Set(GetOperandId(dest)); } } blkLiveGen [block.Index] = liveGen; blkLiveKill[block.Index] = liveKill; } // Compute global live sets. BitMap[] blkLiveIn = new BitMap[cfg.Blocks.Count]; BitMap[] blkLiveOut = new BitMap[cfg.Blocks.Count]; for (int index = 0; index < cfg.Blocks.Count; index++) { blkLiveIn [index] = new BitMap(mapSize); blkLiveOut[index] = new BitMap(mapSize); } bool modified; do { modified = false; for (int index = 0; index < cfg.PostOrderBlocks.Length; index++) { BasicBlock block = cfg.PostOrderBlocks[index]; BitMap liveOut = blkLiveOut[block.Index]; foreach (BasicBlock successor in Successors(block)) { if (liveOut.Set(blkLiveIn[successor.Index])) { modified = true; } } BitMap liveIn = blkLiveIn[block.Index]; liveIn.Set(liveOut); liveIn.Clear(blkLiveKill[block.Index]); liveIn.Set(blkLiveGen [block.Index]); } }while (modified); _blockLiveIn = blkLiveIn; _blockEdges = new HashSet <int>(); // Compute lifetime intervals. int operationPos = _operationsCount; for (int index = 0; index < cfg.PostOrderBlocks.Length; index++) { BasicBlock block = cfg.PostOrderBlocks[index]; // We handle empty blocks by pretending they have a dummy instruction, // because otherwise the block would have the same start and end position, // and this is not valid. int instCount = Math.Max(block.Operations.Count, 1); int blockStart = operationPos - instCount * InstructionGap; int blockEnd = operationPos; _blockRanges[block.Index] = new LiveRange(blockStart, blockEnd); _blockEdges.Add(blockStart); BitMap liveOut = blkLiveOut[block.Index]; foreach (int id in liveOut) { _intervals[id].AddRange(blockStart, blockEnd); } if (block.Operations.Count == 0) { operationPos -= InstructionGap; continue; } foreach (Node node in BottomOperations(block)) { operationPos -= InstructionGap; foreach (Operand dest in Destinations(node)) { LiveInterval interval = _intervals[GetOperandId(dest)]; interval.SetStart(operationPos + 1); interval.AddUsePosition(operationPos + 1); } foreach (Operand source in Sources(node)) { LiveInterval interval = _intervals[GetOperandId(source)]; interval.AddRange(blockStart, operationPos + 1); interval.AddUsePosition(operationPos); } if (node is Operation operation && operation.Instruction == Instruction.Call) { AddIntervalCallerSavedReg(context.Masks.IntCallerSavedRegisters, operationPos, RegisterType.Integer); AddIntervalCallerSavedReg(context.Masks.VecCallerSavedRegisters, operationPos, RegisterType.Vector); } } } }