NVPTXProxyRegErasure.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. //===- NVPTXProxyRegErasure.cpp - NVPTX Proxy Register Instruction Erasure -==//
  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. // The pass is needed to remove ProxyReg instructions and restore related
  10. // registers. The instructions were needed at instruction selection stage to
  11. // make sure that callseq_end nodes won't be removed as "dead nodes". This can
  12. // happen when we expand instructions into libcalls and the call site doesn't
  13. // care about the libcall chain. Call site cares about data flow only, and the
  14. // latest data flow node happens to be before callseq_end. Therefore the node
  15. // becomes dangling and "dead". The ProxyReg acts like an additional data flow
  16. // node *after* the callseq_end in the chain and ensures that everything will be
  17. // preserved.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #include "NVPTX.h"
  21. #include "llvm/CodeGen/MachineFunctionPass.h"
  22. #include "llvm/CodeGen/MachineInstrBuilder.h"
  23. #include "llvm/CodeGen/MachineRegisterInfo.h"
  24. #include "llvm/CodeGen/TargetInstrInfo.h"
  25. #include "llvm/CodeGen/TargetRegisterInfo.h"
  26. using namespace llvm;
  27. namespace llvm {
  28. void initializeNVPTXProxyRegErasurePass(PassRegistry &);
  29. }
  30. namespace {
  31. struct NVPTXProxyRegErasure : public MachineFunctionPass {
  32. public:
  33. static char ID;
  34. NVPTXProxyRegErasure() : MachineFunctionPass(ID) {
  35. initializeNVPTXProxyRegErasurePass(*PassRegistry::getPassRegistry());
  36. }
  37. bool runOnMachineFunction(MachineFunction &MF) override;
  38. StringRef getPassName() const override {
  39. return "NVPTX Proxy Register Instruction Erasure";
  40. }
  41. void getAnalysisUsage(AnalysisUsage &AU) const override {
  42. MachineFunctionPass::getAnalysisUsage(AU);
  43. }
  44. private:
  45. void replaceMachineInstructionUsage(MachineFunction &MF, MachineInstr &MI);
  46. void replaceRegisterUsage(MachineInstr &Instr, MachineOperand &From,
  47. MachineOperand &To);
  48. };
  49. } // namespace
  50. char NVPTXProxyRegErasure::ID = 0;
  51. INITIALIZE_PASS(NVPTXProxyRegErasure, "nvptx-proxyreg-erasure", "NVPTX ProxyReg Erasure", false, false)
  52. bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
  53. SmallVector<MachineInstr *, 16> RemoveList;
  54. for (auto &BB : MF) {
  55. for (auto &MI : BB) {
  56. switch (MI.getOpcode()) {
  57. case NVPTX::ProxyRegI1:
  58. case NVPTX::ProxyRegI16:
  59. case NVPTX::ProxyRegI32:
  60. case NVPTX::ProxyRegI64:
  61. case NVPTX::ProxyRegF16:
  62. case NVPTX::ProxyRegF16x2:
  63. case NVPTX::ProxyRegF32:
  64. case NVPTX::ProxyRegF64:
  65. replaceMachineInstructionUsage(MF, MI);
  66. RemoveList.push_back(&MI);
  67. break;
  68. }
  69. }
  70. }
  71. for (auto *MI : RemoveList) {
  72. MI->eraseFromParent();
  73. }
  74. return !RemoveList.empty();
  75. }
  76. void NVPTXProxyRegErasure::replaceMachineInstructionUsage(MachineFunction &MF,
  77. MachineInstr &MI) {
  78. auto &InOp = *MI.uses().begin();
  79. auto &OutOp = *MI.defs().begin();
  80. assert(InOp.isReg() && "ProxyReg input operand should be a register.");
  81. assert(OutOp.isReg() && "ProxyReg output operand should be a register.");
  82. for (auto &BB : MF) {
  83. for (auto &I : BB) {
  84. replaceRegisterUsage(I, OutOp, InOp);
  85. }
  86. }
  87. }
  88. void NVPTXProxyRegErasure::replaceRegisterUsage(MachineInstr &Instr,
  89. MachineOperand &From,
  90. MachineOperand &To) {
  91. for (auto &Op : Instr.uses()) {
  92. if (Op.isReg() && Op.getReg() == From.getReg()) {
  93. Op.setReg(To.getReg());
  94. }
  95. }
  96. }
  97. MachineFunctionPass *llvm::createNVPTXProxyRegErasurePass() {
  98. return new NVPTXProxyRegErasure();
  99. }