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