1 //===- ReducerWorkItem.cpp - Wrapper for Module and MachineFunction -------===//
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
7 //===----------------------------------------------------------------------===//
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/TargetInstrInfo.h"
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/Instructions.h"
28 #include "llvm/IR/ModuleSummaryIndex.h"
29 #include "llvm/IR/Operator.h"
30 #include "llvm/IR/Verifier.h"
31 #include "llvm/IRReader/IRReader.h"
32 #include "llvm/MC/TargetRegistry.h"
33 #include "llvm/Passes/PassBuilder.h"
34 #include "llvm/Support/MemoryBufferRef.h"
35 #include "llvm/Support/SourceMgr.h"
36 #include "llvm/Support/TargetSelect.h"
37 #include "llvm/Support/ToolOutputFile.h"
38 #include "llvm/Support/WithColor.h"
39 #include "llvm/Target/TargetMachine.h"
40 #include "llvm/TargetParser/Host.h"
41 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
42 #include "llvm/Transforms/Utils/Cloning.h"
47 ReducerWorkItem::ReducerWorkItem() = default;
48 ReducerWorkItem::~ReducerWorkItem() = default;
50 extern cl::OptionCategory LLVMReduceOptions
;
51 static cl::opt
<std::string
> TargetTriple("mtriple",
52 cl::desc("Set the target triple"),
53 cl::cat(LLVMReduceOptions
));
55 static cl::opt
<bool> TmpFilesAsBitcode(
56 "write-tmp-files-as-bitcode",
57 cl::desc("Always write temporary files as bitcode instead of textual IR"),
58 cl::init(false), cl::cat(LLVMReduceOptions
));
60 static void cloneFrameInfo(
61 MachineFrameInfo
&DstMFI
, const MachineFrameInfo
&SrcMFI
,
62 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
) {
63 DstMFI
.setFrameAddressIsTaken(SrcMFI
.isFrameAddressTaken());
64 DstMFI
.setReturnAddressIsTaken(SrcMFI
.isReturnAddressTaken());
65 DstMFI
.setHasStackMap(SrcMFI
.hasStackMap());
66 DstMFI
.setHasPatchPoint(SrcMFI
.hasPatchPoint());
67 DstMFI
.setUseLocalStackAllocationBlock(
68 SrcMFI
.getUseLocalStackAllocationBlock());
69 DstMFI
.setOffsetAdjustment(SrcMFI
.getOffsetAdjustment());
71 DstMFI
.ensureMaxAlignment(SrcMFI
.getMaxAlign());
72 assert(DstMFI
.getMaxAlign() == SrcMFI
.getMaxAlign() &&
73 "we need to set exact alignment");
75 DstMFI
.setAdjustsStack(SrcMFI
.adjustsStack());
76 DstMFI
.setHasCalls(SrcMFI
.hasCalls());
77 DstMFI
.setHasOpaqueSPAdjustment(SrcMFI
.hasOpaqueSPAdjustment());
78 DstMFI
.setHasCopyImplyingStackAdjustment(
79 SrcMFI
.hasCopyImplyingStackAdjustment());
80 DstMFI
.setHasVAStart(SrcMFI
.hasVAStart());
81 DstMFI
.setHasMustTailInVarArgFunc(SrcMFI
.hasMustTailInVarArgFunc());
82 DstMFI
.setHasTailCall(SrcMFI
.hasTailCall());
84 if (SrcMFI
.isMaxCallFrameSizeComputed())
85 DstMFI
.setMaxCallFrameSize(SrcMFI
.getMaxCallFrameSize());
87 DstMFI
.setCVBytesOfCalleeSavedRegisters(
88 SrcMFI
.getCVBytesOfCalleeSavedRegisters());
90 if (MachineBasicBlock
*SavePt
= SrcMFI
.getSavePoint())
91 DstMFI
.setSavePoint(Src2DstMBB
.find(SavePt
)->second
);
92 if (MachineBasicBlock
*RestorePt
= SrcMFI
.getRestorePoint())
93 DstMFI
.setRestorePoint(Src2DstMBB
.find(RestorePt
)->second
);
96 auto CopyObjectProperties
= [](MachineFrameInfo
&DstMFI
,
97 const MachineFrameInfo
&SrcMFI
, int FI
) {
98 if (SrcMFI
.isStatepointSpillSlotObjectIndex(FI
))
99 DstMFI
.markAsStatepointSpillSlotObjectIndex(FI
);
100 DstMFI
.setObjectSSPLayout(FI
, SrcMFI
.getObjectSSPLayout(FI
));
101 DstMFI
.setObjectZExt(FI
, SrcMFI
.isObjectZExt(FI
));
102 DstMFI
.setObjectSExt(FI
, SrcMFI
.isObjectSExt(FI
));
105 for (int i
= 0, e
= SrcMFI
.getNumObjects() - SrcMFI
.getNumFixedObjects();
109 assert(!SrcMFI
.isFixedObjectIndex(i
));
110 if (SrcMFI
.isVariableSizedObjectIndex(i
)) {
111 NewFI
= DstMFI
.CreateVariableSizedObject(SrcMFI
.getObjectAlign(i
),
112 SrcMFI
.getObjectAllocation(i
));
114 NewFI
= DstMFI
.CreateStackObject(
115 SrcMFI
.getObjectSize(i
), SrcMFI
.getObjectAlign(i
),
116 SrcMFI
.isSpillSlotObjectIndex(i
), SrcMFI
.getObjectAllocation(i
),
117 SrcMFI
.getStackID(i
));
118 DstMFI
.setObjectOffset(NewFI
, SrcMFI
.getObjectOffset(i
));
121 CopyObjectProperties(DstMFI
, SrcMFI
, i
);
124 assert(i
== NewFI
&& "expected to keep stable frame index numbering");
127 // Copy the fixed frame objects backwards to preserve frame index numbers,
128 // since CreateFixedObject uses front insertion.
129 for (int i
= -1; i
>= (int)-SrcMFI
.getNumFixedObjects(); --i
) {
130 assert(SrcMFI
.isFixedObjectIndex(i
));
131 int NewFI
= DstMFI
.CreateFixedObject(
132 SrcMFI
.getObjectSize(i
), SrcMFI
.getObjectOffset(i
),
133 SrcMFI
.isImmutableObjectIndex(i
), SrcMFI
.isAliasedObjectIndex(i
));
134 CopyObjectProperties(DstMFI
, SrcMFI
, i
);
137 assert(i
== NewFI
&& "expected to keep stable frame index numbering");
140 for (unsigned I
= 0, E
= SrcMFI
.getLocalFrameObjectCount(); I
< E
; ++I
) {
141 auto LocalObject
= SrcMFI
.getLocalFrameObjectMap(I
);
142 DstMFI
.mapLocalFrameObject(LocalObject
.first
, LocalObject
.second
);
145 DstMFI
.setCalleeSavedInfo(SrcMFI
.getCalleeSavedInfo());
147 if (SrcMFI
.hasStackProtectorIndex()) {
148 DstMFI
.setStackProtectorIndex(SrcMFI
.getStackProtectorIndex());
151 // FIXME: Needs test, missing MIR serialization.
152 if (SrcMFI
.hasFunctionContextIndex()) {
153 DstMFI
.setFunctionContextIndex(SrcMFI
.getFunctionContextIndex());
157 static void cloneJumpTableInfo(
158 MachineFunction
&DstMF
, const MachineJumpTableInfo
&SrcJTI
,
159 const DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> &Src2DstMBB
) {
161 auto *DstJTI
= DstMF
.getOrCreateJumpTableInfo(SrcJTI
.getEntryKind());
163 std::vector
<MachineBasicBlock
*> DstBBs
;
165 for (const MachineJumpTableEntry
&Entry
: SrcJTI
.getJumpTables()) {
166 for (MachineBasicBlock
*X
: Entry
.MBBs
)
167 DstBBs
.push_back(Src2DstMBB
.find(X
)->second
);
169 DstJTI
->createJumpTableIndex(DstBBs
);
174 static void cloneMemOperands(MachineInstr
&DstMI
, MachineInstr
&SrcMI
,
175 MachineFunction
&SrcMF
, MachineFunction
&DstMF
) {
176 // The new MachineMemOperands should be owned by the new function's
178 PseudoSourceValueManager
&PSVMgr
= DstMF
.getPSVManager();
180 // We also need to remap the PseudoSourceValues from the new function's
181 // PseudoSourceValueManager.
182 SmallVector
<MachineMemOperand
*, 2> NewMMOs
;
183 for (MachineMemOperand
*OldMMO
: SrcMI
.memoperands()) {
184 MachinePointerInfo
NewPtrInfo(OldMMO
->getPointerInfo());
185 if (const PseudoSourceValue
*PSV
=
186 dyn_cast_if_present
<const PseudoSourceValue
*>(NewPtrInfo
.V
)) {
187 switch (PSV
->kind()) {
188 case PseudoSourceValue::Stack
:
189 NewPtrInfo
.V
= PSVMgr
.getStack();
191 case PseudoSourceValue::GOT
:
192 NewPtrInfo
.V
= PSVMgr
.getGOT();
194 case PseudoSourceValue::JumpTable
:
195 NewPtrInfo
.V
= PSVMgr
.getJumpTable();
197 case PseudoSourceValue::ConstantPool
:
198 NewPtrInfo
.V
= PSVMgr
.getConstantPool();
200 case PseudoSourceValue::FixedStack
:
201 NewPtrInfo
.V
= PSVMgr
.getFixedStack(
202 cast
<FixedStackPseudoSourceValue
>(PSV
)->getFrameIndex());
204 case PseudoSourceValue::GlobalValueCallEntry
:
205 NewPtrInfo
.V
= PSVMgr
.getGlobalValueCallEntry(
206 cast
<GlobalValuePseudoSourceValue
>(PSV
)->getValue());
208 case PseudoSourceValue::ExternalSymbolCallEntry
:
209 NewPtrInfo
.V
= PSVMgr
.getExternalSymbolCallEntry(
210 cast
<ExternalSymbolPseudoSourceValue
>(PSV
)->getSymbol());
212 case PseudoSourceValue::TargetCustom
:
214 // FIXME: We have no generic interface for allocating custom PSVs.
215 report_fatal_error("Cloning TargetCustom PSV not handled");
219 MachineMemOperand
*NewMMO
= DstMF
.getMachineMemOperand(
220 NewPtrInfo
, OldMMO
->getFlags(), OldMMO
->getMemoryType(),
221 OldMMO
->getBaseAlign(), OldMMO
->getAAInfo(), OldMMO
->getRanges(),
222 OldMMO
->getSyncScopeID(), OldMMO
->getSuccessOrdering(),
223 OldMMO
->getFailureOrdering());
224 NewMMOs
.push_back(NewMMO
);
227 DstMI
.setMemRefs(DstMF
, NewMMOs
);
230 static std::unique_ptr
<MachineFunction
> cloneMF(MachineFunction
*SrcMF
,
231 MachineModuleInfo
&DestMMI
) {
232 auto DstMF
= std::make_unique
<MachineFunction
>(
233 SrcMF
->getFunction(), SrcMF
->getTarget(), SrcMF
->getSubtarget(),
234 SrcMF
->getFunctionNumber(), DestMMI
);
235 DenseMap
<MachineBasicBlock
*, MachineBasicBlock
*> Src2DstMBB
;
237 auto *SrcMRI
= &SrcMF
->getRegInfo();
238 auto *DstMRI
= &DstMF
->getRegInfo();
241 for (MachineBasicBlock
&SrcMBB
: *SrcMF
) {
242 MachineBasicBlock
*DstMBB
=
243 DstMF
->CreateMachineBasicBlock(SrcMBB
.getBasicBlock());
244 Src2DstMBB
[&SrcMBB
] = DstMBB
;
246 DstMBB
->setCallFrameSize(SrcMBB
.getCallFrameSize());
248 if (SrcMBB
.isIRBlockAddressTaken())
249 DstMBB
->setAddressTakenIRBlock(SrcMBB
.getAddressTakenIRBlock());
250 if (SrcMBB
.isMachineBlockAddressTaken())
251 DstMBB
->setMachineBlockAddressTaken();
253 // FIXME: This is not serialized
254 if (SrcMBB
.hasLabelMustBeEmitted())
255 DstMBB
->setLabelMustBeEmitted();
257 DstMBB
->setAlignment(SrcMBB
.getAlignment());
259 // FIXME: This is not serialized
260 DstMBB
->setMaxBytesForAlignment(SrcMBB
.getMaxBytesForAlignment());
262 DstMBB
->setIsEHPad(SrcMBB
.isEHPad());
263 DstMBB
->setIsEHScopeEntry(SrcMBB
.isEHScopeEntry());
264 DstMBB
->setIsEHCatchretTarget(SrcMBB
.isEHCatchretTarget());
265 DstMBB
->setIsEHFuncletEntry(SrcMBB
.isEHFuncletEntry());
267 // FIXME: These are not serialized
268 DstMBB
->setIsCleanupFuncletEntry(SrcMBB
.isCleanupFuncletEntry());
269 DstMBB
->setIsBeginSection(SrcMBB
.isBeginSection());
270 DstMBB
->setIsEndSection(SrcMBB
.isEndSection());
272 DstMBB
->setSectionID(SrcMBB
.getSectionID());
273 DstMBB
->setIsInlineAsmBrIndirectTarget(
274 SrcMBB
.isInlineAsmBrIndirectTarget());
276 // FIXME: This is not serialized
277 if (std::optional
<uint64_t> Weight
= SrcMBB
.getIrrLoopHeaderWeight())
278 DstMBB
->setIrrLoopHeaderWeight(*Weight
);
281 const MachineFrameInfo
&SrcMFI
= SrcMF
->getFrameInfo();
282 MachineFrameInfo
&DstMFI
= DstMF
->getFrameInfo();
284 // Copy stack objects and other info
285 cloneFrameInfo(DstMFI
, SrcMFI
, Src2DstMBB
);
287 if (MachineJumpTableInfo
*SrcJTI
= SrcMF
->getJumpTableInfo()) {
288 cloneJumpTableInfo(*DstMF
, *SrcJTI
, Src2DstMBB
);
291 // Remap the debug info frame index references.
292 DstMF
->VariableDbgInfos
= SrcMF
->VariableDbgInfos
;
294 // Clone virtual registers
295 for (unsigned I
= 0, E
= SrcMRI
->getNumVirtRegs(); I
!= E
; ++I
) {
296 Register Reg
= Register::index2VirtReg(I
);
297 Register NewReg
= DstMRI
->createIncompleteVirtualRegister(
298 SrcMRI
->getVRegName(Reg
));
299 assert(NewReg
== Reg
&& "expected to preserve virtreg number");
301 DstMRI
->setRegClassOrRegBank(NewReg
, SrcMRI
->getRegClassOrRegBank(Reg
));
303 LLT RegTy
= SrcMRI
->getType(Reg
);
305 DstMRI
->setType(NewReg
, RegTy
);
307 // Copy register allocation hints.
308 const auto &Hints
= SrcMRI
->getRegAllocationHints(Reg
);
309 for (Register PrefReg
: Hints
.second
)
310 DstMRI
->addRegAllocationHint(NewReg
, PrefReg
);
313 const TargetSubtargetInfo
&STI
= DstMF
->getSubtarget();
314 const TargetInstrInfo
*TII
= STI
.getInstrInfo();
315 const TargetRegisterInfo
*TRI
= STI
.getRegisterInfo();
318 for (auto &SrcMBB
: *SrcMF
) {
319 auto *DstMBB
= Src2DstMBB
[&SrcMBB
];
320 DstMF
->push_back(DstMBB
);
322 for (auto It
= SrcMBB
.succ_begin(), IterEnd
= SrcMBB
.succ_end();
323 It
!= IterEnd
; ++It
) {
324 auto *SrcSuccMBB
= *It
;
325 auto *DstSuccMBB
= Src2DstMBB
[SrcSuccMBB
];
326 DstMBB
->addSuccessor(DstSuccMBB
, SrcMBB
.getSuccProbability(It
));
329 for (auto &LI
: SrcMBB
.liveins_dbg())
330 DstMBB
->addLiveIn(LI
);
332 // Make sure MRI knows about registers clobbered by unwinder.
333 if (DstMBB
->isEHPad()) {
334 if (auto *RegMask
= TRI
->getCustomEHPadPreservedMask(*DstMF
))
335 DstMRI
->addPhysRegsUsedFromRegMask(RegMask
);
339 DenseSet
<const uint32_t *> ConstRegisterMasks
;
341 // Track predefined/named regmasks which we ignore.
342 for (const uint32_t *Mask
: TRI
->getRegMasks())
343 ConstRegisterMasks
.insert(Mask
);
345 // Clone instructions.
346 for (auto &SrcMBB
: *SrcMF
) {
347 auto *DstMBB
= Src2DstMBB
[&SrcMBB
];
348 for (auto &SrcMI
: SrcMBB
) {
349 const auto &MCID
= TII
->get(SrcMI
.getOpcode());
350 auto *DstMI
= DstMF
->CreateMachineInstr(MCID
, SrcMI
.getDebugLoc(),
351 /*NoImplicit=*/true);
352 DstMI
->setFlags(SrcMI
.getFlags());
353 DstMI
->setAsmPrinterFlag(SrcMI
.getAsmPrinterFlags());
355 DstMBB
->push_back(DstMI
);
356 for (auto &SrcMO
: SrcMI
.operands()) {
357 MachineOperand
DstMO(SrcMO
);
362 DstMO
.setMBB(Src2DstMBB
[DstMO
.getMBB()]);
363 else if (DstMO
.isRegMask()) {
364 DstMRI
->addPhysRegsUsedFromRegMask(DstMO
.getRegMask());
366 if (!ConstRegisterMasks
.count(DstMO
.getRegMask())) {
367 uint32_t *DstMask
= DstMF
->allocateRegMask();
368 std::memcpy(DstMask
, SrcMO
.getRegMask(),
370 MachineOperand::getRegMaskSize(TRI
->getNumRegs()));
371 DstMO
.setRegMask(DstMask
);
375 DstMI
->addOperand(DstMO
);
378 cloneMemOperands(*DstMI
, SrcMI
, *SrcMF
, *DstMF
);
382 DstMF
->setAlignment(SrcMF
->getAlignment());
383 DstMF
->setExposesReturnsTwice(SrcMF
->exposesReturnsTwice());
384 DstMF
->setHasInlineAsm(SrcMF
->hasInlineAsm());
385 DstMF
->setHasWinCFI(SrcMF
->hasWinCFI());
387 DstMF
->getProperties().reset().set(SrcMF
->getProperties());
389 if (!SrcMF
->getFrameInstructions().empty() ||
390 !SrcMF
->getLongjmpTargets().empty() ||
391 !SrcMF
->getCatchretTargets().empty())
392 report_fatal_error("cloning not implemented for machine function property");
394 DstMF
->setCallsEHReturn(SrcMF
->callsEHReturn());
395 DstMF
->setCallsUnwindInit(SrcMF
->callsUnwindInit());
396 DstMF
->setHasEHCatchret(SrcMF
->hasEHCatchret());
397 DstMF
->setHasEHScopes(SrcMF
->hasEHScopes());
398 DstMF
->setHasEHFunclets(SrcMF
->hasEHFunclets());
399 DstMF
->setIsOutlined(SrcMF
->isOutlined());
401 if (!SrcMF
->getLandingPads().empty() ||
402 !SrcMF
->getCodeViewAnnotations().empty() ||
403 !SrcMF
->getTypeInfos().empty() ||
404 !SrcMF
->getFilterIds().empty() ||
405 SrcMF
->hasAnyWasmLandingPadIndex() ||
406 SrcMF
->hasAnyCallSiteLandingPad() ||
407 SrcMF
->hasAnyCallSiteLabel() ||
408 !SrcMF
->getCallSitesInfo().empty())
409 report_fatal_error("cloning not implemented for machine function property");
411 DstMF
->setDebugInstrNumberingCount(SrcMF
->DebugInstrNumberingCount
);
413 if (!DstMF
->cloneInfoFrom(*SrcMF
, Src2DstMBB
))
414 report_fatal_error("target does not implement MachineFunctionInfo cloning");
416 DstMRI
->freezeReservedRegs(*DstMF
);
418 DstMF
->verify(nullptr, "", /*AbortOnError=*/true);
422 static void initializeTargetInfo() {
423 InitializeAllTargets();
424 InitializeAllTargetMCs();
425 InitializeAllAsmPrinters();
426 InitializeAllAsmParsers();
429 void ReducerWorkItem::print(raw_ostream
&ROS
, void *p
) const {
432 for (Function
&F
: *M
) {
433 if (auto *MF
= MMI
->getMachineFunction(F
))
437 M
->print(ROS
, /*AssemblyAnnotationWriter=*/nullptr,
438 /*ShouldPreserveUseListOrder=*/true);
442 bool ReducerWorkItem::verify(raw_fd_ostream
*OS
) const {
443 if (verifyModule(*M
, OS
))
449 for (const Function
&F
: getModule()) {
450 if (const MachineFunction
*MF
= MMI
->getMachineFunction(F
)) {
451 if (!MF
->verify(nullptr, "", /*AbortOnError=*/false))
459 bool ReducerWorkItem::isReduced(const TestRunner
&Test
) const {
460 const bool UseBitcode
= Test
.inputIsBitcode() || TmpFilesAsBitcode
;
462 SmallString
<128> CurrentFilepath
;
464 // Write ReducerWorkItem to tmp file
466 std::error_code EC
= sys::fs::createTemporaryFile(
467 "llvm-reduce", isMIR() ? "mir" : (UseBitcode
? "bc" : "ll"), FD
,
469 UseBitcode
&& !isMIR() ? sys::fs::OF_None
: sys::fs::OF_Text
);
471 WithColor::error(errs(), Test
.getToolName())
472 << "error making unique filename: " << EC
.message() << '\n';
476 ToolOutputFile
Out(CurrentFilepath
, FD
);
478 writeOutput(Out
.os(), UseBitcode
);
481 if (Out
.os().has_error()) {
482 WithColor::error(errs(), Test
.getToolName())
483 << "error emitting bitcode to file '" << CurrentFilepath
484 << "': " << Out
.os().error().message() << '\n';
488 // Current Chunks aren't interesting
489 return Test
.run(CurrentFilepath
);
492 std::unique_ptr
<ReducerWorkItem
>
493 ReducerWorkItem::clone(const TargetMachine
*TM
) const {
494 auto CloneMMM
= std::make_unique
<ReducerWorkItem
>();
496 // We're assuming the Module IR contents are always unchanged by MIR
497 // reductions, and can share it as a constant.
500 // MachineModuleInfo contains a lot of other state used during codegen which
501 // we won't be using here, but we should be able to ignore it (although this
503 const LLVMTargetMachine
*LLVMTM
=
504 static_cast<const LLVMTargetMachine
*>(TM
);
505 CloneMMM
->MMI
= std::make_unique
<MachineModuleInfo
>(LLVMTM
);
507 for (const Function
&F
: getModule()) {
508 if (auto *MF
= MMI
->getMachineFunction(F
))
509 CloneMMM
->MMI
->insertFunction(F
, cloneMF(MF
, *CloneMMM
->MMI
));
512 CloneMMM
->M
= CloneModule(*M
);
517 /// Try to produce some number that indicates a function is getting smaller /
519 static uint64_t computeMIRComplexityScoreImpl(const MachineFunction
&MF
) {
521 const MachineFrameInfo
&MFI
= MF
.getFrameInfo();
523 // Add for stack objects
524 Score
+= MFI
.getNumObjects();
526 // Add in the block count.
527 Score
+= 2 * MF
.size();
529 const MachineRegisterInfo
&MRI
= MF
.getRegInfo();
530 for (unsigned I
= 0, E
= MRI
.getNumVirtRegs(); I
!= E
; ++I
) {
531 Register Reg
= Register::index2VirtReg(I
);
532 Score
+= MRI
.getRegAllocationHints(Reg
).second
.size();
535 for (const MachineBasicBlock
&MBB
: MF
) {
536 for (const MachineInstr
&MI
: MBB
) {
537 const unsigned Opc
= MI
.getOpcode();
539 // Reductions may want or need to introduce implicit_defs, so don't count
541 // TODO: These probably should count in some way.
542 if (Opc
== TargetOpcode::IMPLICIT_DEF
||
543 Opc
== TargetOpcode::G_IMPLICIT_DEF
)
546 // Each instruction adds to the score
549 if (Opc
== TargetOpcode::PHI
|| Opc
== TargetOpcode::G_PHI
||
550 Opc
== TargetOpcode::INLINEASM
|| Opc
== TargetOpcode::INLINEASM_BR
)
553 if (MI
.getFlags() != 0)
556 // Increase weight for more operands.
557 for (const MachineOperand
&MO
: MI
.operands()) {
560 // Treat registers as more complex.
564 // And subregisters as even more complex.
565 if (MO
.getSubReg()) {
570 } else if (MO
.isRegMask())
579 uint64_t ReducerWorkItem::computeMIRComplexityScore() const {
582 for (const Function
&F
: getModule()) {
583 if (auto *MF
= MMI
->getMachineFunction(F
))
584 Score
+= computeMIRComplexityScoreImpl(*MF
);
590 // FIXME: ReduceOperandsSkip has similar function, except it uses larger numbers
592 static unsigned classifyReductivePower(const Value
*V
) {
593 if (auto *C
= dyn_cast
<ConstantData
>(V
)) {
594 if (C
->isNullValue())
598 if (isa
<UndefValue
>(V
))
603 if (isa
<GlobalValue
>(V
))
606 // TODO: Account for expression size
607 if (isa
<ConstantExpr
>(V
))
610 if (isa
<Constant
>(V
))
613 if (isa
<Argument
>(V
))
616 if (isa
<Instruction
>(V
))
622 // TODO: Additional flags and attributes may be complexity reducing. If we start
623 // adding flags and attributes, they could have negative cost.
624 static uint64_t computeIRComplexityScoreImpl(const Function
&F
) {
625 uint64_t Score
= 1; // Count the function itself
626 SmallVector
<std::pair
<unsigned, MDNode
*>> MDs
;
628 AttributeList Attrs
= F
.getAttributes();
629 for (AttributeSet AttrSet
: Attrs
)
630 Score
+= AttrSet
.getNumAttributes();
632 for (const BasicBlock
&BB
: F
) {
635 for (const Instruction
&I
: BB
) {
638 if (const auto *OverflowOp
= dyn_cast
<OverflowingBinaryOperator
>(&I
)) {
639 if (OverflowOp
->hasNoUnsignedWrap())
641 if (OverflowOp
->hasNoSignedWrap())
643 } else if (const auto *GEP
= dyn_cast
<GEPOperator
>(&I
)) {
644 if (GEP
->isInBounds())
646 } else if (const auto *ExactOp
= dyn_cast
<PossiblyExactOperator
>(&I
)) {
647 if (ExactOp
->isExact())
649 } else if (const auto *FPOp
= dyn_cast
<FPMathOperator
>(&I
)) {
650 FastMathFlags FMF
= FPOp
->getFastMathFlags();
651 if (FMF
.allowReassoc())
657 if (FMF
.noSignedZeros())
659 if (FMF
.allowReciprocal())
661 if (FMF
.allowContract())
663 if (FMF
.approxFunc())
667 for (const Value
*Operand
: I
.operands()) {
669 Score
+= classifyReductivePower(Operand
);
672 I
.getAllMetadata(MDs
);
681 uint64_t ReducerWorkItem::computeIRComplexityScore() const {
684 const Module
&M
= getModule();
685 Score
+= M
.named_metadata_size();
687 SmallVector
<std::pair
<unsigned, MDNode
*>, 32> GlobalMetadata
;
688 for (const GlobalVariable
&GV
: M
.globals()) {
691 if (GV
.hasInitializer())
692 Score
+= classifyReductivePower(GV
.getInitializer());
694 // TODO: Account for linkage?
696 GV
.getAllMetadata(GlobalMetadata
);
697 Score
+= GlobalMetadata
.size();
698 GlobalMetadata
.clear();
701 for (const GlobalAlias
&GA
: M
.aliases())
702 Score
+= classifyReductivePower(GA
.getAliasee());
704 for (const GlobalIFunc
&GI
: M
.ifuncs())
705 Score
+= classifyReductivePower(GI
.getResolver());
707 for (const Function
&F
: M
)
708 Score
+= computeIRComplexityScoreImpl(F
);
713 void ReducerWorkItem::writeOutput(raw_ostream
&OS
, bool EmitBitcode
) const {
714 // Requesting bitcode emission with mir is nonsense, so just ignore it.
715 if (EmitBitcode
&& !isMIR())
718 print(OS
, /*AnnotationWriter=*/nullptr);
721 void ReducerWorkItem::readBitcode(MemoryBufferRef Data
, LLVMContext
&Ctx
,
722 StringRef ToolName
) {
723 Expected
<BitcodeFileContents
> IF
= llvm::getBitcodeFileContents(Data
);
725 WithColor::error(errs(), ToolName
) << IF
.takeError();
728 BitcodeModule BM
= IF
->Mods
[0];
729 Expected
<BitcodeLTOInfo
> LI
= BM
.getLTOInfo();
730 Expected
<std::unique_ptr
<Module
>> MOrErr
= BM
.parseModule(Ctx
);
731 if (!LI
|| !MOrErr
) {
732 WithColor::error(errs(), ToolName
) << IF
.takeError();
735 LTOInfo
= std::make_unique
<BitcodeLTOInfo
>(*LI
);
736 M
= std::move(MOrErr
.get());
739 void ReducerWorkItem::writeBitcode(raw_ostream
&OutStream
) const {
740 if (LTOInfo
&& LTOInfo
->IsThinLTO
&& LTOInfo
->EnableSplitLTOUnit
) {
742 LoopAnalysisManager LAM
;
743 FunctionAnalysisManager FAM
;
744 CGSCCAnalysisManager CGAM
;
745 ModuleAnalysisManager MAM
;
746 PB
.registerModuleAnalyses(MAM
);
747 PB
.registerCGSCCAnalyses(CGAM
);
748 PB
.registerFunctionAnalyses(FAM
);
749 PB
.registerLoopAnalyses(LAM
);
750 PB
.crossRegisterProxies(LAM
, FAM
, CGAM
, MAM
);
751 ModulePassManager MPM
;
752 MPM
.addPass(ThinLTOBitcodeWriterPass(OutStream
, nullptr));
755 std::unique_ptr
<ModuleSummaryIndex
> Index
;
756 if (LTOInfo
&& LTOInfo
->HasSummary
) {
757 ProfileSummaryInfo
PSI(*M
);
758 Index
= std::make_unique
<ModuleSummaryIndex
>(
759 buildModuleSummaryIndex(*M
, nullptr, &PSI
));
761 WriteBitcodeToFile(getModule(), OutStream
,
762 /*ShouldPreserveUseListOrder=*/true, Index
.get());
766 std::pair
<std::unique_ptr
<ReducerWorkItem
>, bool>
767 llvm::parseReducerWorkItem(StringRef ToolName
, StringRef Filename
,
769 std::unique_ptr
<TargetMachine
> &TM
, bool IsMIR
) {
770 bool IsBitcode
= false;
773 auto MMM
= std::make_unique
<ReducerWorkItem
>();
776 initializeTargetInfo();
778 auto FileOrErr
= MemoryBuffer::getFileOrSTDIN(Filename
, /*IsText=*/true);
779 if (std::error_code EC
= FileOrErr
.getError()) {
780 WithColor::error(errs(), ToolName
) << EC
.message() << '\n';
781 return {nullptr, false};
784 std::unique_ptr
<MIRParser
> MParser
=
785 createMIRParser(std::move(FileOrErr
.get()), Ctxt
);
787 auto SetDataLayout
= [&](StringRef DataLayoutTargetTriple
,
788 StringRef OldDLStr
) -> std::optional
<std::string
> {
789 // NB: We always call createTargetMachineForTriple() even if an explicit
790 // DataLayout is already set in the module since we want to use this
791 // callback to setup the TargetMachine rather than doing it later.
792 std::string IRTargetTriple
= DataLayoutTargetTriple
.str();
793 if (!TargetTriple
.empty())
794 IRTargetTriple
= Triple::normalize(TargetTriple
);
795 TheTriple
= Triple(IRTargetTriple
);
796 if (TheTriple
.getTriple().empty())
797 TheTriple
.setTriple(sys::getDefaultTargetTriple());
798 ExitOnError
ExitOnErr(std::string(ToolName
) + ": error: ");
799 TM
= ExitOnErr(codegen::createTargetMachineForTriple(TheTriple
.str()));
801 return TM
->createDataLayout().getStringRepresentation();
804 std::unique_ptr
<Module
> M
= MParser
->parseIRModule(SetDataLayout
);
805 LLVMTargetMachine
*LLVMTM
= static_cast<LLVMTargetMachine
*>(TM
.get());
807 MMM
->MMI
= std::make_unique
<MachineModuleInfo
>(LLVMTM
);
808 MParser
->parseMachineFunctions(*M
, *MMM
->MMI
);
809 MMM
->M
= std::move(M
);
812 ErrorOr
<std::unique_ptr
<MemoryBuffer
>> MB
=
813 MemoryBuffer::getFileOrSTDIN(Filename
);
814 if (std::error_code EC
= MB
.getError()) {
815 WithColor::error(errs(), ToolName
)
816 << Filename
<< ": " << EC
.message() << "\n";
817 return {nullptr, false};
820 if (!isBitcode((const unsigned char *)(*MB
)->getBufferStart(),
821 (const unsigned char *)(*MB
)->getBufferEnd())) {
822 std::unique_ptr
<Module
> Result
= parseIR(**MB
, Err
, Ctxt
);
824 Err
.print(ToolName
.data(), errs());
825 return {nullptr, false};
827 MMM
->M
= std::move(Result
);
830 MMM
->readBitcode(MemoryBufferRef(**MB
), Ctxt
, ToolName
);
832 if (MMM
->LTOInfo
->IsThinLTO
&& MMM
->LTOInfo
->EnableSplitLTOUnit
)
833 initializeTargetInfo();
836 if (MMM
->verify(&errs())) {
837 WithColor::error(errs(), ToolName
)
838 << Filename
<< " - input module is broken!\n";
839 return {nullptr, false};
841 return {std::move(MMM
), IsBitcode
};