1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
|
//===-- RegUsageInfoCollector.cpp - Register Usage Information Collector --===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// This pass is required to take advantage of the interprocedural register
/// allocation infrastructure.
///
/// This pass is simple MachineFunction pass which collects register usage
/// details by iterating through each physical registers and checking
/// MRI::isPhysRegUsed() then creates a RegMask based on this details.
/// The pass then stores this RegMask in PhysicalRegisterUsageInfo.cpp
///
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegisterUsageInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
using namespace llvm;
#define DEBUG_TYPE "ip-regalloc"
STATISTIC(NumCSROpt,
"Number of functions optimized for callee saved registers");
namespace {
class RegUsageInfoCollector : public MachineFunctionPass {
public:
RegUsageInfoCollector() : MachineFunctionPass(ID) {
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeRegUsageInfoCollectorPass(Registry);
}
StringRef getPassName() const override {
return "Register Usage Information Collector Pass";
}
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<PhysicalRegisterUsageInfo>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF) override;
// Call determineCalleeSaves and then also set the bits for subregs and
// fully saved superregs.
static void computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF);
static char ID;
};
} // end of anonymous namespace
char RegUsageInfoCollector::ID = 0;
INITIALIZE_PASS_BEGIN(RegUsageInfoCollector, "RegUsageInfoCollector",
"Register Usage Information Collector", false, false)
INITIALIZE_PASS_DEPENDENCY(PhysicalRegisterUsageInfo)
INITIALIZE_PASS_END(RegUsageInfoCollector, "RegUsageInfoCollector",
"Register Usage Information Collector", false, false)
FunctionPass *llvm::createRegUsageInfoCollector() {
return new RegUsageInfoCollector();
}
bool RegUsageInfoCollector::runOnMachineFunction(MachineFunction &MF) {
MachineRegisterInfo *MRI = &MF.getRegInfo();
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
const TargetMachine &TM = MF.getTarget();
LLVM_DEBUG(dbgs() << " -------------------- " << getPassName()
<< " -------------------- \n");
LLVM_DEBUG(dbgs() << "Function Name : " << MF.getName() << "\n");
std::vector<uint32_t> RegMask;
// Compute the size of the bit vector to represent all the registers.
// The bit vector is broken into 32-bit chunks, thus takes the ceil of
// the number of registers divided by 32 for the size.
unsigned RegMaskSize = MachineOperand::getRegMaskSize(TRI->getNumRegs());
RegMask.resize(RegMaskSize, ~((uint32_t)0));
const Function &F = MF.getFunction();
PhysicalRegisterUsageInfo &PRUI = getAnalysis<PhysicalRegisterUsageInfo>();
PRUI.setTargetMachine(TM);
LLVM_DEBUG(dbgs() << "Clobbered Registers: ");
BitVector SavedRegs;
computeCalleeSavedRegs(SavedRegs, MF);
const BitVector &UsedPhysRegsMask = MRI->getUsedPhysRegsMask();
auto SetRegAsDefined = [&RegMask] (unsigned Reg) {
RegMask[Reg / 32] &= ~(1u << Reg % 32);
};
// Scan all the physical registers. When a register is defined in the current
// function set it and all the aliasing registers as defined in the regmask.
for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
// Don't count registers that are saved and restored.
if (SavedRegs.test(PReg))
continue;
// If a register is defined by an instruction mark it as defined together
// with all it's unsaved aliases.
if (!MRI->def_empty(PReg)) {
for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI)
if (!SavedRegs.test(*AI))
SetRegAsDefined(*AI);
continue;
}
// If a register is in the UsedPhysRegsMask set then mark it as defined.
// All clobbered aliases will also be in the set, so we can skip setting
// as defined all the aliases here.
if (UsedPhysRegsMask.test(PReg))
SetRegAsDefined(PReg);
}
if (TargetFrameLowering::isSafeForNoCSROpt(F)) {
++NumCSROpt;
LLVM_DEBUG(dbgs() << MF.getName()
<< " function optimized for not having CSR.\n");
}
for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg)
if (MachineOperand::clobbersPhysReg(&(RegMask[0]), PReg))
LLVM_DEBUG(dbgs() << printReg(PReg, TRI) << " ");
LLVM_DEBUG(dbgs() << " \n----------------------------------------\n");
PRUI.storeUpdateRegUsageInfo(F, RegMask);
return false;
}
void RegUsageInfoCollector::
computeCalleeSavedRegs(BitVector &SavedRegs, MachineFunction &MF) {
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
// Target will return the set of registers that it saves/restores as needed.
SavedRegs.clear();
TFI.determineCalleeSaves(MF, SavedRegs);
// Insert subregs.
const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
for (unsigned i = 0; CSRegs[i]; ++i) {
unsigned Reg = CSRegs[i];
if (SavedRegs.test(Reg))
for (MCSubRegIterator SR(Reg, &TRI, false); SR.isValid(); ++SR)
SavedRegs.set(*SR);
}
// Insert any register fully saved via subregisters.
for (unsigned PReg = 1, PRegE = TRI.getNumRegs(); PReg < PRegE; ++PReg) {
if (SavedRegs.test(PReg))
continue;
// Check if PReg is fully covered by its subregs.
bool CoveredBySubRegs = false;
for (const TargetRegisterClass *RC : TRI.regclasses())
if (RC->CoveredBySubRegs && RC->contains(PReg)) {
CoveredBySubRegs = true;
break;
}
if (!CoveredBySubRegs)
continue;
// Add PReg to SavedRegs if all subregs are saved.
bool AllSubRegsSaved = true;
for (MCSubRegIterator SR(PReg, &TRI, false); SR.isValid(); ++SR)
if (!SavedRegs.test(*SR)) {
AllSubRegsSaved = false;
break;
}
if (AllSubRegsSaved)
SavedRegs.set(PReg);
}
}
|