xref: /llvm-project/llvm/tools/llvm-reduce/ReducerWorkItem.cpp (revision bb3f5e1fed7c6ba733b7f273e93f5d3930976185)
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 "TestRunner.h"
11 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
12 #include "llvm/Analysis/ProfileSummaryInfo.h"
13 #include "llvm/Bitcode/BitcodeReader.h"
14 #include "llvm/Bitcode/BitcodeWriter.h"
15 #include "llvm/CodeGen/CommandFlags.h"
16 #include "llvm/CodeGen/MIRParser/MIRParser.h"
17 #include "llvm/CodeGen/MIRPrinter.h"
18 #include "llvm/CodeGen/MachineDominators.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineFunctionPass.h"
22 #include "llvm/CodeGen/MachineJumpTableInfo.h"
23 #include "llvm/CodeGen/MachineModuleInfo.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/PseudoSourceValueManager.h"
26 #include "llvm/CodeGen/TargetInstrInfo.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/Instructions.h"
29 #include "llvm/IR/ModuleSummaryIndex.h"
30 #include "llvm/IR/Operator.h"
31 #include "llvm/IR/Verifier.h"
32 #include "llvm/IRReader/IRReader.h"
33 #include "llvm/MC/TargetRegistry.h"
34 #include "llvm/Passes/PassBuilder.h"
35 #include "llvm/Support/MemoryBufferRef.h"
36 #include "llvm/Support/SourceMgr.h"
37 #include "llvm/Support/TargetSelect.h"
38 #include "llvm/Support/ToolOutputFile.h"
39 #include "llvm/Support/WithColor.h"
40 #include "llvm/Target/TargetMachine.h"
41 #include "llvm/TargetParser/Host.h"
42 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
43 #include "llvm/Transforms/Utils/Cloning.h"
44 #include <optional>
45 
46 using namespace llvm;
47 
48 ReducerWorkItem::ReducerWorkItem() = default;
49 ReducerWorkItem::~ReducerWorkItem() = default;
50 
51 extern cl::OptionCategory LLVMReduceOptions;
52 static cl::opt<std::string> TargetTriple("mtriple",
53                                          cl::desc("Set the target triple"),
54                                          cl::cat(LLVMReduceOptions));
55 static cl::opt<bool> PrintInvalidMachineReductions(
56     "print-invalid-reduction-machine-verifier-errors",
57     cl::desc(
58         "Print machine verifier errors on invalid reduction attempts triple"),
59     cl::cat(LLVMReduceOptions));
60 
61 static cl::opt<bool> TmpFilesAsBitcode(
62     "write-tmp-files-as-bitcode",
63     cl::desc("Always write temporary files as bitcode instead of textual IR"),
64     cl::init(false), cl::cat(LLVMReduceOptions));
65 
66 static void cloneFrameInfo(
67     MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI,
68     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) {
69   DstMFI.setFrameAddressIsTaken(SrcMFI.isFrameAddressTaken());
70   DstMFI.setReturnAddressIsTaken(SrcMFI.isReturnAddressTaken());
71   DstMFI.setHasStackMap(SrcMFI.hasStackMap());
72   DstMFI.setHasPatchPoint(SrcMFI.hasPatchPoint());
73   DstMFI.setUseLocalStackAllocationBlock(
74       SrcMFI.getUseLocalStackAllocationBlock());
75   DstMFI.setOffsetAdjustment(SrcMFI.getOffsetAdjustment());
76 
77   DstMFI.ensureMaxAlignment(SrcMFI.getMaxAlign());
78   assert(DstMFI.getMaxAlign() == SrcMFI.getMaxAlign() &&
79          "we need to set exact alignment");
80 
81   DstMFI.setAdjustsStack(SrcMFI.adjustsStack());
82   DstMFI.setHasCalls(SrcMFI.hasCalls());
83   DstMFI.setHasOpaqueSPAdjustment(SrcMFI.hasOpaqueSPAdjustment());
84   DstMFI.setHasCopyImplyingStackAdjustment(
85       SrcMFI.hasCopyImplyingStackAdjustment());
86   DstMFI.setHasVAStart(SrcMFI.hasVAStart());
87   DstMFI.setHasMustTailInVarArgFunc(SrcMFI.hasMustTailInVarArgFunc());
88   DstMFI.setHasTailCall(SrcMFI.hasTailCall());
89 
90   if (SrcMFI.isMaxCallFrameSizeComputed())
91     DstMFI.setMaxCallFrameSize(SrcMFI.getMaxCallFrameSize());
92 
93   DstMFI.setCVBytesOfCalleeSavedRegisters(
94       SrcMFI.getCVBytesOfCalleeSavedRegisters());
95 
96   if (MachineBasicBlock *SavePt = SrcMFI.getSavePoint())
97     DstMFI.setSavePoint(Src2DstMBB.find(SavePt)->second);
98   if (MachineBasicBlock *RestorePt = SrcMFI.getRestorePoint())
99     DstMFI.setRestorePoint(Src2DstMBB.find(RestorePt)->second);
100 
101 
102   auto CopyObjectProperties = [](MachineFrameInfo &DstMFI,
103                                  const MachineFrameInfo &SrcMFI, int FI) {
104     if (SrcMFI.isStatepointSpillSlotObjectIndex(FI))
105       DstMFI.markAsStatepointSpillSlotObjectIndex(FI);
106     DstMFI.setObjectSSPLayout(FI, SrcMFI.getObjectSSPLayout(FI));
107     DstMFI.setObjectZExt(FI, SrcMFI.isObjectZExt(FI));
108     DstMFI.setObjectSExt(FI, SrcMFI.isObjectSExt(FI));
109   };
110 
111   for (int i = 0, e = SrcMFI.getNumObjects() - SrcMFI.getNumFixedObjects();
112        i != e; ++i) {
113     int NewFI;
114 
115     assert(!SrcMFI.isFixedObjectIndex(i));
116     if (SrcMFI.isVariableSizedObjectIndex(i)) {
117       NewFI = DstMFI.CreateVariableSizedObject(SrcMFI.getObjectAlign(i),
118                                                SrcMFI.getObjectAllocation(i));
119     } else {
120       NewFI = DstMFI.CreateStackObject(
121           SrcMFI.getObjectSize(i), SrcMFI.getObjectAlign(i),
122           SrcMFI.isSpillSlotObjectIndex(i), SrcMFI.getObjectAllocation(i),
123           SrcMFI.getStackID(i));
124       DstMFI.setObjectOffset(NewFI, SrcMFI.getObjectOffset(i));
125     }
126 
127     CopyObjectProperties(DstMFI, SrcMFI, i);
128 
129     (void)NewFI;
130     assert(i == NewFI && "expected to keep stable frame index numbering");
131   }
132 
133   // Copy the fixed frame objects backwards to preserve frame index numbers,
134   // since CreateFixedObject uses front insertion.
135   for (int i = -1; i >= (int)-SrcMFI.getNumFixedObjects(); --i) {
136     assert(SrcMFI.isFixedObjectIndex(i));
137     int NewFI = DstMFI.CreateFixedObject(
138       SrcMFI.getObjectSize(i), SrcMFI.getObjectOffset(i),
139       SrcMFI.isImmutableObjectIndex(i), SrcMFI.isAliasedObjectIndex(i));
140     CopyObjectProperties(DstMFI, SrcMFI, i);
141 
142     (void)NewFI;
143     assert(i == NewFI && "expected to keep stable frame index numbering");
144   }
145 
146   for (unsigned I = 0, E = SrcMFI.getLocalFrameObjectCount(); I < E; ++I) {
147     auto LocalObject = SrcMFI.getLocalFrameObjectMap(I);
148     DstMFI.mapLocalFrameObject(LocalObject.first, LocalObject.second);
149   }
150 
151   DstMFI.setCalleeSavedInfo(SrcMFI.getCalleeSavedInfo());
152 
153   if (SrcMFI.hasStackProtectorIndex()) {
154     DstMFI.setStackProtectorIndex(SrcMFI.getStackProtectorIndex());
155   }
156 
157   // FIXME: Needs test, missing MIR serialization.
158   if (SrcMFI.hasFunctionContextIndex()) {
159     DstMFI.setFunctionContextIndex(SrcMFI.getFunctionContextIndex());
160   }
161 }
162 
163 static void cloneJumpTableInfo(
164     MachineFunction &DstMF, const MachineJumpTableInfo &SrcJTI,
165     const DenseMap<MachineBasicBlock *, MachineBasicBlock *> &Src2DstMBB) {
166 
167   auto *DstJTI = DstMF.getOrCreateJumpTableInfo(SrcJTI.getEntryKind());
168 
169   std::vector<MachineBasicBlock *> DstBBs;
170 
171   for (const MachineJumpTableEntry &Entry : SrcJTI.getJumpTables()) {
172     for (MachineBasicBlock *X : Entry.MBBs)
173       DstBBs.push_back(Src2DstMBB.find(X)->second);
174 
175     DstJTI->createJumpTableIndex(DstBBs);
176     DstBBs.clear();
177   }
178 }
179 
180 static void cloneMemOperands(MachineInstr &DstMI, MachineInstr &SrcMI,
181                              MachineFunction &SrcMF, MachineFunction &DstMF) {
182   // The new MachineMemOperands should be owned by the new function's
183   // Allocator.
184   PseudoSourceValueManager &PSVMgr = DstMF.getPSVManager();
185 
186   // We also need to remap the PseudoSourceValues from the new function's
187   // PseudoSourceValueManager.
188   SmallVector<MachineMemOperand *, 2> NewMMOs;
189   for (MachineMemOperand *OldMMO : SrcMI.memoperands()) {
190     MachinePointerInfo NewPtrInfo(OldMMO->getPointerInfo());
191     if (const PseudoSourceValue *PSV =
192             dyn_cast_if_present<const PseudoSourceValue *>(NewPtrInfo.V)) {
193       switch (PSV->kind()) {
194       case PseudoSourceValue::Stack:
195         NewPtrInfo.V = PSVMgr.getStack();
196         break;
197       case PseudoSourceValue::GOT:
198         NewPtrInfo.V = PSVMgr.getGOT();
199         break;
200       case PseudoSourceValue::JumpTable:
201         NewPtrInfo.V = PSVMgr.getJumpTable();
202         break;
203       case PseudoSourceValue::ConstantPool:
204         NewPtrInfo.V = PSVMgr.getConstantPool();
205         break;
206       case PseudoSourceValue::FixedStack:
207         NewPtrInfo.V = PSVMgr.getFixedStack(
208             cast<FixedStackPseudoSourceValue>(PSV)->getFrameIndex());
209         break;
210       case PseudoSourceValue::GlobalValueCallEntry:
211         NewPtrInfo.V = PSVMgr.getGlobalValueCallEntry(
212             cast<GlobalValuePseudoSourceValue>(PSV)->getValue());
213         break;
214       case PseudoSourceValue::ExternalSymbolCallEntry:
215         NewPtrInfo.V = PSVMgr.getExternalSymbolCallEntry(
216             cast<ExternalSymbolPseudoSourceValue>(PSV)->getSymbol());
217         break;
218       case PseudoSourceValue::TargetCustom:
219       default:
220         // FIXME: We have no generic interface for allocating custom PSVs.
221         report_fatal_error("Cloning TargetCustom PSV not handled");
222       }
223     }
224 
225     MachineMemOperand *NewMMO = DstMF.getMachineMemOperand(
226         NewPtrInfo, OldMMO->getFlags(), OldMMO->getMemoryType(),
227         OldMMO->getBaseAlign(), OldMMO->getAAInfo(), OldMMO->getRanges(),
228         OldMMO->getSyncScopeID(), OldMMO->getSuccessOrdering(),
229         OldMMO->getFailureOrdering());
230     NewMMOs.push_back(NewMMO);
231   }
232 
233   DstMI.setMemRefs(DstMF, NewMMOs);
234 }
235 
236 static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
237                                                 MachineModuleInfo &DestMMI) {
238   auto DstMF = std::make_unique<MachineFunction>(
239       SrcMF->getFunction(), SrcMF->getTarget(), SrcMF->getSubtarget(),
240       SrcMF->getContext(), SrcMF->getFunctionNumber());
241   DenseMap<MachineBasicBlock *, MachineBasicBlock *> Src2DstMBB;
242 
243   auto *SrcMRI = &SrcMF->getRegInfo();
244   auto *DstMRI = &DstMF->getRegInfo();
245 
246   // Clone blocks.
247   for (MachineBasicBlock &SrcMBB : *SrcMF) {
248     MachineBasicBlock *DstMBB =
249         DstMF->CreateMachineBasicBlock(SrcMBB.getBasicBlock());
250     Src2DstMBB[&SrcMBB] = DstMBB;
251 
252     DstMBB->setCallFrameSize(SrcMBB.getCallFrameSize());
253 
254     if (SrcMBB.isIRBlockAddressTaken())
255       DstMBB->setAddressTakenIRBlock(SrcMBB.getAddressTakenIRBlock());
256     if (SrcMBB.isMachineBlockAddressTaken())
257       DstMBB->setMachineBlockAddressTaken();
258 
259     // FIXME: This is not serialized
260     if (SrcMBB.hasLabelMustBeEmitted())
261       DstMBB->setLabelMustBeEmitted();
262 
263     DstMBB->setAlignment(SrcMBB.getAlignment());
264 
265     // FIXME: This is not serialized
266     DstMBB->setMaxBytesForAlignment(SrcMBB.getMaxBytesForAlignment());
267 
268     DstMBB->setIsEHPad(SrcMBB.isEHPad());
269     DstMBB->setIsEHScopeEntry(SrcMBB.isEHScopeEntry());
270     DstMBB->setIsEHCatchretTarget(SrcMBB.isEHCatchretTarget());
271     DstMBB->setIsEHFuncletEntry(SrcMBB.isEHFuncletEntry());
272 
273     // FIXME: These are not serialized
274     DstMBB->setIsCleanupFuncletEntry(SrcMBB.isCleanupFuncletEntry());
275     DstMBB->setIsBeginSection(SrcMBB.isBeginSection());
276     DstMBB->setIsEndSection(SrcMBB.isEndSection());
277 
278     DstMBB->setSectionID(SrcMBB.getSectionID());
279     DstMBB->setIsInlineAsmBrIndirectTarget(
280         SrcMBB.isInlineAsmBrIndirectTarget());
281 
282     // FIXME: This is not serialized
283     if (std::optional<uint64_t> Weight = SrcMBB.getIrrLoopHeaderWeight())
284       DstMBB->setIrrLoopHeaderWeight(*Weight);
285   }
286 
287   const MachineFrameInfo &SrcMFI = SrcMF->getFrameInfo();
288   MachineFrameInfo &DstMFI = DstMF->getFrameInfo();
289 
290   // Copy stack objects and other info
291   cloneFrameInfo(DstMFI, SrcMFI, Src2DstMBB);
292 
293   if (MachineJumpTableInfo *SrcJTI = SrcMF->getJumpTableInfo()) {
294     cloneJumpTableInfo(*DstMF, *SrcJTI, Src2DstMBB);
295   }
296 
297   // Remap the debug info frame index references.
298   DstMF->VariableDbgInfos = SrcMF->VariableDbgInfos;
299 
300   // Clone virtual registers
301   for (unsigned I = 0, E = SrcMRI->getNumVirtRegs(); I != E; ++I) {
302     Register Reg = Register::index2VirtReg(I);
303     Register NewReg = DstMRI->createIncompleteVirtualRegister(
304       SrcMRI->getVRegName(Reg));
305     assert(NewReg == Reg && "expected to preserve virtreg number");
306 
307     DstMRI->setRegClassOrRegBank(NewReg, SrcMRI->getRegClassOrRegBank(Reg));
308 
309     LLT RegTy = SrcMRI->getType(Reg);
310     if (RegTy.isValid())
311       DstMRI->setType(NewReg, RegTy);
312 
313     // Copy register allocation hints.
314     const auto *Hints = SrcMRI->getRegAllocationHints(Reg);
315     if (Hints)
316       for (Register PrefReg : Hints->second)
317         DstMRI->addRegAllocationHint(NewReg, PrefReg);
318   }
319 
320   const TargetSubtargetInfo &STI = DstMF->getSubtarget();
321   const TargetInstrInfo *TII = STI.getInstrInfo();
322   const TargetRegisterInfo *TRI = STI.getRegisterInfo();
323 
324   // Link blocks.
325   for (auto &SrcMBB : *SrcMF) {
326     auto *DstMBB = Src2DstMBB[&SrcMBB];
327     DstMF->push_back(DstMBB);
328 
329     for (auto It = SrcMBB.succ_begin(), IterEnd = SrcMBB.succ_end();
330          It != IterEnd; ++It) {
331       auto *SrcSuccMBB = *It;
332       auto *DstSuccMBB = Src2DstMBB[SrcSuccMBB];
333       DstMBB->addSuccessor(DstSuccMBB, SrcMBB.getSuccProbability(It));
334     }
335 
336     for (auto &LI : SrcMBB.liveins_dbg())
337       DstMBB->addLiveIn(LI);
338 
339     // Make sure MRI knows about registers clobbered by unwinder.
340     if (DstMBB->isEHPad()) {
341       if (auto *RegMask = TRI->getCustomEHPadPreservedMask(*DstMF))
342         DstMRI->addPhysRegsUsedFromRegMask(RegMask);
343     }
344   }
345 
346   DenseSet<const uint32_t *> ConstRegisterMasks;
347 
348   // Track predefined/named regmasks which we ignore.
349   for (const uint32_t *Mask : TRI->getRegMasks())
350     ConstRegisterMasks.insert(Mask);
351 
352   // Clone instructions.
353   for (auto &SrcMBB : *SrcMF) {
354     auto *DstMBB = Src2DstMBB[&SrcMBB];
355     for (auto &SrcMI : SrcMBB) {
356       const auto &MCID = TII->get(SrcMI.getOpcode());
357       auto *DstMI = DstMF->CreateMachineInstr(MCID, SrcMI.getDebugLoc(),
358                                               /*NoImplicit=*/true);
359       DstMI->setFlags(SrcMI.getFlags());
360       DstMI->setAsmPrinterFlag(SrcMI.getAsmPrinterFlags());
361 
362       DstMBB->push_back(DstMI);
363       for (auto &SrcMO : SrcMI.operands()) {
364         MachineOperand DstMO(SrcMO);
365         DstMO.clearParent();
366 
367         // Update MBB.
368         if (DstMO.isMBB())
369           DstMO.setMBB(Src2DstMBB[DstMO.getMBB()]);
370         else if (DstMO.isRegMask()) {
371           DstMRI->addPhysRegsUsedFromRegMask(DstMO.getRegMask());
372 
373           if (!ConstRegisterMasks.count(DstMO.getRegMask())) {
374             uint32_t *DstMask = DstMF->allocateRegMask();
375             std::memcpy(DstMask, SrcMO.getRegMask(),
376                         sizeof(*DstMask) *
377                             MachineOperand::getRegMaskSize(TRI->getNumRegs()));
378             DstMO.setRegMask(DstMask);
379           }
380         }
381 
382         DstMI->addOperand(DstMO);
383       }
384 
385       cloneMemOperands(*DstMI, SrcMI, *SrcMF, *DstMF);
386     }
387   }
388 
389   DstMF->setAlignment(SrcMF->getAlignment());
390   DstMF->setExposesReturnsTwice(SrcMF->exposesReturnsTwice());
391   DstMF->setHasInlineAsm(SrcMF->hasInlineAsm());
392   DstMF->setHasWinCFI(SrcMF->hasWinCFI());
393 
394   DstMF->getProperties().reset().set(SrcMF->getProperties());
395 
396   if (!SrcMF->getFrameInstructions().empty() ||
397       !SrcMF->getLongjmpTargets().empty() ||
398       !SrcMF->getCatchretTargets().empty())
399     report_fatal_error("cloning not implemented for machine function property");
400 
401   DstMF->setCallsEHReturn(SrcMF->callsEHReturn());
402   DstMF->setCallsUnwindInit(SrcMF->callsUnwindInit());
403   DstMF->setHasEHCatchret(SrcMF->hasEHCatchret());
404   DstMF->setHasEHScopes(SrcMF->hasEHScopes());
405   DstMF->setHasEHFunclets(SrcMF->hasEHFunclets());
406   DstMF->setHasFakeUses(SrcMF->hasFakeUses());
407   DstMF->setIsOutlined(SrcMF->isOutlined());
408 
409   if (!SrcMF->getLandingPads().empty() ||
410       !SrcMF->getCodeViewAnnotations().empty() ||
411       !SrcMF->getTypeInfos().empty() ||
412       !SrcMF->getFilterIds().empty() ||
413       SrcMF->hasAnyWasmLandingPadIndex() ||
414       SrcMF->hasAnyCallSiteLandingPad() ||
415       SrcMF->hasAnyCallSiteLabel() ||
416       !SrcMF->getCallSitesInfo().empty())
417     report_fatal_error("cloning not implemented for machine function property");
418 
419   DstMF->setDebugInstrNumberingCount(SrcMF->DebugInstrNumberingCount);
420 
421   if (!DstMF->cloneInfoFrom(*SrcMF, Src2DstMBB))
422     report_fatal_error("target does not implement MachineFunctionInfo cloning");
423 
424   DstMRI->freezeReservedRegs();
425 
426   DstMF->verify(nullptr, "", &errs(), /*AbortOnError=*/true);
427   return DstMF;
428 }
429 
430 static void initializeTargetInfo() {
431   InitializeAllTargets();
432   InitializeAllTargetMCs();
433   InitializeAllAsmPrinters();
434   InitializeAllAsmParsers();
435 }
436 
437 void ReducerWorkItem::print(raw_ostream &ROS, void *p) const {
438   if (MMI) {
439     printMIR(ROS, *M);
440     for (Function &F : *M) {
441       if (auto *MF = MMI->getMachineFunction(F))
442         printMIR(ROS, *MMI, *MF);
443     }
444   } else {
445     M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr,
446              /*ShouldPreserveUseListOrder=*/true);
447   }
448 }
449 
450 bool ReducerWorkItem::verify(raw_fd_ostream *OS) const {
451   if (verifyModule(*M, OS))
452     return true;
453 
454   if (!MMI)
455     return false;
456 
457   for (const Function &F : getModule()) {
458     if (const MachineFunction *MF = MMI->getMachineFunction(F)) {
459       // With the current state of quality, most reduction attempts fail the
460       // machine verifier. Avoid spamming large function dumps on nearly every
461       // attempt until the situation is better.
462       if (!MF->verify(nullptr, "",
463                       /*OS=*/PrintInvalidMachineReductions ? &errs() : nullptr,
464                       /*AbortOnError=*/false)) {
465 
466         if (!PrintInvalidMachineReductions) {
467           WithColor::warning(errs())
468               << "reduction attempt on function '" << MF->getName()
469               << "' failed machine verifier (debug with "
470                  "-print-invalid-reduction-machine-verifier-errors)\n";
471         }
472         return true;
473       }
474     }
475   }
476 
477   return false;
478 }
479 
480 bool ReducerWorkItem::isReduced(const TestRunner &Test) const {
481   const bool UseBitcode = Test.inputIsBitcode() || TmpFilesAsBitcode;
482 
483   SmallString<128> CurrentFilepath;
484 
485   // Write ReducerWorkItem to tmp file
486   int FD;
487   std::error_code EC = sys::fs::createTemporaryFile(
488       "llvm-reduce", isMIR() ? "mir" : (UseBitcode ? "bc" : "ll"), FD,
489       CurrentFilepath,
490       UseBitcode && !isMIR() ? sys::fs::OF_None : sys::fs::OF_Text);
491   if (EC) {
492     WithColor::error(errs(), Test.getToolName())
493         << "error making unique filename: " << EC.message() << '\n';
494     exit(1);
495   }
496 
497   ToolOutputFile Out(CurrentFilepath, FD);
498 
499   writeOutput(Out.os(), UseBitcode);
500 
501   Out.os().close();
502   if (Out.os().has_error()) {
503     WithColor::error(errs(), Test.getToolName())
504         << "error emitting bitcode to file '" << CurrentFilepath
505         << "': " << Out.os().error().message() << '\n';
506     exit(1);
507   }
508 
509   // Current Chunks aren't interesting
510   return Test.run(CurrentFilepath);
511 }
512 
513 std::unique_ptr<ReducerWorkItem>
514 ReducerWorkItem::clone(const TargetMachine *TM) const {
515   auto CloneMMM = std::make_unique<ReducerWorkItem>();
516   if (TM) {
517     // We're assuming the Module IR contents are always unchanged by MIR
518     // reductions, and can share it as a constant.
519     CloneMMM->M = M;
520 
521     // MachineModuleInfo contains a lot of other state used during codegen which
522     // we won't be using here, but we should be able to ignore it (although this
523     // is pretty ugly).
524     CloneMMM->MMI = std::make_unique<MachineModuleInfo>(TM);
525 
526     for (const Function &F : getModule()) {
527       if (auto *MF = MMI->getMachineFunction(F))
528         CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI));
529     }
530   } else {
531     CloneMMM->M = CloneModule(*M);
532   }
533   return CloneMMM;
534 }
535 
536 /// Try to produce some number that indicates a function is getting smaller /
537 /// simpler.
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     if (const auto *Hints = MRI.getRegAllocationHints(Reg))
552       Score += Hints->second.size();
553   }
554 
555   for (const MachineBasicBlock &MBB : MF) {
556     for (const MachineInstr &MI : MBB) {
557       const unsigned Opc = MI.getOpcode();
558 
559       // Reductions may want or need to introduce implicit_defs, so don't count
560       // them.
561       // TODO: These probably should count in some way.
562       if (Opc == TargetOpcode::IMPLICIT_DEF ||
563           Opc == TargetOpcode::G_IMPLICIT_DEF)
564         continue;
565 
566       // Each instruction adds to the score
567       Score += 4;
568 
569       if (Opc == TargetOpcode::PHI || Opc == TargetOpcode::G_PHI ||
570           Opc == TargetOpcode::INLINEASM || Opc == TargetOpcode::INLINEASM_BR)
571         ++Score;
572 
573       if (MI.getFlags() != 0)
574         ++Score;
575 
576       // Increase weight for more operands.
577       for (const MachineOperand &MO : MI.operands()) {
578         ++Score;
579 
580         // Treat registers as more complex.
581         if (MO.isReg()) {
582           ++Score;
583 
584           // And subregisters as even more complex.
585           if (MO.getSubReg()) {
586             ++Score;
587             if (MO.isDef())
588               ++Score;
589           }
590         } else if (MO.isRegMask())
591           ++Score;
592       }
593     }
594   }
595 
596   return Score;
597 }
598 
599 uint64_t ReducerWorkItem::computeMIRComplexityScore() const {
600   uint64_t Score = 0;
601 
602   for (const Function &F : getModule()) {
603     if (auto *MF = MMI->getMachineFunction(F))
604       Score += computeMIRComplexityScoreImpl(*MF);
605   }
606 
607   return Score;
608 }
609 
610 // FIXME: ReduceOperandsSkip has similar function, except it uses larger numbers
611 // for more reduced.
612 static unsigned classifyReductivePower(const Value *V) {
613   if (auto *C = dyn_cast<ConstantData>(V)) {
614     if (C->isNullValue())
615       return 0;
616     if (C->isOneValue())
617       return 1;
618     if (isa<UndefValue>(V))
619       return 2;
620     return 3;
621   }
622 
623   if (isa<GlobalValue>(V))
624     return 4;
625 
626   // TODO: Account for expression size
627   if (isa<ConstantExpr>(V))
628     return 5;
629 
630   if (isa<Constant>(V))
631     return 1;
632 
633   if (isa<Argument>(V))
634     return 6;
635 
636   if (isa<Instruction>(V))
637     return 7;
638 
639   return 0;
640 }
641 
642 // TODO: Additional flags and attributes may be complexity reducing. If we start
643 // adding flags and attributes, they could have negative cost.
644 static uint64_t computeIRComplexityScoreImpl(const Function &F) {
645   uint64_t Score = 1; // Count the function itself
646   SmallVector<std::pair<unsigned, MDNode *>> MDs;
647 
648   AttributeList Attrs = F.getAttributes();
649   for (AttributeSet AttrSet : Attrs)
650     Score += AttrSet.getNumAttributes();
651 
652   for (const BasicBlock &BB : F) {
653     ++Score;
654 
655     for (const Instruction &I : BB) {
656       ++Score;
657 
658       if (const auto *OverflowOp = dyn_cast<OverflowingBinaryOperator>(&I)) {
659         if (OverflowOp->hasNoUnsignedWrap())
660           ++Score;
661         if (OverflowOp->hasNoSignedWrap())
662           ++Score;
663       } else if (const auto *Trunc = dyn_cast<TruncInst>(&I)) {
664         if (Trunc->hasNoSignedWrap())
665           ++Score;
666         if (Trunc->hasNoUnsignedWrap())
667           ++Score;
668       } else if (const auto *ExactOp = dyn_cast<PossiblyExactOperator>(&I)) {
669         if (ExactOp->isExact())
670           ++Score;
671       } else if (const auto *NNI = dyn_cast<PossiblyNonNegInst>(&I)) {
672         if (NNI->hasNonNeg())
673           ++Score;
674       } else if (const auto *PDI = dyn_cast<PossiblyDisjointInst>(&I)) {
675         if (PDI->isDisjoint())
676           ++Score;
677       } else if (const auto *GEP = dyn_cast<GEPOperator>(&I)) {
678         if (GEP->isInBounds())
679           ++Score;
680         if (GEP->hasNoUnsignedSignedWrap())
681           ++Score;
682         if (GEP->hasNoUnsignedWrap())
683           ++Score;
684       } else if (const auto *FPOp = dyn_cast<FPMathOperator>(&I)) {
685         FastMathFlags FMF = FPOp->getFastMathFlags();
686         if (FMF.allowReassoc())
687           ++Score;
688         if (FMF.noNaNs())
689           ++Score;
690         if (FMF.noInfs())
691           ++Score;
692         if (FMF.noSignedZeros())
693           ++Score;
694         if (FMF.allowReciprocal())
695           ++Score;
696         if (FMF.allowContract())
697           ++Score;
698         if (FMF.approxFunc())
699           ++Score;
700       }
701 
702       for (const Value *Operand : I.operands()) {
703         ++Score;
704         Score += classifyReductivePower(Operand);
705       }
706 
707       I.getAllMetadata(MDs);
708       Score += MDs.size();
709       MDs.clear();
710     }
711   }
712 
713   return Score;
714 }
715 
716 uint64_t ReducerWorkItem::computeIRComplexityScore() const {
717   uint64_t Score = 0;
718 
719   const Module &M = getModule();
720   Score += M.named_metadata_size();
721 
722   SmallVector<std::pair<unsigned, MDNode *>, 32> GlobalMetadata;
723   for (const GlobalVariable &GV : M.globals()) {
724     ++Score;
725 
726     if (GV.hasInitializer())
727       Score += classifyReductivePower(GV.getInitializer());
728 
729     // TODO: Account for linkage?
730 
731     GV.getAllMetadata(GlobalMetadata);
732     Score += GlobalMetadata.size();
733     GlobalMetadata.clear();
734   }
735 
736   for (const GlobalAlias &GA : M.aliases())
737     Score += classifyReductivePower(GA.getAliasee());
738 
739   for (const GlobalIFunc &GI : M.ifuncs())
740     Score += classifyReductivePower(GI.getResolver());
741 
742   for (const Function &F : M)
743     Score += computeIRComplexityScoreImpl(F);
744 
745   return Score;
746 }
747 
748 void ReducerWorkItem::writeOutput(raw_ostream &OS, bool EmitBitcode) const {
749   // Requesting bitcode emission with mir is nonsense, so just ignore it.
750   if (EmitBitcode && !isMIR())
751     writeBitcode(OS);
752   else
753     print(OS, /*AnnotationWriter=*/nullptr);
754 }
755 
756 void ReducerWorkItem::readBitcode(MemoryBufferRef Data, LLVMContext &Ctx,
757                                   StringRef ToolName) {
758   Expected<BitcodeFileContents> IF = llvm::getBitcodeFileContents(Data);
759   if (!IF) {
760     WithColor::error(errs(), ToolName) << IF.takeError();
761     exit(1);
762   }
763   BitcodeModule BM = IF->Mods[0];
764   Expected<BitcodeLTOInfo> LI = BM.getLTOInfo();
765   Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(Ctx);
766   if (!LI || !MOrErr) {
767     WithColor::error(errs(), ToolName) << IF.takeError();
768     exit(1);
769   }
770   LTOInfo = std::make_unique<BitcodeLTOInfo>(*LI);
771   M = std::move(MOrErr.get());
772 }
773 
774 void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const {
775   if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) {
776     PassBuilder PB;
777     LoopAnalysisManager LAM;
778     FunctionAnalysisManager FAM;
779     CGSCCAnalysisManager CGAM;
780     ModuleAnalysisManager MAM;
781     PB.registerModuleAnalyses(MAM);
782     PB.registerCGSCCAnalyses(CGAM);
783     PB.registerFunctionAnalyses(FAM);
784     PB.registerLoopAnalyses(LAM);
785     PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
786     ModulePassManager MPM;
787     MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr));
788     MPM.run(*M, MAM);
789   } else {
790     std::unique_ptr<ModuleSummaryIndex> Index;
791     if (LTOInfo && LTOInfo->HasSummary) {
792       ProfileSummaryInfo PSI(*M);
793       Index = std::make_unique<ModuleSummaryIndex>(
794           buildModuleSummaryIndex(*M, nullptr, &PSI));
795     }
796     WriteBitcodeToFile(getModule(), OutStream,
797                        /*ShouldPreserveUseListOrder=*/true, Index.get());
798   }
799 }
800 
801 std::pair<std::unique_ptr<ReducerWorkItem>, bool>
802 llvm::parseReducerWorkItem(StringRef ToolName, StringRef Filename,
803                            LLVMContext &Ctxt,
804                            std::unique_ptr<TargetMachine> &TM, bool IsMIR) {
805   bool IsBitcode = false;
806   Triple TheTriple;
807 
808   auto MMM = std::make_unique<ReducerWorkItem>();
809 
810   if (IsMIR) {
811     initializeTargetInfo();
812 
813     auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
814     if (std::error_code EC = FileOrErr.getError()) {
815       WithColor::error(errs(), ToolName) << EC.message() << '\n';
816       return {nullptr, false};
817     }
818 
819     std::unique_ptr<MIRParser> MParser =
820         createMIRParser(std::move(FileOrErr.get()), Ctxt);
821 
822     auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
823                              StringRef OldDLStr) -> std::optional<std::string> {
824       // NB: We always call createTargetMachineForTriple() even if an explicit
825       // DataLayout is already set in the module since we want to use this
826       // callback to setup the TargetMachine rather than doing it later.
827       std::string IRTargetTriple = DataLayoutTargetTriple.str();
828       if (!TargetTriple.empty())
829         IRTargetTriple = Triple::normalize(TargetTriple);
830       TheTriple = Triple(IRTargetTriple);
831       if (TheTriple.getTriple().empty())
832         TheTriple.setTriple(sys::getDefaultTargetTriple());
833       ExitOnError ExitOnErr(std::string(ToolName) + ": error: ");
834       TM = ExitOnErr(codegen::createTargetMachineForTriple(TheTriple.str()));
835 
836       return TM->createDataLayout().getStringRepresentation();
837     };
838 
839     std::unique_ptr<Module> M = MParser->parseIRModule(SetDataLayout);
840 
841     MMM->MMI = std::make_unique<MachineModuleInfo>(TM.get());
842     MParser->parseMachineFunctions(*M, *MMM->MMI);
843     MMM->M = std::move(M);
844   } else {
845     SMDiagnostic Err;
846     ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
847         MemoryBuffer::getFileOrSTDIN(Filename);
848     if (std::error_code EC = MB.getError()) {
849       WithColor::error(errs(), ToolName)
850           << Filename << ": " << EC.message() << "\n";
851       return {nullptr, false};
852     }
853 
854     if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(),
855                    (const unsigned char *)(*MB)->getBufferEnd())) {
856       std::unique_ptr<Module> Result = parseIR(**MB, Err, Ctxt);
857       if (!Result) {
858         Err.print(ToolName.data(), errs());
859         return {nullptr, false};
860       }
861       MMM->M = std::move(Result);
862     } else {
863       IsBitcode = true;
864       MMM->readBitcode(MemoryBufferRef(**MB), Ctxt, ToolName);
865 
866       if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit)
867         initializeTargetInfo();
868     }
869   }
870   if (MMM->verify(&errs())) {
871     WithColor::error(errs(), ToolName)
872         << Filename << " - input module is broken!\n";
873     return {nullptr, false};
874   }
875   return {std::move(MMM), IsBitcode};
876 }
877