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/Bitcode/BitcodeReader.h"
11 #include "llvm/CodeGen/CommandFlags.h"
12 #include "llvm/CodeGen/MIRParser/MIRParser.h"
13 #include "llvm/CodeGen/MIRPrinter.h"
14 #include "llvm/CodeGen/MachineDominators.h"
15 #include "llvm/CodeGen/MachineFrameInfo.h"
16 #include "llvm/CodeGen/MachineFunction.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineModuleInfo.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/CodeGen/TargetInstrInfo.h"
21 #include "llvm/IR/ModuleSummaryIndex.h"
22 #include "llvm/IR/Verifier.h"
23 #include "llvm/IRReader/IRReader.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/Host.h"
26 #include "llvm/Support/MemoryBufferRef.h"
27 #include "llvm/Support/SourceMgr.h"
28 #include "llvm/Support/TargetSelect.h"
29 #include "llvm/Support/WithColor.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Transforms/Utils/Cloning.h"
32 
33 extern cl::OptionCategory LLVMReduceOptions;
34 static cl::opt<std::string> TargetTriple("mtriple",
35                                          cl::desc("Set the target triple"),
36                                          cl::cat(LLVMReduceOptions));
37 
38 void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx, const char *ToolName);
39 
cloneFrameInfo(MachineFrameInfo & DstMFI,const MachineFrameInfo & SrcMFI,const DenseMap<MachineBasicBlock *,MachineBasicBlock * > & Src2DstMBB)40 static void cloneFrameInfo(
41     MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI,
42     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) {
43   DstMFI.setFrameAddressIsTaken(SrcMFI.isFrameAddressTaken());
44   DstMFI.setReturnAddressIsTaken(SrcMFI.isReturnAddressTaken());
45   DstMFI.setHasStackMap(SrcMFI.hasStackMap());
46   DstMFI.setHasPatchPoint(SrcMFI.hasPatchPoint());
47   DstMFI.setUseLocalStackAllocationBlock(
48       SrcMFI.getUseLocalStackAllocationBlock());
49   DstMFI.setOffsetAdjustment(SrcMFI.getOffsetAdjustment());
50 
51   DstMFI.ensureMaxAlignment(SrcMFI.getMaxAlign());
52   assert(DstMFI.getMaxAlign() == SrcMFI.getMaxAlign() &&
53          "we need to set exact alignment");
54 
55   DstMFI.setAdjustsStack(SrcMFI.adjustsStack());
56   DstMFI.setHasCalls(SrcMFI.hasCalls());
57   DstMFI.setHasOpaqueSPAdjustment(SrcMFI.hasOpaqueSPAdjustment());
58   DstMFI.setHasCopyImplyingStackAdjustment(
59       SrcMFI.hasCopyImplyingStackAdjustment());
60   DstMFI.setHasVAStart(SrcMFI.hasVAStart());
61   DstMFI.setHasMustTailInVarArgFunc(SrcMFI.hasMustTailInVarArgFunc());
62   DstMFI.setHasTailCall(SrcMFI.hasTailCall());
63 
64   if (SrcMFI.isMaxCallFrameSizeComputed())
65     DstMFI.setMaxCallFrameSize(SrcMFI.getMaxCallFrameSize());
66 
67   DstMFI.setCVBytesOfCalleeSavedRegisters(
68       SrcMFI.getCVBytesOfCalleeSavedRegisters());
69 
70   if (MachineBasicBlock *SavePt = SrcMFI.getSavePoint())
71     DstMFI.setSavePoint(Src2DstMBB.find(SavePt)->second);
72   if (MachineBasicBlock *RestorePt = SrcMFI.getRestorePoint())
73     DstMFI.setRestorePoint(Src2DstMBB.find(RestorePt)->second);
74 
75 
76   auto CopyObjectProperties = [](MachineFrameInfo &DstMFI,
77                                  const MachineFrameInfo &SrcMFI, int FI) {
78     if (SrcMFI.isStatepointSpillSlotObjectIndex(FI))
79       DstMFI.markAsStatepointSpillSlotObjectIndex(FI);
80     DstMFI.setObjectSSPLayout(FI, SrcMFI.getObjectSSPLayout(FI));
81     DstMFI.setObjectZExt(FI, SrcMFI.isObjectZExt(FI));
82     DstMFI.setObjectSExt(FI, SrcMFI.isObjectSExt(FI));
83   };
84 
85   for (int i = 0, e = SrcMFI.getNumObjects() - SrcMFI.getNumFixedObjects();
86        i != e; ++i) {
87     int NewFI;
88 
89     assert(!SrcMFI.isFixedObjectIndex(i));
90     if (SrcMFI.isVariableSizedObjectIndex(i)) {
91       NewFI = DstMFI.CreateVariableSizedObject(SrcMFI.getObjectAlign(i),
92                                                SrcMFI.getObjectAllocation(i));
93     } else {
94       NewFI = DstMFI.CreateStackObject(
95           SrcMFI.getObjectSize(i), SrcMFI.getObjectAlign(i),
96           SrcMFI.isSpillSlotObjectIndex(i), SrcMFI.getObjectAllocation(i),
97           SrcMFI.getStackID(i));
98       DstMFI.setObjectOffset(NewFI, SrcMFI.getObjectOffset(i));
99     }
100 
101     CopyObjectProperties(DstMFI, SrcMFI, i);
102 
103     (void)NewFI;
104     assert(i == NewFI && "expected to keep stable frame index numbering");
105   }
106 
107   // Copy the fixed frame objects backwards to preserve frame index numbers,
108   // since CreateFixedObject uses front insertion.
109   for (int i = -1; i >= (int)-SrcMFI.getNumFixedObjects(); --i) {
110     assert(SrcMFI.isFixedObjectIndex(i));
111     int NewFI = DstMFI.CreateFixedObject(
112       SrcMFI.getObjectSize(i), SrcMFI.getObjectOffset(i),
113       SrcMFI.isImmutableObjectIndex(i), SrcMFI.isAliasedObjectIndex(i));
114     CopyObjectProperties(DstMFI, SrcMFI, i);
115 
116     (void)NewFI;
117     assert(i == NewFI && "expected to keep stable frame index numbering");
118   }
119 
120   for (unsigned I = 0, E = SrcMFI.getLocalFrameObjectCount(); I < E; ++I) {
121     auto LocalObject = SrcMFI.getLocalFrameObjectMap(I);
122     DstMFI.mapLocalFrameObject(LocalObject.first, LocalObject.second);
123   }
124 
125   DstMFI.setCalleeSavedInfo(SrcMFI.getCalleeSavedInfo());
126 
127   if (SrcMFI.hasStackProtectorIndex()) {
128     DstMFI.setStackProtectorIndex(SrcMFI.getStackProtectorIndex());
129   }
130 
131   // FIXME: Needs test, missing MIR serialization.
132   if (SrcMFI.hasFunctionContextIndex()) {
133     DstMFI.setFunctionContextIndex(SrcMFI.getFunctionContextIndex());
134   }
135 }
136 
cloneMemOperands(MachineInstr & DstMI,MachineInstr & SrcMI,MachineFunction & SrcMF,MachineFunction & DstMF)137 static void cloneMemOperands(MachineInstr &DstMI, MachineInstr &SrcMI,
138                              MachineFunction &SrcMF, MachineFunction &DstMF) {
139   // The new MachineMemOperands should be owned by the new function's
140   // Allocator.
141   PseudoSourceValueManager &PSVMgr = DstMF.getPSVManager();
142 
143   // We also need to remap the PseudoSourceValues from the new function's
144   // PseudoSourceValueManager.
145   SmallVector<MachineMemOperand *, 2> NewMMOs;
146   for (MachineMemOperand *OldMMO : SrcMI.memoperands()) {
147     MachinePointerInfo NewPtrInfo(OldMMO->getPointerInfo());
148     if (const PseudoSourceValue *PSV =
149             NewPtrInfo.V.dyn_cast<const PseudoSourceValue *>()) {
150       switch (PSV->kind()) {
151       case PseudoSourceValue::Stack:
152         NewPtrInfo.V = PSVMgr.getStack();
153         break;
154       case PseudoSourceValue::GOT:
155         NewPtrInfo.V = PSVMgr.getGOT();
156         break;
157       case PseudoSourceValue::JumpTable:
158         NewPtrInfo.V = PSVMgr.getJumpTable();
159         break;
160       case PseudoSourceValue::ConstantPool:
161         NewPtrInfo.V = PSVMgr.getConstantPool();
162         break;
163       case PseudoSourceValue::FixedStack:
164         NewPtrInfo.V = PSVMgr.getFixedStack(
165             cast<FixedStackPseudoSourceValue>(PSV)->getFrameIndex());
166         break;
167       case PseudoSourceValue::GlobalValueCallEntry:
168         NewPtrInfo.V = PSVMgr.getGlobalValueCallEntry(
169             cast<GlobalValuePseudoSourceValue>(PSV)->getValue());
170         break;
171       case PseudoSourceValue::ExternalSymbolCallEntry:
172         NewPtrInfo.V = PSVMgr.getExternalSymbolCallEntry(
173             cast<ExternalSymbolPseudoSourceValue>(PSV)->getSymbol());
174         break;
175       case PseudoSourceValue::TargetCustom:
176       default:
177         // FIXME: We have no generic interface for allocating custom PSVs.
178         report_fatal_error("Cloning TargetCustom PSV not handled");
179       }
180     }
181 
182     MachineMemOperand *NewMMO = DstMF.getMachineMemOperand(
183         NewPtrInfo, OldMMO->getFlags(), OldMMO->getMemoryType(),
184         OldMMO->getBaseAlign(), OldMMO->getAAInfo(), OldMMO->getRanges(),
185         OldMMO->getSyncScopeID(), OldMMO->getSuccessOrdering(),
186         OldMMO->getFailureOrdering());
187     NewMMOs.push_back(NewMMO);
188   }
189 
190   DstMI.setMemRefs(DstMF, NewMMOs);
191 }
192 
cloneMF(MachineFunction * SrcMF,MachineModuleInfo & DestMMI)193 static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
194                                                 MachineModuleInfo &DestMMI) {
195   auto DstMF = std::make_unique<MachineFunction>(
196       SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(),
197       SrcMF->getFunctionNumber(), DestMMI);
198   DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB;
199 
200   auto *SrcMRI = &SrcMF->getRegInfo();
201   auto *DstMRI = &DstMF->getRegInfo();
202 
203   // Clone blocks.
204   for (MachineBasicBlock &SrcMBB : *SrcMF) {
205     MachineBasicBlock *DstMBB =
206         DstMF->CreateMachineBasicBlock(SrcMBB.getBasicBlock());
207     Src2DstMBB[&SrcMBB] = DstMBB;
208 
209     if (SrcMBB.hasAddressTaken())
210       DstMBB->setHasAddressTaken();
211 
212     // FIXME: This is not serialized
213     if (SrcMBB.hasLabelMustBeEmitted())
214       DstMBB->setLabelMustBeEmitted();
215 
216     DstMBB->setAlignment(SrcMBB.getAlignment());
217 
218     // FIXME: This is not serialized
219     DstMBB->setMaxBytesForAlignment(SrcMBB.getMaxBytesForAlignment());
220 
221     DstMBB->setIsEHPad(SrcMBB.isEHPad());
222     DstMBB->setIsEHScopeEntry(SrcMBB.isEHScopeEntry());
223     DstMBB->setIsEHCatchretTarget(SrcMBB.isEHCatchretTarget());
224     DstMBB->setIsEHFuncletEntry(SrcMBB.isEHFuncletEntry());
225 
226     // FIXME: These are not serialized
227     DstMBB->setIsCleanupFuncletEntry(SrcMBB.isCleanupFuncletEntry());
228     DstMBB->setIsBeginSection(SrcMBB.isBeginSection());
229     DstMBB->setIsEndSection(SrcMBB.isEndSection());
230 
231     DstMBB->setSectionID(SrcMBB.getSectionID());
232     DstMBB->setIsInlineAsmBrIndirectTarget(
233         SrcMBB.isInlineAsmBrIndirectTarget());
234 
235     // FIXME: This is not serialized
236     if (Optional<uint64_t> Weight = SrcMBB.getIrrLoopHeaderWeight())
237       DstMBB->setIrrLoopHeaderWeight(*Weight);
238   }
239 
240   const MachineFrameInfo &SrcMFI = SrcMF->getFrameInfo();
241   MachineFrameInfo &DstMFI = DstMF->getFrameInfo();
242 
243   // Copy stack objects and other info
244   cloneFrameInfo(DstMFI, SrcMFI, Src2DstMBB);
245 
246   // Remap the debug info frame index references.
247   DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos;
248 
249   // Clone virtual registers
250   for (unsigned I = 0, E = SrcMRI->getNumVirtRegs(); I != E; ++I) {
251     Register Reg = Register::index2VirtReg(I);
252     Register NewReg = DstMRI->createIncompleteVirtualRegister(
253       SrcMRI->getVRegName(Reg));
254     assert(NewReg == Reg && "expected to preserve virtreg number");
255 
256     DstMRI->setRegClassOrRegBank(NewReg, SrcMRI->getRegClassOrRegBank(Reg));
257 
258     LLT RegTy = SrcMRI->getType(Reg);
259     if (RegTy.isValid())
260       DstMRI->setType(NewReg, RegTy);
261 
262     // Copy register allocation hints.
263     const auto &Hints = SrcMRI->getRegAllocationHints(Reg);
264     for (Register PrefReg : Hints.second)
265       DstMRI->addRegAllocationHint(NewReg, PrefReg);
266   }
267 
268   const TargetSubtargetInfo &STI = DstMF->getSubtarget();
269   const TargetInstrInfo *TII = STI.getInstrInfo();
270   const TargetRegisterInfo *TRI = STI.getRegisterInfo();
271 
272   // Link blocks.
273   for (auto &SrcMBB : *SrcMF) {
274     auto *DstMBB = Src2DstMBB[&SrcMBB];
275     DstMF->push_back(DstMBB);
276 
277     for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end();
278          It != IterEnd; ++It) {
279       auto *SrcSuccMBB = *It;
280       auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB];
281       DstMBB->addSuccessor(DstSuccMBB, SrcMBB.getSuccProbability(It));
282     }
283 
284     for (auto &LI : SrcMBB.liveins_dbg())
285       DstMBB->addLiveIn(LI);
286 
287     // Make sure MRI knows about registers clobbered by unwinder.
288     if (DstMBB->isEHPad()) {
289       if (auto *RegMask = TRI->getCustomEHPadPreservedMask(*DstMF))
290         DstMRI->addPhysRegsUsedFromRegMask(RegMask);
291     }
292   }
293 
294   DenseSet<const uint32_t *> ConstRegisterMasks;
295 
296   // Track predefined/named regmasks which we ignore.
297   for (const uint32_t *Mask : TRI->getRegMasks())
298     ConstRegisterMasks.insert(Mask);
299 
300   // Clone instructions.
301   for (auto &SrcMBB : *SrcMF) {
302     auto *DstMBB = Src2DstMBB[&SrcMBB];
303     for (auto &SrcMI : SrcMBB) {
304       const auto &MCID = TII->get(SrcMI.getOpcode());
305       auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(),
306                                               /*NoImplicit=*/true);
307       DstMI->setFlags(SrcMI.getFlags());
308       DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags());
309 
310       DstMBB->push_back(DstMI);
311       for (auto &SrcMO : SrcMI.operands()) {
312         MachineOperand DstMO(SrcMO);
313         DstMO.clearParent();
314 
315         // Update MBB.
316         if (DstMO.isMBB())
317           DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
318         else if (DstMO.isRegMask()) {
319           DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask());
320 
321           if (!ConstRegisterMasks.count(DstMO.getRegMask())) {
322             uint32_t *DstMask = DstMF->allocateRegMask();
323             std::memcpy(DstMask, SrcMO.getRegMask(),
324                         sizeof(*DstMask) *
325                             MachineOperand::getRegMaskSize(TRI->getNumRegs()));
326             DstMO.setRegMask(DstMask);
327           }
328         }
329 
330         DstMI->addOperand(DstMO);
331       }
332 
333       cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF);
334     }
335   }
336 
337   DstMF->setAlignment(SrcMF->getAlignment());
338   DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice());
339   DstMF->setHasInlineAsm(SrcMF->hasInlineAsm());
340   DstMF->setHasWinCFI(SrcMF->hasWinCFI());
341 
342   DstMF->getProperties().reset().set(SrcMF->getProperties());
343 
344   if (!SrcMF->getFrameInstructions().empty() ||
345       !SrcMF->getLongjmpTargets().empty() ||
346       !SrcMF->getCatchretTargets().empty())
347     report_fatal_error("cloning not implemented for machine function property");
348 
349   DstMF->setCallsEHReturn(SrcMF->callsEHReturn());
350   DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit());
351   DstMF->setHasEHCatchret(SrcMF->hasEHCatchret());
352   DstMF->setHasEHScopes(SrcMF->hasEHScopes());
353   DstMF->setHasEHFunclets(SrcMF->hasEHFunclets());
354 
355   if (!SrcMF->getLandingPads().empty() ||
356       !SrcMF->getCodeViewAnnotations().empty() ||
357       !SrcMF->getTypeInfos().empty() ||
358       !SrcMF->getFilterIds().empty() ||
359       SrcMF->hasAnyWasmLandingPadIndex() ||
360       SrcMF->hasAnyCallSiteLandingPad() ||
361       SrcMF->hasAnyCallSiteLabel() ||
362       !SrcMF->getCallSitesInfo().empty())
363     report_fatal_error("cloning not implemented for machine function property");
364 
365   DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount);
366 
367   if (!DstMF->cloneInfoFrom(*SrcMF, Src2DstMBB))
368     report_fatal_error("target does not implement MachineFunctionInfo cloning");
369 
370   DstMRI->freezeReservedRegs(*DstMF);
371 
372   DstMF->verify(nullptr, "", /*AbortOnError=*/true);
373   return DstMF;
374 }
375 
initializeTargetInfo()376 static void initializeTargetInfo() {
377   InitializeAllTargets();
378   InitializeAllTargetMCs();
379   InitializeAllAsmPrinters();
380   InitializeAllAsmParsers();
381 }
382 
383 std::unique_ptr<ReducerWorkItem>
parseReducerWorkItem(const char * ToolName,StringRef Filename,LLVMContext & Ctxt,std::unique_ptr<TargetMachine> & TM,bool IsMIR)384 parseReducerWorkItem(const char *ToolName, StringRef Filename,
385                      LLVMContext &Ctxt, std::unique_ptr<TargetMachine> &TM,
386                      bool IsMIR) {
387   Triple TheTriple;
388 
389   auto MMM = std::make_unique<ReducerWorkItem>();
390 
391   if (IsMIR) {
392     initializeTargetInfo();
393 
394     auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
395     if (std::error_code EC = FileOrErr.getError()) {
396       WithColor::error(errs(), ToolName) << EC.message() << '\n';
397       return nullptr;
398     }
399 
400     std::unique_ptr<MIRParser> MParser =
401         createMIRParser(std::move(FileOrErr.get()), Ctxt);
402 
403     auto SetDataLayout =
404         [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> {
405       // If we are supposed to override the target triple, do so now.
406       std::string IRTargetTriple = DataLayoutTargetTriple.str();
407       if (!TargetTriple.empty())
408         IRTargetTriple = Triple::normalize(TargetTriple);
409       TheTriple = Triple(IRTargetTriple);
410       if (TheTriple.getTriple().empty())
411         TheTriple.setTriple(sys::getDefaultTargetTriple());
412 
413       std::string Error;
414       const Target *TheTarget =
415           TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
416       if (!TheTarget) {
417         WithColor::error(errs(), ToolName) << Error;
418         exit(1);
419       }
420 
421       // Hopefully the MIR parsing doesn't depend on any options.
422       TargetOptions Options;
423       Optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
424       std::string CPUStr = codegen::getCPUStr();
425       std::string FeaturesStr = codegen::getFeaturesStr();
426       TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
427           TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
428           codegen::getExplicitCodeModel(), CodeGenOpt::Default));
429       assert(TM && "Could not allocate target machine!");
430 
431       return TM->createDataLayout().getStringRepresentation();
432     };
433 
434     std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
435     LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
436 
437     MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
438     MParser->parseMachineFunctions(*M, *MMM->MMI);
439     MMM->M = std::move(M);
440   } else {
441     SMDiagnostic Err;
442     ErrorOr<std::unique_ptr<MemoryBuffer>> MB = MemoryBuffer::getFileOrSTDIN(Filename);
443     if (std::error_code EC = MB.getError()) {
444       WithColor::error(errs(), ToolName) << Filename << ": " << EC.message() << "\n";
445       return nullptr;
446     }
447 
448     if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(),
449                   (const unsigned char *)(*MB)->getBufferEnd())) {
450       std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt);
451       if (!Result) {
452         Err.print(ToolName, errs());
453         return nullptr;
454       }
455       MMM->M = std::move(Result);
456     } else {
457       readBitcode(*MMM, MemoryBufferRef(**MB), Ctxt, ToolName);
458 
459       if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit)
460        initializeTargetInfo();
461     }
462   }
463   if (verifyReducerWorkItem(*MMM, &errs())) {
464     WithColor::error(errs(), ToolName)
465         << Filename << " - input module is broken!\n";
466     return nullptr;
467   }
468   return MMM;
469 }
470 
471 std::unique_ptr<ReducerWorkItem>
cloneReducerWorkItem(const ReducerWorkItem & MMM,const TargetMachine * TM)472 cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) {
473   auto CloneMMM = std::make_unique<ReducerWorkItem>();
474   if (TM) {
475     // We're assuming the Module IR contents are always unchanged by MIR
476     // reductions, and can share it as a constant.
477     CloneMMM->M = MMM.M;
478 
479     // MachineModuleInfo contains a lot of other state used during codegen which
480     // we won't be using here, but we should be able to ignore it (although this
481     // is pretty ugly).
482     const LLVMTargetMachine *LLVMTM =
483         static_cast<const LLVMTargetMachine *>(TM);
484     CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
485 
486     for (const Function &F : MMM.getModule()) {
487       if (auto *MF = MMM.MMI->getMachineFunction(F))
488         CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI));
489     }
490   } else {
491     CloneMMM->M = CloneModule(*MMM.M);
492   }
493   return CloneMMM;
494 }
495 
verifyReducerWorkItem(const ReducerWorkItem & MMM,raw_fd_ostream * OS)496 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) {
497   if (verifyModule(*MMM.M, OS))
498     return true;
499 
500   if (!MMM.MMI)
501     return false;
502 
503   for (const Function &F : MMM.getModule()) {
504     if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) {
505       if (!MF->verify(nullptr, "", /*AbortOnError=*/false))
506         return true;
507     }
508   }
509 
510   return false;
511 }
512 
print(raw_ostream & ROS,void * p) const513 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
514   if (MMI) {
515     printMIR(ROS, *M);
516     for (Function &F : *M) {
517       if (auto *MF = MMI->getMachineFunction(F))
518         printMIR(ROS, *MF);
519     }
520   } else {
521     M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
522              /*ShouldPreserveUseListOrder=*/true);
523   }
524 }
525 
526 // FIXME: We might want to use a different metric than "number of
527 // bytes in serialized IR" to detect non-progress of the main delta
528 // loop
getIRSize() const529 uint64_t ReducerWorkItem::getIRSize() const {
530   std::string Str;
531   raw_string_ostream SS(Str);
532   print(SS, /*AnnotationWriter=*/nullptr);
533   return Str.length();
534 }
535 
536 /// Try to produce some number that indicates a function is getting smaller /
537 /// simpler.
computeMIRComplexityScoreImpl(const MachineFunction & MF)538 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) {
539   uint64_t Score = 0;
540   const MachineFrameInfo &MFI = MF.getFrameInfo();
541 
542   // Add for stack objects
543   Score += MFI.getNumObjects();
544 
545   // Add in the block count.
546   Score += 2 * MF.size();
547 
548   const MachineRegisterInfo &MRI = MF.getRegInfo();
549   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
550     Register Reg = Register::index2VirtReg(I);
551     Score += MRI.getRegAllocationHints(Reg).second.size();
552   }
553 
554   for (const MachineBasicBlock &MBB : MF) {
555     for (const MachineInstr &MI : MBB) {
556       const unsigned Opc = MI.getOpcode();
557 
558       // Reductions may want or need to introduce implicit_defs, so don't count
559       // them.
560       // TODO: These probably should count in some way.
561       if (Opc == TargetOpcode::IMPLICIT_DEF ||
562           Opc == TargetOpcode::G_IMPLICIT_DEF)
563         continue;
564 
565       // Each instruction adds to the score
566       Score += 4;
567 
568       if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI ||
569           Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR)
570         ++Score;
571 
572       if (MI.getFlags() != 0)
573         ++Score;
574 
575       // Increase weight for more operands.
576       for (const MachineOperand &MO : MI.operands()) {
577         ++Score;
578 
579         // Treat registers as more complex.
580         if (MO.isReg()) {
581           ++Score;
582 
583           // And subregisters as even more complex.
584           if (MO.getSubReg()) {
585             ++Score;
586             if (MO.isDef())
587               ++Score;
588           }
589         } else if (MO.isRegMask())
590           ++Score;
591       }
592     }
593   }
594 
595   return Score;
596 }
597 
computeMIRComplexityScore() const598 uint64_t ReducerWorkItem::computeMIRComplexityScore() const {
599   uint64_t Score = 0;
600 
601   for (const Function &F : getModule()) {
602     if (auto *MF = MMI->getMachineFunction(F))
603       Score += computeMIRComplexityScoreImpl(*MF);
604   }
605 
606   return Score;
607 }
608