diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:41:05 +0000 | 
| commit | 01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch) | |
| tree | 4def12e759965de927d963ac65840d663ef9d1ea /lib/CodeGen/RegUsageInfoCollector.cpp | |
| parent | f0f4822ed4b66e3579e92a89f368f8fb860e218e (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/RegUsageInfoCollector.cpp')
| -rw-r--r-- | lib/CodeGen/RegUsageInfoCollector.cpp | 142 | 
1 files changed, 142 insertions, 0 deletions
diff --git a/lib/CodeGen/RegUsageInfoCollector.cpp b/lib/CodeGen/RegUsageInfoCollector.cpp new file mode 100644 index 000000000000..50b885423375 --- /dev/null +++ b/lib/CodeGen/RegUsageInfoCollector.cpp @@ -0,0 +1,142 @@ +//===-- 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/Target/TargetFrameLowering.h" + +using namespace llvm; + +#define DEBUG_TYPE "ip-regalloc" + +STATISTIC(NumCSROpt, +          "Number of functions optimized for callee saved registers"); + +namespace llvm { +void initializeRegUsageInfoCollectorPass(PassRegistry &); +} + +namespace { +class RegUsageInfoCollector : public MachineFunctionPass { +public: +  RegUsageInfoCollector() : MachineFunctionPass(ID) { +    PassRegistry &Registry = *PassRegistry::getPassRegistry(); +    initializeRegUsageInfoCollectorPass(Registry); +  } + +  const char *getPassName() const override { +    return "Register Usage Information Collector Pass"; +  } + +  void getAnalysisUsage(AnalysisUsage &AU) const override; + +  bool runOnMachineFunction(MachineFunction &MF) override; + +  static char ID; + +private: +  void markRegClobbered(const TargetRegisterInfo *TRI, uint32_t *RegMask, +                        unsigned PReg); +}; +} // 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(); +} + +void RegUsageInfoCollector::markRegClobbered(const TargetRegisterInfo *TRI, +                                             uint32_t *RegMask, unsigned PReg) { +  // If PReg is clobbered then all of its alias are also clobbered. +  for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI) +    RegMask[*AI / 32] &= ~(1u << *AI % 32); +} + +void RegUsageInfoCollector::getAnalysisUsage(AnalysisUsage &AU) const { +  AU.addRequired<PhysicalRegisterUsageInfo>(); +  AU.setPreservesAll(); +  MachineFunctionPass::getAnalysisUsage(AU); +} + +bool RegUsageInfoCollector::runOnMachineFunction(MachineFunction &MF) { +  MachineRegisterInfo *MRI = &MF.getRegInfo(); +  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); +  const TargetMachine &TM = MF.getTarget(); + +  DEBUG(dbgs() << " -------------------- " << getPassName() +               << " -------------------- \n"); +  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 = (TRI->getNumRegs() + 31) / 32; +  RegMask.resize(RegMaskSize, 0xFFFFFFFF); + +  const Function *F = MF.getFunction(); + +  PhysicalRegisterUsageInfo *PRUI = &getAnalysis<PhysicalRegisterUsageInfo>(); + +  PRUI->setTargetMachine(&TM); + +  DEBUG(dbgs() << "Clobbered Registers: "); + +  for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) +    if (MRI->isPhysRegModified(PReg, true)) +      markRegClobbered(TRI, &RegMask[0], PReg); + +  if (!TargetFrameLowering::isSafeForNoCSROpt(F)) { +    const uint32_t *CallPreservedMask = +        TRI->getCallPreservedMask(MF, F->getCallingConv()); +    // Set callee saved register as preserved. +    for (unsigned i = 0; i < RegMaskSize; ++i) +      RegMask[i] = RegMask[i] | CallPreservedMask[i]; +  } else { +    ++NumCSROpt; +    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)) +      DEBUG(dbgs() << TRI->getName(PReg) << " "); + +  DEBUG(dbgs() << " \n----------------------------------------\n"); + +  PRUI->storeUpdateRegUsageInfo(F, std::move(RegMask)); + +  return false; +}  | 
