PPCVSXCopy.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. //===-------------- PPCVSXCopy.cpp - VSX Copy Legalization ----------------===//
  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. // A pass which deals with the complexity of generating legal VSX register
  10. // copies to/from register classes which partially overlap with the VSX
  11. // register file.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "MCTargetDesc/PPCPredicates.h"
  15. #include "PPC.h"
  16. #include "PPCHazardRecognizers.h"
  17. #include "PPCInstrBuilder.h"
  18. #include "PPCInstrInfo.h"
  19. #include "PPCMachineFunctionInfo.h"
  20. #include "PPCTargetMachine.h"
  21. #include "llvm/ADT/STLExtras.h"
  22. #include "llvm/ADT/Statistic.h"
  23. #include "llvm/CodeGen/MachineFrameInfo.h"
  24. #include "llvm/CodeGen/MachineFunctionPass.h"
  25. #include "llvm/CodeGen/MachineInstrBuilder.h"
  26. #include "llvm/CodeGen/MachineMemOperand.h"
  27. #include "llvm/CodeGen/MachineRegisterInfo.h"
  28. #include "llvm/MC/MCAsmInfo.h"
  29. #include "llvm/MC/TargetRegistry.h"
  30. #include "llvm/Support/Debug.h"
  31. #include "llvm/Support/ErrorHandling.h"
  32. #include "llvm/Support/raw_ostream.h"
  33. using namespace llvm;
  34. #define DEBUG_TYPE "ppc-vsx-copy"
  35. namespace {
  36. // PPCVSXCopy pass - For copies between VSX registers and non-VSX registers
  37. // (Altivec and scalar floating-point registers), we need to transform the
  38. // copies into subregister copies with other restrictions.
  39. struct PPCVSXCopy : public MachineFunctionPass {
  40. static char ID;
  41. PPCVSXCopy() : MachineFunctionPass(ID) {
  42. initializePPCVSXCopyPass(*PassRegistry::getPassRegistry());
  43. }
  44. const TargetInstrInfo *TII;
  45. bool IsRegInClass(unsigned Reg, const TargetRegisterClass *RC,
  46. MachineRegisterInfo &MRI) {
  47. if (Register::isVirtualRegister(Reg)) {
  48. return RC->hasSubClassEq(MRI.getRegClass(Reg));
  49. } else if (RC->contains(Reg)) {
  50. return true;
  51. }
  52. return false;
  53. }
  54. bool IsVSReg(unsigned Reg, MachineRegisterInfo &MRI) {
  55. return IsRegInClass(Reg, &PPC::VSRCRegClass, MRI);
  56. }
  57. bool IsVRReg(unsigned Reg, MachineRegisterInfo &MRI) {
  58. return IsRegInClass(Reg, &PPC::VRRCRegClass, MRI);
  59. }
  60. bool IsF8Reg(unsigned Reg, MachineRegisterInfo &MRI) {
  61. return IsRegInClass(Reg, &PPC::F8RCRegClass, MRI);
  62. }
  63. bool IsVSFReg(unsigned Reg, MachineRegisterInfo &MRI) {
  64. return IsRegInClass(Reg, &PPC::VSFRCRegClass, MRI);
  65. }
  66. bool IsVSSReg(unsigned Reg, MachineRegisterInfo &MRI) {
  67. return IsRegInClass(Reg, &PPC::VSSRCRegClass, MRI);
  68. }
  69. protected:
  70. bool processBlock(MachineBasicBlock &MBB) {
  71. bool Changed = false;
  72. MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
  73. for (MachineInstr &MI : MBB) {
  74. if (!MI.isFullCopy())
  75. continue;
  76. MachineOperand &DstMO = MI.getOperand(0);
  77. MachineOperand &SrcMO = MI.getOperand(1);
  78. if ( IsVSReg(DstMO.getReg(), MRI) &&
  79. !IsVSReg(SrcMO.getReg(), MRI)) {
  80. // This is a copy *to* a VSX register from a non-VSX register.
  81. Changed = true;
  82. const TargetRegisterClass *SrcRC = &PPC::VSLRCRegClass;
  83. assert((IsF8Reg(SrcMO.getReg(), MRI) ||
  84. IsVSSReg(SrcMO.getReg(), MRI) ||
  85. IsVSFReg(SrcMO.getReg(), MRI)) &&
  86. "Unknown source for a VSX copy");
  87. Register NewVReg = MRI.createVirtualRegister(SrcRC);
  88. BuildMI(MBB, MI, MI.getDebugLoc(),
  89. TII->get(TargetOpcode::SUBREG_TO_REG), NewVReg)
  90. .addImm(1) // add 1, not 0, because there is no implicit clearing
  91. // of the high bits.
  92. .add(SrcMO)
  93. .addImm(PPC::sub_64);
  94. // The source of the original copy is now the new virtual register.
  95. SrcMO.setReg(NewVReg);
  96. } else if (!IsVSReg(DstMO.getReg(), MRI) &&
  97. IsVSReg(SrcMO.getReg(), MRI)) {
  98. // This is a copy *from* a VSX register to a non-VSX register.
  99. Changed = true;
  100. const TargetRegisterClass *DstRC = &PPC::VSLRCRegClass;
  101. assert((IsF8Reg(DstMO.getReg(), MRI) ||
  102. IsVSFReg(DstMO.getReg(), MRI) ||
  103. IsVSSReg(DstMO.getReg(), MRI)) &&
  104. "Unknown destination for a VSX copy");
  105. // Copy the VSX value into a new VSX register of the correct subclass.
  106. Register NewVReg = MRI.createVirtualRegister(DstRC);
  107. BuildMI(MBB, MI, MI.getDebugLoc(), TII->get(TargetOpcode::COPY),
  108. NewVReg)
  109. .add(SrcMO);
  110. // Transform the original copy into a subregister extraction copy.
  111. SrcMO.setReg(NewVReg);
  112. SrcMO.setSubReg(PPC::sub_64);
  113. }
  114. }
  115. return Changed;
  116. }
  117. public:
  118. bool runOnMachineFunction(MachineFunction &MF) override {
  119. // If we don't have VSX on the subtarget, don't do anything.
  120. const PPCSubtarget &STI = MF.getSubtarget<PPCSubtarget>();
  121. if (!STI.hasVSX())
  122. return false;
  123. TII = STI.getInstrInfo();
  124. bool Changed = false;
  125. for (MachineBasicBlock &B : llvm::make_early_inc_range(MF))
  126. if (processBlock(B))
  127. Changed = true;
  128. return Changed;
  129. }
  130. void getAnalysisUsage(AnalysisUsage &AU) const override {
  131. MachineFunctionPass::getAnalysisUsage(AU);
  132. }
  133. };
  134. }
  135. INITIALIZE_PASS(PPCVSXCopy, DEBUG_TYPE,
  136. "PowerPC VSX Copy Legalization", false, false)
  137. char PPCVSXCopy::ID = 0;
  138. FunctionPass*
  139. llvm::createPPCVSXCopyPass() { return new PPCVSXCopy(); }