ReducerWorkItem.cpp 27 KB

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