ReducerWorkItem.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. //===- ReducerWorkItem.cpp - Wrapper for Module and MachineFunction -------===//
  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. #include "ReducerWorkItem.h"
  9. #include "llvm/CodeGen/MIRParser/MIRParser.h"
  10. #include "llvm/CodeGen/MIRPrinter.h"
  11. #include "llvm/CodeGen/MachineDominators.h"
  12. #include "llvm/CodeGen/MachineFunction.h"
  13. #include "llvm/CodeGen/MachineFunctionPass.h"
  14. #include "llvm/CodeGen/MachineRegisterInfo.h"
  15. #include "llvm/CodeGen/TargetInstrInfo.h"
  16. #include "llvm/IR/Verifier.h"
  17. #include "llvm/IRReader/IRReader.h"
  18. #include "llvm/Target/TargetMachine.h"
  19. #include "llvm/Transforms/Utils/Cloning.h"
  20. static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF) {
  21. auto DstMF = std::make_unique<MachineFunction>(
  22. SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(),
  23. SrcMF->getFunctionNumber(), SrcMF->getMMI());
  24. DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB;
  25. DenseMap<Register, Register> Src2DstReg;
  26. auto *SrcMRI = &SrcMF->getRegInfo();
  27. auto *DstMRI = &DstMF->getRegInfo();
  28. // Create vregs.
  29. for (auto &SrcMBB : *SrcMF) {
  30. for (auto &SrcMI : SrcMBB) {
  31. for (unsigned I = 0, E = SrcMI.getNumOperands(); I < E; ++I) {
  32. auto &DMO = SrcMI.getOperand(I);
  33. if (!DMO.isReg() || !DMO.isDef())
  34. continue;
  35. Register SrcReg = DMO.getReg();
  36. if (Register::isPhysicalRegister(SrcReg))
  37. continue;
  38. auto SrcRC = SrcMRI->getRegClass(SrcReg);
  39. auto DstReg = DstMRI->createVirtualRegister(SrcRC);
  40. Src2DstReg[SrcReg] = DstReg;
  41. }
  42. }
  43. }
  44. // Clone blocks.
  45. for (auto &SrcMBB : *SrcMF)
  46. Src2DstMBB[&SrcMBB] = DstMF->CreateMachineBasicBlock();
  47. // Link blocks.
  48. for (auto &SrcMBB : *SrcMF) {
  49. auto *DstMBB = Src2DstMBB[&SrcMBB];
  50. DstMF->push_back(DstMBB);
  51. for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end();
  52. It != IterEnd; ++It) {
  53. auto *SrcSuccMBB = *It;
  54. auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB];
  55. DstMBB->addSuccessor(DstSuccMBB);
  56. }
  57. for (auto &LI : SrcMBB.liveins())
  58. DstMBB->addLiveIn(LI);
  59. }
  60. // Clone instructions.
  61. for (auto &SrcMBB : *SrcMF) {
  62. auto *DstMBB = Src2DstMBB[&SrcMBB];
  63. for (auto &SrcMI : SrcMBB) {
  64. const auto &MCID =
  65. DstMF->getSubtarget().getInstrInfo()->get(SrcMI.getOpcode());
  66. auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(),
  67. /*NoImplicit=*/true);
  68. DstMBB->push_back(DstMI);
  69. for (auto &SrcMO : SrcMI.operands()) {
  70. MachineOperand DstMO(SrcMO);
  71. DstMO.clearParent();
  72. // Update vreg.
  73. if (DstMO.isReg() && Src2DstReg.count(DstMO.getReg())) {
  74. DstMO.setReg(Src2DstReg[DstMO.getReg()]);
  75. }
  76. // Update MBB.
  77. if (DstMO.isMBB()) {
  78. DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
  79. }
  80. DstMI->addOperand(DstMO);
  81. }
  82. DstMI->setMemRefs(*DstMF, SrcMI.memoperands());
  83. }
  84. }
  85. DstMF->verify(nullptr, "", /*AbortOnError=*/true);
  86. return DstMF;
  87. }
  88. std::unique_ptr<ReducerWorkItem> parseReducerWorkItem(StringRef Filename,
  89. LLVMContext &Ctxt,
  90. MachineModuleInfo *MMI) {
  91. auto MMM = std::make_unique<ReducerWorkItem>();
  92. if (MMI) {
  93. auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
  94. std::unique_ptr<MIRParser> MParser =
  95. createMIRParser(std::move(FileOrErr.get()), Ctxt);
  96. auto SetDataLayout =
  97. [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> {
  98. return MMI->getTarget().createDataLayout().getStringRepresentation();
  99. };
  100. std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
  101. MParser->parseMachineFunctions(*M, *MMI);
  102. MachineFunction *MF = nullptr;
  103. for (auto &F : *M) {
  104. if (auto *MF4F = MMI->getMachineFunction(F)) {
  105. // XXX: Maybe it would not be a lot of effort to handle multiple MFs by
  106. // simply storing them in a ReducerWorkItem::SmallVector or similar. The
  107. // single MF use-case seems a lot more common though so that will do for
  108. // now.
  109. assert(!MF && "Only single MF supported!");
  110. MF = MF4F;
  111. }
  112. }
  113. assert(MF && "No MF found!");
  114. MMM->M = std::move(M);
  115. MMM->MF = cloneMF(MF);
  116. } else {
  117. SMDiagnostic Err;
  118. std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt);
  119. if (!Result) {
  120. Err.print("llvm-reduce", errs());
  121. return std::unique_ptr<ReducerWorkItem>();
  122. }
  123. MMM->M = std::move(Result);
  124. }
  125. if (verifyReducerWorkItem(*MMM, &errs())) {
  126. errs() << "Error: " << Filename << " - input module is broken!\n";
  127. return std::unique_ptr<ReducerWorkItem>();
  128. }
  129. return MMM;
  130. }
  131. std::unique_ptr<ReducerWorkItem>
  132. cloneReducerWorkItem(const ReducerWorkItem &MMM) {
  133. auto CloneMMM = std::make_unique<ReducerWorkItem>();
  134. if (MMM.MF) {
  135. // Note that we cannot clone the Module as then we would need a way to
  136. // updated the cloned MachineFunction's IR references.
  137. // XXX: Actually have a look at
  138. // std::unique_ptr<Module> CloneModule(const Module &M, ValueToValueMapTy
  139. // &VMap);
  140. CloneMMM->M = MMM.M;
  141. CloneMMM->MF = cloneMF(MMM.MF.get());
  142. } else {
  143. CloneMMM->M = CloneModule(*MMM.M);
  144. }
  145. return CloneMMM;
  146. }
  147. bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) {
  148. if (verifyModule(*MMM.M, OS))
  149. return true;
  150. if (MMM.MF && !MMM.MF->verify(nullptr, "", /*AbortOnError=*/false))
  151. return true;
  152. return false;
  153. }
  154. void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
  155. if (MF) {
  156. printMIR(ROS, *M);
  157. printMIR(ROS, *MF);
  158. } else {
  159. M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
  160. /*ShouldPreserveUseListOrder=*/true);
  161. }
  162. }