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