156fa1b4fSSamuel //===- DeltaManager.cpp - Runs Delta Passes to reduce Input ---------------===// 256fa1b4fSSamuel // 356fa1b4fSSamuel // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 456fa1b4fSSamuel // See https://llvm.org/LICENSE.txt for license information. 556fa1b4fSSamuel // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 656fa1b4fSSamuel // 756fa1b4fSSamuel //===----------------------------------------------------------------------===// 856fa1b4fSSamuel // 956fa1b4fSSamuel // This file calls each specialized Delta pass in order to reduce the input IR 1056fa1b4fSSamuel // file. 1156fa1b4fSSamuel // 1256fa1b4fSSamuel //===----------------------------------------------------------------------===// 1356fa1b4fSSamuel 1456fa1b4fSSamuel #include "DeltaManager.h" 1542c7f494SClemens Wasser #include "ReducerWorkItem.h" 1656fa1b4fSSamuel #include "TestRunner.h" 1756fa1b4fSSamuel #include "deltas/Delta.h" 1856fa1b4fSSamuel #include "deltas/ReduceAliases.h" 1956fa1b4fSSamuel #include "deltas/ReduceArguments.h" 2056fa1b4fSSamuel #include "deltas/ReduceAttributes.h" 2156fa1b4fSSamuel #include "deltas/ReduceBasicBlocks.h" 222c799b77SMatthew Voss #include "deltas/ReduceDIMetadata.h" 235ff67204SStephen Tozer #include "deltas/ReduceDbgRecords.h" 24*42067f26SRobert Barinov #include "deltas/ReduceDistinctMetadata.h" 2556fa1b4fSSamuel #include "deltas/ReduceFunctionBodies.h" 2656fa1b4fSSamuel #include "deltas/ReduceFunctions.h" 2780ba72b0SArthur Eubanks #include "deltas/ReduceGlobalObjects.h" 2856fa1b4fSSamuel #include "deltas/ReduceGlobalValues.h" 2956fa1b4fSSamuel #include "deltas/ReduceGlobalVarInitializers.h" 3056fa1b4fSSamuel #include "deltas/ReduceGlobalVars.h" 313939e99aSMatt Arsenault #include "deltas/ReduceIRReferences.h" 3227902eeaSMatt Arsenault #include "deltas/ReduceInstructionFlags.h" 3320110521SMatt Arsenault #include "deltas/ReduceInstructionFlagsMIR.h" 3456fa1b4fSSamuel #include "deltas/ReduceInstructions.h" 35fd41738eSMarkus Lavin #include "deltas/ReduceInstructionsMIR.h" 36a455c916SMatt Arsenault #include "deltas/ReduceInvokes.h" 37596fdf75SMatt Arsenault #include "deltas/ReduceMemoryOperations.h" 3856fa1b4fSSamuel #include "deltas/ReduceMetadata.h" 39d2e10364SArthur Eubanks #include "deltas/ReduceModuleData.h" 40573a5de7SMatt Arsenault #include "deltas/ReduceOpcodes.h" 4156fa1b4fSSamuel #include "deltas/ReduceOperandBundles.h" 42f18c0739SSamuel #include "deltas/ReduceOperands.h" 43c15f930eSMichael Kruse #include "deltas/ReduceOperandsSkip.h" 44dd71b65cSMichael Kruse #include "deltas/ReduceOperandsToArgs.h" 45e24b390dSMatt Arsenault #include "deltas/ReduceRegisterDefs.h" 460f9d9eddSMatt Arsenault #include "deltas/ReduceRegisterMasks.h" 4747c8ec81SMatt Arsenault #include "deltas/ReduceRegisterUses.h" 4856fa1b4fSSamuel #include "deltas/ReduceSpecialGlobals.h" 492f1fa624SJohn Regehr #include "deltas/ReduceUsingSimplifyCFG.h" 50a0dcbe45SMatt Arsenault #include "deltas/ReduceVirtualRegisters.h" 51bd1f80f5SArthur Eubanks #include "deltas/RunIRPasses.h" 52eea11e73SMatt Arsenault #include "deltas/SimplifyInstructions.h" 530fbb2615SArthur Eubanks #include "deltas/StripDebugInfo.h" 54333ffafbSMatt Arsenault #include "llvm/ADT/SmallSet.h" 55545a8177SArthur Eubanks #include "llvm/Support/CommandLine.h" 5656fa1b4fSSamuel 57545a8177SArthur Eubanks using namespace llvm; 5856fa1b4fSSamuel 59c3bc72ccSMatt Arsenault using SmallStringSet = SmallSet<StringRef, 8>; 60c3bc72ccSMatt Arsenault 610d36d84dSMarkus Lavin extern cl::OptionCategory LLVMReduceOptions; 62c3bc72ccSMatt Arsenault static cl::list<std::string> 63545a8177SArthur Eubanks DeltaPasses("delta-passes", 64545a8177SArthur Eubanks cl::desc("Delta passes to run, separated by commas. By " 650d36d84dSMarkus Lavin "default, run all delta passes."), 66c3bc72ccSMatt Arsenault cl::cat(LLVMReduceOptions), cl::CommaSeparated); 67c3bc72ccSMatt Arsenault 68c3bc72ccSMatt Arsenault static cl::list<std::string> 69c3bc72ccSMatt Arsenault SkipDeltaPasses("skip-delta-passes", 70c3bc72ccSMatt Arsenault cl::desc("Delta passes to not run, separated by commas. By " 71c3bc72ccSMatt Arsenault "default, run all delta passes."), 72c3bc72ccSMatt Arsenault cl::cat(LLVMReduceOptions), cl::CommaSeparated); 73545a8177SArthur Eubanks 74545a8177SArthur Eubanks #define DELTA_PASSES \ 75cd434a20Sowenca do { \ 760fbb2615SArthur Eubanks DELTA_PASS("strip-debug-info", stripDebugInfoDeltaPass) \ 7771d1bd14SJohn Regehr DELTA_PASS("functions", reduceFunctionsDeltaPass) \ 7871d1bd14SJohn Regehr DELTA_PASS("function-bodies", reduceFunctionBodiesDeltaPass) \ 79545a8177SArthur Eubanks DELTA_PASS("special-globals", reduceSpecialGlobalsDeltaPass) \ 80545a8177SArthur Eubanks DELTA_PASS("aliases", reduceAliasesDeltaPass) \ 81bc3e4923SMatt Arsenault DELTA_PASS("ifuncs", reduceIFuncsDeltaPass) \ 8208d1c43cSMatt Arsenault DELTA_PASS("simplify-conditionals-true", reduceConditionalsTrueDeltaPass) \ 8340bdfd39SJeremy Morse DELTA_PASS("simplify-conditionals-false", \ 8440bdfd39SJeremy Morse reduceConditionalsFalseDeltaPass) \ 85a455c916SMatt Arsenault DELTA_PASS("invokes", reduceInvokesDeltaPass) \ 8640bdfd39SJeremy Morse DELTA_PASS("unreachable-basic-blocks", \ 8740bdfd39SJeremy Morse reduceUnreachableBasicBlocksDeltaPass) \ 88545a8177SArthur Eubanks DELTA_PASS("basic-blocks", reduceBasicBlocksDeltaPass) \ 8945a91c15SMatt Arsenault DELTA_PASS("simplify-cfg", reduceUsingSimplifyCFGDeltaPass) \ 9047e44c0cSMatt Arsenault DELTA_PASS("function-data", reduceFunctionDataDeltaPass) \ 91545a8177SArthur Eubanks DELTA_PASS("global-values", reduceGlobalValuesDeltaPass) \ 9280ba72b0SArthur Eubanks DELTA_PASS("global-objects", reduceGlobalObjectsDeltaPass) \ 93545a8177SArthur Eubanks DELTA_PASS("global-initializers", reduceGlobalsInitializersDeltaPass) \ 94545a8177SArthur Eubanks DELTA_PASS("global-variables", reduceGlobalsDeltaPass) \ 952c799b77SMatthew Voss DELTA_PASS("di-metadata", reduceDIMetadataDeltaPass) \ 96ababa964SOrlando Cazalet-Hyams DELTA_PASS("dbg-records", reduceDbgRecordDeltaPass) \ 97*42067f26SRobert Barinov DELTA_PASS("distinct-metadata", reduceDistinctMetadataDeltaPass) \ 98545a8177SArthur Eubanks DELTA_PASS("metadata", reduceMetadataDeltaPass) \ 995f6bf752SMatt Arsenault DELTA_PASS("named-metadata", reduceNamedMetadataDeltaPass) \ 100545a8177SArthur Eubanks DELTA_PASS("arguments", reduceArgumentsDeltaPass) \ 101545a8177SArthur Eubanks DELTA_PASS("instructions", reduceInstructionsDeltaPass) \ 102eea11e73SMatt Arsenault DELTA_PASS("simplify-instructions", simplifyInstructionsDeltaPass) \ 103bd1f80f5SArthur Eubanks DELTA_PASS("ir-passes", runIRPassesDeltaPass) \ 10496605639SArthur Eubanks DELTA_PASS("operands-zero", reduceOperandsZeroDeltaPass) \ 10596605639SArthur Eubanks DELTA_PASS("operands-one", reduceOperandsOneDeltaPass) \ 10626107559SMatt Arsenault DELTA_PASS("operands-nan", reduceOperandsNaNDeltaPass) \ 107dd71b65cSMichael Kruse DELTA_PASS("operands-to-args", reduceOperandsToArgsDeltaPass) \ 108c15f930eSMichael Kruse DELTA_PASS("operands-skip", reduceOperandsSkipDeltaPass) \ 109545a8177SArthur Eubanks DELTA_PASS("operand-bundles", reduceOperandBundesDeltaPass) \ 110545a8177SArthur Eubanks DELTA_PASS("attributes", reduceAttributesDeltaPass) \ 111cd434a20Sowenca DELTA_PASS("module-data", reduceModuleDataDeltaPass) \ 112573a5de7SMatt Arsenault DELTA_PASS("opcodes", reduceOpcodesDeltaPass) \ 113596fdf75SMatt Arsenault DELTA_PASS("volatile", reduceVolatileInstructionsDeltaPass) \ 11483da1a6aSMatt Arsenault DELTA_PASS("atomic-ordering", reduceAtomicOrderingDeltaPass) \ 115b1e17199SMatt Arsenault DELTA_PASS("syncscopes", reduceAtomicSyncScopesDeltaPass) \ 11627902eeaSMatt Arsenault DELTA_PASS("instruction-flags", reduceInstructionFlagsDeltaPass) \ 117cd434a20Sowenca } while (false) 118545a8177SArthur Eubanks 119fd41738eSMarkus Lavin #define DELTA_PASSES_MIR \ 120cd434a20Sowenca do { \ 121853a46cfSFlorian Mayer DELTA_PASS("instructions", reduceInstructionsMIRDeltaPass) \ 1223939e99aSMatt Arsenault DELTA_PASS("ir-instruction-references", \ 1233939e99aSMatt Arsenault reduceIRInstructionReferencesDeltaPass) \ 1243939e99aSMatt Arsenault DELTA_PASS("ir-block-references", reduceIRBlockReferencesDeltaPass) \ 12520110521SMatt Arsenault DELTA_PASS("ir-function-references", reduceIRFunctionReferencesDeltaPass) \ 126a0dcbe45SMatt Arsenault DELTA_PASS("instruction-flags", reduceInstructionFlagsMIRDeltaPass) \ 12747c8ec81SMatt Arsenault DELTA_PASS("register-uses", reduceRegisterUsesMIRDeltaPass) \ 128e24b390dSMatt Arsenault DELTA_PASS("register-defs", reduceRegisterDefsMIRDeltaPass) \ 129cd434a20Sowenca DELTA_PASS("register-hints", reduceVirtualRegisterHintsDeltaPass) \ 1300f9d9eddSMatt Arsenault DELTA_PASS("register-masks", reduceRegisterMasksMIRDeltaPass) \ 131cd434a20Sowenca } while (false) 132fd41738eSMarkus Lavin 133c3bc72ccSMatt Arsenault static void runAllDeltaPasses(TestRunner &Tester, 134c3bc72ccSMatt Arsenault const SmallStringSet &SkipPass) { 135c3bc72ccSMatt Arsenault #define DELTA_PASS(NAME, FUNC) \ 136c3bc72ccSMatt Arsenault if (!SkipPass.count(NAME)) { \ 137c3bc72ccSMatt Arsenault FUNC(Tester); \ 138c3bc72ccSMatt Arsenault } 139fd41738eSMarkus Lavin if (Tester.getProgram().isMIR()) { 140cd434a20Sowenca DELTA_PASSES_MIR; 141fd41738eSMarkus Lavin } else { 142cd434a20Sowenca DELTA_PASSES; 143fd41738eSMarkus Lavin } 144545a8177SArthur Eubanks #undef DELTA_PASS 14556fa1b4fSSamuel } 146545a8177SArthur Eubanks 147545a8177SArthur Eubanks static void runDeltaPassName(TestRunner &Tester, StringRef PassName) { 148545a8177SArthur Eubanks #define DELTA_PASS(NAME, FUNC) \ 149545a8177SArthur Eubanks if (PassName == NAME) { \ 150545a8177SArthur Eubanks FUNC(Tester); \ 151545a8177SArthur Eubanks return; \ 152545a8177SArthur Eubanks } 153fd41738eSMarkus Lavin if (Tester.getProgram().isMIR()) { 154cd434a20Sowenca DELTA_PASSES_MIR; 155fd41738eSMarkus Lavin } else { 156cd434a20Sowenca DELTA_PASSES; 157fd41738eSMarkus Lavin } 158545a8177SArthur Eubanks #undef DELTA_PASS 159c3bc72ccSMatt Arsenault 160c3bc72ccSMatt Arsenault // We should have errored on unrecognized passes before trying to run 161c3bc72ccSMatt Arsenault // anything. 162c3bc72ccSMatt Arsenault llvm_unreachable("unknown delta pass"); 163545a8177SArthur Eubanks } 164545a8177SArthur Eubanks 165545a8177SArthur Eubanks void llvm::printDeltaPasses(raw_ostream &OS) { 166545a8177SArthur Eubanks OS << "Delta passes (pass to `--delta-passes=` as a comma separated list):\n"; 167545a8177SArthur Eubanks #define DELTA_PASS(NAME, FUNC) OS << " " << NAME << "\n"; 168fd41738eSMarkus Lavin OS << " IR:\n"; 169cd434a20Sowenca DELTA_PASSES; 170fd41738eSMarkus Lavin OS << " MIR:\n"; 171cd434a20Sowenca DELTA_PASSES_MIR; 172545a8177SArthur Eubanks #undef DELTA_PASS 173545a8177SArthur Eubanks } 174545a8177SArthur Eubanks 175c3bc72ccSMatt Arsenault // Built a set of available delta passes. 176c3bc72ccSMatt Arsenault static void collectPassNames(const TestRunner &Tester, 177c3bc72ccSMatt Arsenault SmallStringSet &NameSet) { 178c3bc72ccSMatt Arsenault #define DELTA_PASS(NAME, FUNC) NameSet.insert(NAME); 179c3bc72ccSMatt Arsenault if (Tester.getProgram().isMIR()) { 180c3bc72ccSMatt Arsenault DELTA_PASSES_MIR; 181c3bc72ccSMatt Arsenault } else { 182c3bc72ccSMatt Arsenault DELTA_PASSES; 183c3bc72ccSMatt Arsenault } 184c3bc72ccSMatt Arsenault #undef DELTA_PASS 185c3bc72ccSMatt Arsenault } 186c3bc72ccSMatt Arsenault 187c3bc72ccSMatt Arsenault /// Verify all requested or skipped passes are valid names, and return them in a 188c3bc72ccSMatt Arsenault /// set. 189c3bc72ccSMatt Arsenault static SmallStringSet handlePassList(const TestRunner &Tester, 190c3bc72ccSMatt Arsenault const cl::list<std::string> &PassList) { 191c3bc72ccSMatt Arsenault SmallStringSet AllPasses; 192c3bc72ccSMatt Arsenault collectPassNames(Tester, AllPasses); 193c3bc72ccSMatt Arsenault 194c3bc72ccSMatt Arsenault SmallStringSet PassSet; 195c3bc72ccSMatt Arsenault for (StringRef PassName : PassList) { 196c3bc72ccSMatt Arsenault if (!AllPasses.count(PassName)) { 197c3bc72ccSMatt Arsenault errs() << "unknown pass \"" << PassName << "\"\n"; 198c3bc72ccSMatt Arsenault exit(1); 199c3bc72ccSMatt Arsenault } 200c3bc72ccSMatt Arsenault 201c3bc72ccSMatt Arsenault PassSet.insert(PassName); 202c3bc72ccSMatt Arsenault } 203c3bc72ccSMatt Arsenault 204c3bc72ccSMatt Arsenault return PassSet; 205c3bc72ccSMatt Arsenault } 206c3bc72ccSMatt Arsenault 2074eec1710SJohn Regehr void llvm::runDeltaPasses(TestRunner &Tester, int MaxPassIterations) { 20835264e71SMatt Arsenault uint64_t OldComplexity = Tester.getProgram().getComplexityScore(); 209c3bc72ccSMatt Arsenault 210c3bc72ccSMatt Arsenault SmallStringSet RunPassSet, SkipPassSet; 211c3bc72ccSMatt Arsenault 212c3bc72ccSMatt Arsenault if (!DeltaPasses.empty()) 213c3bc72ccSMatt Arsenault RunPassSet = handlePassList(Tester, DeltaPasses); 214c3bc72ccSMatt Arsenault 215c3bc72ccSMatt Arsenault if (!SkipDeltaPasses.empty()) 216c3bc72ccSMatt Arsenault SkipPassSet = handlePassList(Tester, SkipDeltaPasses); 217c3bc72ccSMatt Arsenault 2184eec1710SJohn Regehr for (int Iter = 0; Iter < MaxPassIterations; ++Iter) { 219545a8177SArthur Eubanks if (DeltaPasses.empty()) { 220c3bc72ccSMatt Arsenault runAllDeltaPasses(Tester, SkipPassSet); 221545a8177SArthur Eubanks } else { 222c3bc72ccSMatt Arsenault for (StringRef PassName : DeltaPasses) { 223c3bc72ccSMatt Arsenault if (!SkipPassSet.count(PassName)) 224c3bc72ccSMatt Arsenault runDeltaPassName(Tester, PassName); 225545a8177SArthur Eubanks } 226545a8177SArthur Eubanks } 227c3bc72ccSMatt Arsenault 22835264e71SMatt Arsenault uint64_t NewComplexity = Tester.getProgram().getComplexityScore(); 22935264e71SMatt Arsenault if (NewComplexity >= OldComplexity) 2304eec1710SJohn Regehr break; 23135264e71SMatt Arsenault OldComplexity = NewComplexity; 2324eec1710SJohn Regehr } 233545a8177SArthur Eubanks } 234