15ffd83dbSDimitry Andric //===---------- SystemZPhysRegCopy.cpp - Handle phys reg copies -----------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric // 95ffd83dbSDimitry Andric // This pass makes sure that a COPY of a physical register will be 105ffd83dbSDimitry Andric // implementable after register allocation in copyPhysReg() (this could be 115ffd83dbSDimitry Andric // done in EmitInstrWithCustomInserter() instead if COPY instructions would 125ffd83dbSDimitry Andric // be passed to it). 135ffd83dbSDimitry Andric // 145ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 155ffd83dbSDimitry Andric 165ffd83dbSDimitry Andric #include "SystemZMachineFunctionInfo.h" 175ffd83dbSDimitry Andric #include "SystemZTargetMachine.h" 185ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineDominators.h" 195ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 205ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 215ffd83dbSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 225ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 235ffd83dbSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 245ffd83dbSDimitry Andric #include "llvm/Target/TargetMachine.h" 255ffd83dbSDimitry Andric 265ffd83dbSDimitry Andric using namespace llvm; 275ffd83dbSDimitry Andric 285ffd83dbSDimitry Andric namespace { 295ffd83dbSDimitry Andric 305ffd83dbSDimitry Andric class SystemZCopyPhysRegs : public MachineFunctionPass { 315ffd83dbSDimitry Andric public: 325ffd83dbSDimitry Andric static char ID; 335ffd83dbSDimitry Andric SystemZCopyPhysRegs() 345ffd83dbSDimitry Andric : MachineFunctionPass(ID), TII(nullptr), MRI(nullptr) { 355ffd83dbSDimitry Andric initializeSystemZCopyPhysRegsPass(*PassRegistry::getPassRegistry()); 365ffd83dbSDimitry Andric } 375ffd83dbSDimitry Andric 385ffd83dbSDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 395ffd83dbSDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override; 405ffd83dbSDimitry Andric 415ffd83dbSDimitry Andric private: 425ffd83dbSDimitry Andric 435ffd83dbSDimitry Andric bool visitMBB(MachineBasicBlock &MBB); 445ffd83dbSDimitry Andric 455ffd83dbSDimitry Andric const SystemZInstrInfo *TII; 465ffd83dbSDimitry Andric MachineRegisterInfo *MRI; 475ffd83dbSDimitry Andric }; 485ffd83dbSDimitry Andric 495ffd83dbSDimitry Andric char SystemZCopyPhysRegs::ID = 0; 505ffd83dbSDimitry Andric 515ffd83dbSDimitry Andric } // end anonymous namespace 525ffd83dbSDimitry Andric 535ffd83dbSDimitry Andric INITIALIZE_PASS(SystemZCopyPhysRegs, "systemz-copy-physregs", 54*04eeddc0SDimitry Andric "SystemZ Copy Physregs", false, false) 555ffd83dbSDimitry Andric 565ffd83dbSDimitry Andric FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) { 575ffd83dbSDimitry Andric return new SystemZCopyPhysRegs(); 585ffd83dbSDimitry Andric } 595ffd83dbSDimitry Andric 605ffd83dbSDimitry Andric void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const { 615ffd83dbSDimitry Andric AU.setPreservesCFG(); 625ffd83dbSDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 635ffd83dbSDimitry Andric } 645ffd83dbSDimitry Andric 655ffd83dbSDimitry Andric bool SystemZCopyPhysRegs::visitMBB(MachineBasicBlock &MBB) { 665ffd83dbSDimitry Andric bool Modified = false; 675ffd83dbSDimitry Andric 685ffd83dbSDimitry Andric // Certain special registers can only be copied from a subset of the 695ffd83dbSDimitry Andric // default register class of the type. It is therefore necessary to create 705ffd83dbSDimitry Andric // the target copy instructions before regalloc instead of in copyPhysReg(). 715ffd83dbSDimitry Andric for (MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 725ffd83dbSDimitry Andric MBBI != E; ) { 735ffd83dbSDimitry Andric MachineInstr *MI = &*MBBI++; 745ffd83dbSDimitry Andric if (!MI->isCopy()) 755ffd83dbSDimitry Andric continue; 765ffd83dbSDimitry Andric 775ffd83dbSDimitry Andric DebugLoc DL = MI->getDebugLoc(); 785ffd83dbSDimitry Andric Register SrcReg = MI->getOperand(1).getReg(); 795ffd83dbSDimitry Andric Register DstReg = MI->getOperand(0).getReg(); 805ffd83dbSDimitry Andric if (DstReg.isVirtual() && 815ffd83dbSDimitry Andric (SrcReg == SystemZ::CC || SystemZ::AR32BitRegClass.contains(SrcReg))) { 825ffd83dbSDimitry Andric Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass); 835ffd83dbSDimitry Andric if (SrcReg == SystemZ::CC) 845ffd83dbSDimitry Andric BuildMI(MBB, MI, DL, TII->get(SystemZ::IPM), Tmp); 855ffd83dbSDimitry Andric else 865ffd83dbSDimitry Andric BuildMI(MBB, MI, DL, TII->get(SystemZ::EAR), Tmp).addReg(SrcReg); 875ffd83dbSDimitry Andric MI->getOperand(1).setReg(Tmp); 885ffd83dbSDimitry Andric Modified = true; 895ffd83dbSDimitry Andric } 905ffd83dbSDimitry Andric else if (SrcReg.isVirtual() && 915ffd83dbSDimitry Andric SystemZ::AR32BitRegClass.contains(DstReg)) { 925ffd83dbSDimitry Andric Register Tmp = MRI->createVirtualRegister(&SystemZ::GR32BitRegClass); 935ffd83dbSDimitry Andric MI->getOperand(0).setReg(Tmp); 945ffd83dbSDimitry Andric BuildMI(MBB, MBBI, DL, TII->get(SystemZ::SAR), DstReg).addReg(Tmp); 955ffd83dbSDimitry Andric Modified = true; 965ffd83dbSDimitry Andric } 975ffd83dbSDimitry Andric } 985ffd83dbSDimitry Andric 995ffd83dbSDimitry Andric return Modified; 1005ffd83dbSDimitry Andric } 1015ffd83dbSDimitry Andric 1025ffd83dbSDimitry Andric bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) { 1035ffd83dbSDimitry Andric TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo()); 1045ffd83dbSDimitry Andric MRI = &F.getRegInfo(); 1055ffd83dbSDimitry Andric 1065ffd83dbSDimitry Andric bool Modified = false; 1075ffd83dbSDimitry Andric for (auto &MBB : F) 1085ffd83dbSDimitry Andric Modified |= visitMBB(MBB); 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric return Modified; 1115ffd83dbSDimitry Andric } 1125ffd83dbSDimitry Andric 113