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 
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 
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 
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   // Clone instructions.
295   for (auto &SrcMBB : *SrcMF) {
296     auto *DstMBB = Src2DstMBB[&SrcMBB];
297     for (auto &SrcMI : SrcMBB) {
298       const auto &MCID = TII->get(SrcMI.getOpcode());
299       auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(),
300                                               /*NoImplicit=*/true);
301       DstMI->setFlags(SrcMI.getFlags());
302       DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags());
303 
304       DstMBB->push_back(DstMI);
305       for (auto &SrcMO : SrcMI.operands()) {
306         MachineOperand DstMO(SrcMO);
307         DstMO.clearParent();
308 
309         // Update MBB.
310         if (DstMO.isMBB())
311           DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
312         else if (DstMO.isRegMask())
313           DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask());
314 
315         DstMI->addOperand(DstMO);
316       }
317 
318       cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF);
319     }
320   }
321 
322   DstMF->setAlignment(SrcMF->getAlignment());
323   DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice());
324   DstMF->setHasInlineAsm(SrcMF->hasInlineAsm());
325   DstMF->setHasWinCFI(SrcMF->hasWinCFI());
326 
327   DstMF->getProperties().reset().set(SrcMF->getProperties());
328 
329   if (!SrcMF->getFrameInstructions().empty() ||
330       !SrcMF->getLongjmpTargets().empty() ||
331       !SrcMF->getCatchretTargets().empty())
332     report_fatal_error("cloning not implemented for machine function property");
333 
334   DstMF->setCallsEHReturn(SrcMF->callsEHReturn());
335   DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit());
336   DstMF->setHasEHCatchret(SrcMF->hasEHCatchret());
337   DstMF->setHasEHScopes(SrcMF->hasEHScopes());
338   DstMF->setHasEHFunclets(SrcMF->hasEHFunclets());
339 
340   if (!SrcMF->getLandingPads().empty() ||
341       !SrcMF->getCodeViewAnnotations().empty() ||
342       !SrcMF->getTypeInfos().empty() ||
343       !SrcMF->getFilterIds().empty() ||
344       SrcMF->hasAnyWasmLandingPadIndex() ||
345       SrcMF->hasAnyCallSiteLandingPad() ||
346       SrcMF->hasAnyCallSiteLabel() ||
347       !SrcMF->getCallSitesInfo().empty())
348     report_fatal_error("cloning not implemented for machine function property");
349 
350   DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount);
351 
352   if (!DstMF->cloneInfoFrom(*SrcMF, Src2DstMBB))
353     report_fatal_error("target does not implement MachineFunctionInfo cloning");
354 
355   DstMRI->freezeReservedRegs(*DstMF);
356 
357   DstMF->verify(nullptr, "", /*AbortOnError=*/true);
358   return DstMF;
359 }
360 
361 static void initializeTargetInfo() {
362   InitializeAllTargets();
363   InitializeAllTargetMCs();
364   InitializeAllAsmPrinters();
365   InitializeAllAsmParsers();
366 }
367 
368 std::unique_ptr<ReducerWorkItem>
369 parseReducerWorkItem(const char *ToolName, StringRef Filename,
370                      LLVMContext &Ctxt, std::unique_ptr<TargetMachine> &TM,
371                      bool IsMIR) {
372   Triple TheTriple;
373 
374   auto MMM = std::make_unique<ReducerWorkItem>();
375 
376   if (IsMIR) {
377     initializeTargetInfo();
378 
379     auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
380     if (std::error_code EC = FileOrErr.getError()) {
381       WithColor::error(errs(), ToolName) << EC.message() << '\n';
382       return nullptr;
383     }
384 
385     std::unique_ptr<MIRParser> MParser =
386         createMIRParser(std::move(FileOrErr.get()), Ctxt);
387 
388     auto SetDataLayout =
389         [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> {
390       // If we are supposed to override the target triple, do so now.
391       std::string IRTargetTriple = DataLayoutTargetTriple.str();
392       if (!TargetTriple.empty())
393         IRTargetTriple = Triple::normalize(TargetTriple);
394       TheTriple = Triple(IRTargetTriple);
395       if (TheTriple.getTriple().empty())
396         TheTriple.setTriple(sys::getDefaultTargetTriple());
397 
398       std::string Error;
399       const Target *TheTarget =
400           TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
401       if (!TheTarget) {
402         WithColor::error(errs(), ToolName) << Error;
403         exit(1);
404       }
405 
406       // Hopefully the MIR parsing doesn't depend on any options.
407       TargetOptions Options;
408       Optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
409       std::string CPUStr = codegen::getCPUStr();
410       std::string FeaturesStr = codegen::getFeaturesStr();
411       TM = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
412           TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM,
413           codegen::getExplicitCodeModel(), CodeGenOpt::Default));
414       assert(TM && "Could not allocate target machine!");
415 
416       return TM->createDataLayout().getStringRepresentation();
417     };
418 
419     std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
420     LLVMTargetMachine *LLVMTM = static_cast<LLVMTargetMachine *>(TM.get());
421 
422     MMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
423     MParser->parseMachineFunctions(*M, *MMM->MMI);
424     MMM->M = std::move(M);
425   } else {
426     SMDiagnostic Err;
427     ErrorOr<std::unique_ptr<MemoryBuffer>> MB = MemoryBuffer::getFileOrSTDIN(Filename);
428     if (std::error_code EC = MB.getError()) {
429       WithColor::error(errs(), ToolName) << Filename << ": " << EC.message() << "\n";
430       return nullptr;
431     }
432 
433     if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(),
434                   (const unsigned char *)(*MB)->getBufferEnd())) {
435       std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt);
436       if (!Result) {
437         Err.print(ToolName, errs());
438         return nullptr;
439       }
440       MMM->M = std::move(Result);
441     } else {
442       readBitcode(*MMM, MemoryBufferRef(**MB), Ctxt, ToolName);
443 
444       if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit)
445        initializeTargetInfo();
446     }
447   }
448   if (verifyReducerWorkItem(*MMM, &errs())) {
449     WithColor::error(errs(), ToolName)
450         << Filename << " - input module is broken!\n";
451     return nullptr;
452   }
453   return MMM;
454 }
455 
456 std::unique_ptr<ReducerWorkItem>
457 cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) {
458   auto CloneMMM = std::make_unique<ReducerWorkItem>();
459   if (TM) {
460     // We're assuming the Module IR contents are always unchanged by MIR
461     // reductions, and can share it as a constant.
462     CloneMMM->M = MMM.M;
463 
464     // MachineModuleInfo contains a lot of other state used during codegen which
465     // we won't be using here, but we should be able to ignore it (although this
466     // is pretty ugly).
467     const LLVMTargetMachine *LLVMTM =
468         static_cast<const LLVMTargetMachine *>(TM);
469     CloneMMM->MMI = std::make_unique<MachineModuleInfo>(LLVMTM);
470 
471     for (const Function &F : MMM.getModule()) {
472       if (auto *MF = MMM.MMI->getMachineFunction(F))
473         CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI));
474     }
475   } else {
476     CloneMMM->M = CloneModule(*MMM.M);
477   }
478   return CloneMMM;
479 }
480 
481 bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) {
482   if (verifyModule(*MMM.M, OS))
483     return true;
484 
485   if (!MMM.MMI)
486     return false;
487 
488   for (const Function &F : MMM.getModule()) {
489     if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) {
490       if (!MF->verify(nullptr, "", /*AbortOnError=*/false))
491         return true;
492     }
493   }
494 
495   return false;
496 }
497 
498 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
499   if (MMI) {
500     printMIR(ROS, *M);
501     for (Function &F : *M) {
502       if (auto *MF = MMI->getMachineFunction(F))
503         printMIR(ROS, *MF);
504     }
505   } else {
506     M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
507              /*ShouldPreserveUseListOrder=*/true);
508   }
509 }
510 
511 // FIXME: We might want to use a different metric than "number of
512 // bytes in serialized IR" to detect non-progress of the main delta
513 // loop
514 uint64_t ReducerWorkItem::getIRSize() const {
515   std::string Str;
516   raw_string_ostream SS(Str);
517   print(SS, /*AnnotationWriter=*/nullptr);
518   return Str.length();
519 }
520 
521 /// Try to produce some number that indicates a function is getting smaller /
522 /// simpler.
523 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) {
524   uint64_t Score = 0;
525   const MachineFrameInfo &MFI = MF.getFrameInfo();
526 
527   // Add for stack objects
528   Score += MFI.getNumObjects();
529 
530   // Add in the block count.
531   Score += 2 * MF.size();
532 
533   const MachineRegisterInfo &MRI = MF.getRegInfo();
534   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
535     Register Reg = Register::index2VirtReg(I);
536     Score += MRI.getRegAllocationHints(Reg).second.size();
537   }
538 
539   for (const MachineBasicBlock &MBB : MF) {
540     for (const MachineInstr &MI : MBB) {
541       const unsigned Opc = MI.getOpcode();
542 
543       // Reductions may want or need to introduce implicit_defs, so don't count
544       // them.
545       // TODO: These probably should count in some way.
546       if (Opc == TargetOpcode::IMPLICIT_DEF ||
547           Opc == TargetOpcode::G_IMPLICIT_DEF)
548         continue;
549 
550       // Each instruction adds to the score
551       Score += 4;
552 
553       if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI ||
554           Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR)
555         ++Score;
556 
557       if (MI.getFlags() != 0)
558         ++Score;
559 
560       // Increase weight for more operands.
561       for (const MachineOperand &MO : MI.operands()) {
562         ++Score;
563 
564         // Treat registers as more complex.
565         if (MO.isReg()) {
566           ++Score;
567 
568           // And subregisters as even more complex.
569           if (MO.getSubReg()) {
570             ++Score;
571             if (MO.isDef())
572               ++Score;
573           }
574         } else if (MO.isRegMask())
575           ++Score;
576       }
577     }
578   }
579 
580   return Score;
581 }
582 
583 uint64_t ReducerWorkItem::computeMIRComplexityScore() const {
584   uint64_t Score = 0;
585 
586   for (const Function &F : getModule()) {
587     if (auto *MF = MMI->getMachineFunction(F))
588       Score += computeMIRComplexityScoreImpl(*MF);
589   }
590 
591   return Score;
592 }
593