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