Home | History | Annotate | Line # | Download | only in SystemZ
      1 //===---------- SystemZPhysRegCopy.cpp - Handle phys reg copies -----------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This pass makes sure that a COPY of a physical register will be
     10 // implementable after register allocation in copyPhysReg() (this could be
     11 // done in EmitInstrWithCustomInserter() instead if COPY instructions would
     12 // be passed to it).
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "SystemZMachineFunctionInfo.h"
     17 #include "SystemZTargetMachine.h"
     18 #include "llvm/CodeGen/MachineDominators.h"
     19 #include "llvm/CodeGen/MachineFunctionPass.h"
     20 #include "llvm/CodeGen/MachineInstrBuilder.h"
     21 #include "llvm/CodeGen/MachineRegisterInfo.h"
     22 #include "llvm/CodeGen/TargetInstrInfo.h"
     23 #include "llvm/CodeGen/TargetRegisterInfo.h"
     24 #include "llvm/Target/TargetMachine.h"
     25 
     26 using namespace llvm;
     27 
     28 #define SYSTEMZ_COPYPHYSREGS_NAME "SystemZ Copy Physregs"
     29 
     30 namespace llvm {
     31   void initializeSystemZCopyPhysRegsPass(PassRegistry&);
     32 }
     33 
     34 namespace {
     35 
     36 class SystemZCopyPhysRegs : public MachineFunctionPass {
     37 public:
     38   static char ID;
     39   SystemZCopyPhysRegs()
     40     : MachineFunctionPass(ID), TII(nullptr), MRI(nullptr) {
     41     initializeSystemZCopyPhysRegsPass(*PassRegistry::getPassRegistry());
     42   }
     43 
     44   StringRef getPassName() const override { return SYSTEMZ_COPYPHYSREGS_NAME; }
     45 
     46   bool runOnMachineFunction(MachineFunction &MF) override;
     47   void getAnalysisUsage(AnalysisUsage &AU) const override;
     48 
     49 private:
     50 
     51   bool visitMBB(MachineBasicBlock &MBB);
     52 
     53   const SystemZInstrInfo *TII;
     54   MachineRegisterInfo *MRI;
     55 };
     56 
     57 char SystemZCopyPhysRegs::ID = 0;
     58 
     59 } // end anonymous namespace
     60 
     61 INITIALIZE_PASS(SystemZCopyPhysRegs, "systemz-copy-physregs",
     62                 SYSTEMZ_COPYPHYSREGS_NAME, false, false)
     63 
     64 FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) {
     65   return new SystemZCopyPhysRegs();
     66 }
     67 
     68 void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const {
     69   AU.setPreservesCFG();
     70   MachineFunctionPass::getAnalysisUsage(AU);
     71 }
     72 
     73 bool SystemZCopyPhysRegs::visitMBB(MachineBasicBlock &MBB) {
     74   bool Modified = false;
     75 
     76   // Certain special registers can only be copied from a subset of the
     77   // default register class of the type. It is therefore necessary to create
     78   // the target copy instructions before regalloc instead of in copyPhysReg().
     79   for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
     80        MBBI != E; ) {
     81     MachineInstr *MI = &*MBBI++;
     82     if (!MI->isCopy())
     83       continue;
     84 
     85     DebugLoc DL = MI->getDebugLoc();
     86     Register SrcReg = MI->getOperand(1).getReg();
     87     Register DstReg = MI->getOperand(0).getReg();
     88     if (DstReg.isVirtual() &&
     89         (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(SrcReg))) {
     90       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
     91       if (SrcReg == SystemZ::CC)
     92         BuildMI(MBB, MI, DL, TII->get(SystemZ::IPM), Tmp);
     93       else
     94         BuildMI(MBB, MI, DL, TII->get(SystemZ::EAR), Tmp).addReg(SrcReg);
     95       MI->getOperand(1).setReg(Tmp);
     96       Modified = true;
     97     }
     98     else if (SrcReg.isVirtual() &&
     99              SystemZ::AR32BitRegClass.contains(DstReg)) {
    100       Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass);
    101       MI->getOperand(0).setReg(Tmp);
    102       BuildMI(MBB, MBBI, DL, TII->get(SystemZ::SAR), DstReg).addReg(Tmp);
    103       Modified = true;
    104     }
    105   }
    106 
    107   return Modified;
    108 }
    109 
    110 bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) {
    111   TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo());
    112   MRI = &F.getRegInfo();
    113 
    114   bool Modified = false;
    115   for (auto &MBB : F)
    116     Modified |= visitMBB(MBB);
    117 
    118   return Modified;
    119 }
    120 
    121