mirror of
https://github.com/llvm/llvm-project.git
synced 2026-10-26 13:53:31 +08:00
Change `TargetRegisterInfo::getRegAllocationHints` and all target overrides to accept `SmallSetVector<MCPhysReg, 16> &Hints` instead of `SmallVectorImpl`, structurally preventing duplicate register allocation hints while preserving insertion order. Assisted-by: Gemini Link: #190139 Link: #193011 Link: #219007 Link: #224448 Link: #224451 Link: #224742
106 lines
4.0 KiB
C++
106 lines
4.0 KiB
C++
//===-- llvm/CodeGen/AllocationOrder.cpp - Allocation Order ---------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements an allocation order for virtual registers.
|
|
//
|
|
// The preferred allocation order for a virtual register depends on allocation
|
|
// hints, anti-hints, and target hooks. The AllocationOrder class encapsulates
|
|
// all of that.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "AllocationOrder.h"
|
|
#include "llvm/ADT/BitVector.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/CodeGen/RegisterClassInfo.h"
|
|
#include "llvm/CodeGen/VirtRegMap.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "regalloc"
|
|
|
|
static void getBitVecRegAntiHints(Register VReg, BitVector &AntiHintedRegUnits,
|
|
const VirtRegMap &VRM,
|
|
const MachineRegisterInfo &MRI,
|
|
const TargetRegisterInfo &TRI) {
|
|
assert(VReg.isVirtual() && "Anti-hints are only for virtual registers");
|
|
for (Register AntiHintVReg : MRI.getRegAllocationAntiHints(VReg)) {
|
|
// Check if the anti-hinted register has been allocated.
|
|
if (!VRM.hasPhys(AntiHintVReg))
|
|
continue;
|
|
// Delay until first allocated anti-hinted register so unused cases keep
|
|
// default empty BitVector.
|
|
if (AntiHintedRegUnits.empty())
|
|
AntiHintedRegUnits.resize(TRI.getNumRegUnits());
|
|
for (MCRegUnit Unit : TRI.regunits(VRM.getPhys(AntiHintVReg)))
|
|
AntiHintedRegUnits.set(static_cast<unsigned>(Unit));
|
|
}
|
|
}
|
|
|
|
// Compare VirtRegMap::getRegAllocPref().
|
|
AllocationOrder AllocationOrder::create(Register VirtReg, const VirtRegMap &VRM,
|
|
const RegisterClassInfo &RegClassInfo,
|
|
const LiveRegMatrix *Matrix) {
|
|
const MachineFunction &MF = VRM.getMachineFunction();
|
|
const TargetRegisterInfo *TRI = &VRM.getTargetRegInfo();
|
|
const MachineRegisterInfo &MRI = MF.getRegInfo();
|
|
auto Order = RegClassInfo.getOrder(MF.getRegInfo().getRegClass(VirtReg));
|
|
// Get Hints.
|
|
SmallSetVector<MCPhysReg, 16> Hints;
|
|
bool HardHints =
|
|
TRI->getRegAllocationHints(VirtReg, Order, Hints, MF, &VRM, Matrix);
|
|
|
|
// HintsAndCustomOrder holds Hints first followed by the custom order if the
|
|
// anti-hints reorders it.
|
|
SmallVector<MCPhysReg, 16> HintsAndCustomOrder = Hints.takeVector();
|
|
const int NumHints = static_cast<int>(HintsAndCustomOrder.size());
|
|
|
|
// HintsAndCustomOrder only holds Hints (custom order is not added yet).
|
|
LLVM_DEBUG({
|
|
if (NumHints) {
|
|
dbgs() << "hints:";
|
|
for (MCPhysReg Hint : HintsAndCustomOrder)
|
|
dbgs() << ' ' << printReg(Hint, TRI);
|
|
dbgs() << '\n';
|
|
}
|
|
});
|
|
|
|
// Get anti-hints.
|
|
BitVector AntiHintedRegUnits;
|
|
getBitVecRegAntiHints(VirtReg, AntiHintedRegUnits, VRM, MRI, *TRI);
|
|
|
|
LLVM_DEBUG({
|
|
if (AntiHintedRegUnits.any()) {
|
|
dbgs() << "anti-hints:";
|
|
for (Register AntiHintVReg : MRI.getRegAllocationAntiHints(VirtReg)) {
|
|
if (!VRM.hasPhys(AntiHintVReg))
|
|
continue;
|
|
dbgs() << ' ' << printReg(VRM.getPhys(AntiHintVReg), TRI);
|
|
}
|
|
dbgs() << '\n';
|
|
}
|
|
});
|
|
|
|
if (AntiHintedRegUnits.any())
|
|
TRI->applyRegAllocationAntiHints(VirtReg, Order, HintsAndCustomOrder,
|
|
NumHints, AntiHintedRegUnits, MF, Matrix,
|
|
&RegClassInfo);
|
|
|
|
// Create allocation order object.
|
|
AllocationOrder AO(std::move(HintsAndCustomOrder), NumHints, Order,
|
|
HardHints);
|
|
|
|
assert(all_of(AO.hints(),
|
|
[&](MCPhysReg Hint) { return is_contained(AO.Order, Hint); }) &&
|
|
"Target hint is outside allocation order.");
|
|
return AO;
|
|
}
|