xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SystemZ/SystemZCopyPhysRegs.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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;
SystemZCopyPhysRegs()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",
5404eeddc0SDimitry Andric                 "SystemZ Copy Physregs", false, false)
555ffd83dbSDimitry Andric 
createSystemZCopyPhysRegsPass(SystemZTargetMachine & TM)565ffd83dbSDimitry Andric FunctionPass *llvm::createSystemZCopyPhysRegsPass(SystemZTargetMachine &TM) {
575ffd83dbSDimitry Andric   return new SystemZCopyPhysRegs();
585ffd83dbSDimitry Andric }
595ffd83dbSDimitry Andric 
getAnalysisUsage(AnalysisUsage & AU) const605ffd83dbSDimitry Andric void SystemZCopyPhysRegs::getAnalysisUsage(AnalysisUsage &AU) const {
615ffd83dbSDimitry Andric   AU.setPreservesCFG();
625ffd83dbSDimitry Andric   MachineFunctionPass::getAnalysisUsage(AU);
635ffd83dbSDimitry Andric }
645ffd83dbSDimitry Andric 
visitMBB(MachineBasicBlock & MBB)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 
runOnMachineFunction(MachineFunction & F)1025ffd83dbSDimitry Andric bool SystemZCopyPhysRegs::runOnMachineFunction(MachineFunction &F) {
103*81ad6265SDimitry Andric   TII = F.getSubtarget<SystemZSubtarget>().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