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