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