aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-07-31 21:22:58 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-12-22 09:58:08 +0000
commite55e5e640b052220b1cd9f86f9729662df5b1e02 (patch)
tree69e53f4bc6869aac9aa198548da5f2ec332a7e3e /contrib/llvm-project/llvm/include
parente50e5090c165b2eb32ecc3957ff24e5cfab182bf (diff)
downloadsrc-e55e5e640b052220b1cd9f86f9729662df5b1e02.tar.gz
src-e55e5e640b052220b1cd9f86f9729662df5b1e02.zip
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
master 2e10b7a39b9, the last commit before the llvmorg-12-init tag, from which release/11.x was branched. Note that for now, I rolled back all our local changes to make merging easier, and I will reapply the still-relevant ones after updating to 11.0.0-rc1. (cherry picked from commit 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
Diffstat (limited to 'contrib/llvm-project/llvm/include')
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/Core.h56
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/DataTypes.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/DebugInfo.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/ExecutionEngine.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/Orc.h335
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/Transforms/Coroutines.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm-c/lto.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/APFloat.h72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/APInt.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/AllocatorList.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Any.h63
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/BitVector.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Bitfields.h289
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/BitmaskEnum.h41
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/CachedHashString.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/CoalescingBitVector.h444
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/DeltaAlgorithm.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/DenseMap.h87
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/DenseMapInfo.h114
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/DenseSet.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/EnumeratedArray.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h141
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/FoldingSet.h138
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h225
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Hashing.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ImmutableMap.h98
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ImmutableSet.h104
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/IntervalMap.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Optional.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PointerEmbeddedInt.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PointerSumType.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PointerUnion.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PostOrderIterator.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/PriorityWorklist.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SCCIterator.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h631
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ScopedHashTable.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SetOperations.h21
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SetVector.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SmallString.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h107
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SparseMultiSet.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/SparseSet.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/StringExtras.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/StringMap.h230
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/StringMapEntry.h135
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/StringRef.h32
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/StringSet.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/TinyPtrVector.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Triple.h44
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Twine.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/TypeSwitch.h176
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/Waymarking.h325
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/bit.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/fallible_iterator.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ilist.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ADT/iterator.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/AliasAnalysis.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/AliasSetTracker.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/AssumeBundleQueries.h167
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/AssumptionCache.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfo.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h126
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/BranchProbabilityInfo.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CFG.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CFGPrinter.h194
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CGSCCPassManager.h87
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CallGraph.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CaptureTracking.h46
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/CodeMetrics.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ConstantFolding.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DDG.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DependenceAnalysis.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DependenceGraphBuilder.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DivergenceAnalysis.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DomTreeUpdater.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/DominanceFrontier.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/EHPersonalities.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/HeatUtils.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/IVDescriptors.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/IndirectCallVisitor.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InlineAdvisor.h238
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InlineCost.h108
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InlineFeaturesAnalysis.h45
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h70
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InstructionPrecedenceTracking.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/InstructionSimplify.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LazyCallGraph.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/Loads.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopAccessAnalysis.h136
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopAnalysisManager.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfo.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfoImpl.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopNestAnalysis.h162
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/LoopPass.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MLInlineAdvisor.h107
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MLModelRunner.h39
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MemoryLocation.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSA.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSAUpdater.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/MustExecute.h135
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/OrderedBasicBlock.h74
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/OrderedInstructions.h64
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/Passes.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/PhiValues.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/PostDominators.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ProfileSummaryInfo.h107
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/PtrUseVisitor.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfo.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfoImpl.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/RegionPass.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolution.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h69
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ScopedNoAliasAA.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/StackLifetime.h202
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/StackSafetyAnalysis.h59
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/SyncDependenceAnalysis.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/SyntheticCountsUtils.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h115
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.def36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h923
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h715
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/Utils/Local.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/Utils/TFUtils.h115
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ValueLattice.h267
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/ValueTracking.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/VecFuncs.def23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Analysis/VectorUtils.h237
-rw-r--r--contrib/llvm-project/llvm/include/llvm/AsmParser/Parser.h81
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/COFF.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.def94
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.h39
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h129
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/VE.def48
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/MachO.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/Magic.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackDocument.h99
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/Wasm.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/WasmRelocs.def31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/BinaryFormat/XCOFF.h57
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Bitcode/BitcodeReader.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Bitcode/LLVMBitCodes.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Bitstream/BitstreamReader.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/Analysis.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/AntiDepBreaker.h97
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h138
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinterHandler.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h920
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/CallingConvLower.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.h151
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.inc428
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/DIE.h49
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/DbgEntityHistoryCalculator.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/EdgeBundles.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ExecutionDomainFix.h15
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/FastISel.h64
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h75
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h88
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InlineAsmLowering.h67
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h353
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h117
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h120
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LostDebugLocObserver.h50
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h74
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h236
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Types.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Utils.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ISDOpcodes.h2355
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/IndirectThunks.h110
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/IntrinsicLowering.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LexicalScopes.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveInterval.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervalCalc.h71
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervals.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeCalc.h57
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeEdit.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/LiveVariables.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MBFIWrapper.h46
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIParser.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h149
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineCombinerPattern.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineConstantPool.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineDominators.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFrameInfo.h63
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFunction.h100
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h125
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundle.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineMemOperand.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePipeliner.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePostDominators.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegisterInfo.h184
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSSAUpdater.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineScheduler.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSizeOpts.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ModuloSchedule.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ParallelCG.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/Passes.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/PseudoSourceValue.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h171
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/Register.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDAG.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDFS.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAG.h337
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGISel.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGNodes.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/SlotIndexes.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/Spiller.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/StackMaps.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/StackProtector.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TailDuplicator.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetCallingConv.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h73
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetInstrInfo.h98
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h453
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.h76
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.td305
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/VirtRegMap.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinker.h619
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFStreamer.h219
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DIContext.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h27
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h83
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h86
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h81
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h75
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h63
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/InlineInfo.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LineTable.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LookupResult.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/Range.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/GenericError.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBLineNumber.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h78
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h39
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h45
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativePublicSymbol.h44
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Demangle/Demangle.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h47
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h52
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h38
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ObjectCache.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h92
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h405
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h136
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h170
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h96
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h161
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h15
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h355
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h44
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h43
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h32
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h27
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/Directive/DirectiveBase.td109
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenACC/ACC.td604
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMP.td1489
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h69
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPContext.h187
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPGridValues.h131
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h258
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def870
-rw-r--r--contrib/llvm-project/llvm/include/llvm/FuzzMutate/FuzzerCLI.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/FuzzMutate/Random.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/AbstractCallSite.h247
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Argument.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Attributes.h46
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Attributes.td34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/AutoUpgrade.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/BasicBlock.h107
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/CFG.h43
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/CFGDiff.h284
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/CallSite.h926
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Constant.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ConstantFolder.h107
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ConstantRange.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Constants.h103
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ConstrainedOps.def105
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DIBuilder.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DataLayout.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DebugInfo.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h345
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DebugLoc.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DerivedTypes.h275
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h46
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Dominators.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/FPEnv.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Function.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/GetElementPtrTypeIterator.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/GlobalObject.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/GlobalValue.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/GlobalVariable.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h1044
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IRBuilderFolder.h141
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IRPrintingPasses.h17
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/InstrTypes.h170
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Instruction.h87
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Instructions.h655
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h1685
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.h50
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.td436
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAArch64.td923
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAMDGPU.td696
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsARM.td361
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsBPF.td5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagon.td6198
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagonDep.td6144
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsMips.td268
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsNVVM.td26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsPowerPC.td223
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsSystemZ.td126
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td63
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td801
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsXCore.td72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/LLVMContext.h50
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/LLVMRemarkStreamer.h95
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/LegacyPassManagers.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/LegacyPassNameParser.h41
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Mangler.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/MatrixBuilder.h221
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Metadata.h32
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Module.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndex.h150
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/NoFolder.h155
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Operator.h47
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/PassInstrumentation.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/PassManager.h170
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h157
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/PassTimingInfo.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/PatternMatch.h325
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ProfileSummary.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/RemarkStreamer.h108
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Statepoint.h309
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Type.h83
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Use.h69
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/User.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/VPIntrinsics.def84
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/Value.h62
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h44
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IR/ValueMap.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/IRReader/IRReader.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/InitializePasses.h15
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LTO/Config.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LTO/LTO.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LTO/LTOBackend.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOModule.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/LinkAllPasses.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/ConstantPools.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/LaneBitmask.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCAsmInfo.h47
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCAsmLayout.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCAssembler.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCContext.h88
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCDirectives.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h87
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCELFObjectWriter.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCELFStreamer.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCExpr.h237
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCFixup.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCFragment.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCInstrDesc.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCInstrInfo.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCInstrItineraries.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCMachObjectWriter.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCObjectFileInfo.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h102
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCObjectWriter.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCParser/AsmLexer.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParser.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCRegister.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSchedule.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSection.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSectionCOFF.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSectionELF.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSectionMachO.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSectionWasm.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSectionXCOFF.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCStreamer.h247
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSymbolWasm.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCSymbolXCOFF.h52
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptions.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h57
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc65
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCValue.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCWasmObjectWriter.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCWasmStreamer.h36
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFStreamer.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFObjectWriter.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFStreamer.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/StringTableBuilder.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MC/SubtargetFeature.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/CodeEmitter.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/LSUnit.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/Pipeline.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/MCA/Stages/DispatchStage.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ArchiveWriter.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/Binary.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/COFF.h136
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/COFFImportFile.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ELF.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ELFObjectFile.h121
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ELFTypes.h15
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/Error.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/IRObjectFile.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/IRSymtab.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/MachO.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/MachOUniversal.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ModuleSymbolTable.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/ObjectFile.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/SymbolicFile.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/TapiFile.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/TapiUniversal.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/Wasm.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h21
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h91
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h138
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Option/OptParser.td43
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Option/Option.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Pass.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/PassAnalysisSupport.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/PassSupport.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h96
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h233
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h48
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/GCOV.h322
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProf.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/ProfileCommon.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProf.h153
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfReader.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfWriter.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Remarks/RemarkLinker.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStreamer.h73
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStringTable.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.def26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/AMDGPUMetadata.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ARMAttributeParser.h173
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ARMBuildAttributes.h109
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.def24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.h50
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Alignment.h166
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Allocator.h150
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/AllocatorBase.h103
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/AtomicOrdering.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Base64.h56
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamArray.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamReader.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamWriter.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/BranchProbability.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/CFGDiff.h250
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/CFGUpdate.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/CachePruning.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Casting.h64
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/CheckedArithmetic.h18
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Chrono.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/CommandLine.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Compiler.h64
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/DataExtractor.h146
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/DebugCounter.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ELFAttributeParser.h72
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ELFAttributes.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Endian.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Errno.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Error.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ErrorOr.h48
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ExtensibleRTTI.h135
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FileCheck.h19
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FileCollector.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FileOutputBuffer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FormatAdapters.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FormatProviders.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FormatVariadic.h63
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FormatVariadicDetails.h34
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/FormattedStream.h40
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/GenericDomTree.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h77
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/GlobPattern.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/GraphWriter.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Host.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/JSON.h29
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/KnownBits.h93
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/LEB128.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MD5.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MSVCErrorWorkarounds.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MachineValueType.h489
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MathExtras.h77
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MemAlloc.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/MemoryBuffer.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/NativeFormatting.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/OptimizedStructLayout.h142
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Parallel.h92
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Path.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/PointerLikeTypeTraits.h21
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/PrettyStackTrace.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Process.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Program.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributeParser.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributes.h44
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Regex.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SHA1.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ScaledNumber.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SourceMgr.h98
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SpecialCaseList.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/StringPool.h139
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SuffixTree.h350
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SwapByteOrder.h81
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/SystemUtils.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TargetOpcodes.def41
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h53
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TaskQueue.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ThreadPool.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Threading.h98
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TimeProfiler.h26
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/ToolOutputFile.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TrailingObjects.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TrigramIndex.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/TypeSize.h70
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/VersionTuple.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/VirtualFileSystem.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/Windows/WindowsSupport.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/WithColor.h48
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.def281
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.h148
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/YAMLParser.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h127
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h93
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Support/type_traits.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TableGen/Main.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TableGen/Record.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TableGen/StringToOffsetTable.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/GenericOpcodes.td110
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Combine.td139
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Target.td9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/Target.td73
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetCallingConv.td5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetIntrinsicInfo.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetItinerary.td2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetLoweringObjectFile.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetMachine.h35
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetOptions.h94
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetSchedule.td4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Target/TargetSelectionDAG.td67
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Testing/Support/Annotations.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Testing/Support/Error.h42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/ELF/TBEHandler.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.def27
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/ArchitectureSet.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/InterfaceFile.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/PackedVersion.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIReader.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIWriter.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h28
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroEarly.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroElide.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroSplit.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Attributor.h1586
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/FunctionImport.h10
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Inliner.h49
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h66
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h12
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombine.h16
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombineWorklist.h90
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h49
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/CGProfile.h5
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h14
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Float2Int.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h58
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVNExpression.h9
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/JumpThreading.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h57
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h11
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Reassociate.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils.h37
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AMDGPUEmitPrintf.h25
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h60
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h100
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h103
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h109
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h39
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h33
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Cloning.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeExtractor.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h41
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Debugify.h22
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Evaluator.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionComparator.h2
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h23
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Local.h102
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopSimplify.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopUtils.h156
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopVersioning.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h8
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PredicateInfo.h85
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h1
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h (renamed from contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h)42
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h7
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h169
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h51
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h3
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UniqueInternalLinkageNames.h31
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnrollLoop.h46
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Utils/VNCoercion.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize.h6
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h20
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h32
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h13
-rw-r--r--contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/VectorCombine.h30
-rw-r--r--contrib/llvm-project/llvm/include/llvm/XRay/Graph.h24
-rw-r--r--contrib/llvm-project/llvm/include/llvm/XRay/InstrumentationMap.h4
-rw-r--r--contrib/llvm-project/llvm/include/llvm/module.modulemap22
786 files changed, 44139 insertions, 23425 deletions
diff --git a/contrib/llvm-project/llvm/include/llvm-c/Core.h b/contrib/llvm-project/llvm/include/llvm-c/Core.h
index 7a39731d3e0c..2c7b4c6eff10 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/Core.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/Core.h
@@ -144,23 +144,25 @@ typedef enum {
} LLVMOpcode;
typedef enum {
- LLVMVoidTypeKind, /**< type with no size */
- LLVMHalfTypeKind, /**< 16 bit floating point type */
- LLVMFloatTypeKind, /**< 32 bit floating point type */
- LLVMDoubleTypeKind, /**< 64 bit floating point type */
- LLVMX86_FP80TypeKind, /**< 80 bit floating point type (X87) */
- LLVMFP128TypeKind, /**< 128 bit floating point type (112-bit mantissa)*/
- LLVMPPC_FP128TypeKind, /**< 128 bit floating point type (two 64-bits) */
- LLVMLabelTypeKind, /**< Labels */
- LLVMIntegerTypeKind, /**< Arbitrary bit width integers */
- LLVMFunctionTypeKind, /**< Functions */
- LLVMStructTypeKind, /**< Structures */
- LLVMArrayTypeKind, /**< Arrays */
- LLVMPointerTypeKind, /**< Pointers */
- LLVMVectorTypeKind, /**< SIMD 'packed' format, or other vector type */
- LLVMMetadataTypeKind, /**< Metadata */
- LLVMX86_MMXTypeKind, /**< X86 MMX */
- LLVMTokenTypeKind /**< Tokens */
+ LLVMVoidTypeKind, /**< type with no size */
+ LLVMHalfTypeKind, /**< 16 bit floating point type */
+ LLVMFloatTypeKind, /**< 32 bit floating point type */
+ LLVMDoubleTypeKind, /**< 64 bit floating point type */
+ LLVMX86_FP80TypeKind, /**< 80 bit floating point type (X87) */
+ LLVMFP128TypeKind, /**< 128 bit floating point type (112-bit mantissa)*/
+ LLVMPPC_FP128TypeKind, /**< 128 bit floating point type (two 64-bits) */
+ LLVMLabelTypeKind, /**< Labels */
+ LLVMIntegerTypeKind, /**< Arbitrary bit width integers */
+ LLVMFunctionTypeKind, /**< Functions */
+ LLVMStructTypeKind, /**< Structures */
+ LLVMArrayTypeKind, /**< Arrays */
+ LLVMPointerTypeKind, /**< Pointers */
+ LLVMVectorTypeKind, /**< Fixed width SIMD vector type */
+ LLVMMetadataTypeKind, /**< Metadata */
+ LLVMX86_MMXTypeKind, /**< X86 MMX */
+ LLVMTokenTypeKind, /**< Tokens */
+ LLVMScalableVectorTypeKind, /**< Scalable SIMD vector type */
+ LLVMBFloatTypeKind /**< 16 bit brain floating point type */
} LLVMTypeKind;
typedef enum {
@@ -1163,6 +1165,11 @@ unsigned LLVMGetIntTypeWidth(LLVMTypeRef IntegerTy);
LLVMTypeRef LLVMHalfTypeInContext(LLVMContextRef C);
/**
+ * Obtain a 16-bit brain floating point type from a context.
+ */
+LLVMTypeRef LLVMBFloatTypeInContext(LLVMContextRef C);
+
+/**
* Obtain a 32-bit floating point type from a context.
*/
LLVMTypeRef LLVMFloatTypeInContext(LLVMContextRef C);
@@ -1194,6 +1201,7 @@ LLVMTypeRef LLVMPPCFP128TypeInContext(LLVMContextRef C);
* These map to the functions in this group of the same name.
*/
LLVMTypeRef LLVMHalfType(void);
+LLVMTypeRef LLVMBFloatType(void);
LLVMTypeRef LLVMFloatType(void);
LLVMTypeRef LLVMDoubleType(void);
LLVMTypeRef LLVMX86FP80Type(void);
@@ -2690,7 +2698,7 @@ LLVMValueRef LLVMGetNextGlobalIFunc(LLVMValueRef IFunc);
* no previous global aliases.
*/
LLVMValueRef LLVMGetPreviousGlobalIFunc(LLVMValueRef IFunc);
-
+
/**
* Retrieves the resolver function associated with this indirect function, or
* NULL if it doesn't not exist.
@@ -2944,7 +2952,7 @@ void LLVMInsertExistingBasicBlockAfterInsertBlock(LLVMBuilderRef Builder,
*/
void LLVMAppendExistingBasicBlock(LLVMValueRef Fn,
LLVMBasicBlockRef BB);
-
+
/**
* Create a new basic block without inserting it into a function.
*
@@ -3251,8 +3259,8 @@ LLVMTypeRef LLVMGetCalledFunctionType(LLVMValueRef C);
* This expects an LLVMValueRef that corresponds to a llvm::CallInst or
* llvm::InvokeInst.
*
- * @see llvm::CallInst::getCalledValue()
- * @see llvm::InvokeInst::getCalledValue()
+ * @see llvm::CallInst::getCalledOperand()
+ * @see llvm::InvokeInst::getCalledOperand()
*/
LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr);
@@ -3755,7 +3763,7 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
LLVMValueRef Val, const char *Name);
/**
- * Creates and inserts a memset to the specified pointer and the
+ * Creates and inserts a memset to the specified pointer and the
* specified value.
*
* @see llvm::IRRBuilder::CreateMemSet()
@@ -3768,7 +3776,7 @@ LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr,
*
* @see llvm::IRRBuilder::CreateMemCpy()
*/
-LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B,
+LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size);
@@ -3777,7 +3785,7 @@ LLVMValueRef LLVMBuildMemCpy(LLVMBuilderRef B,
*
* @see llvm::IRRBuilder::CreateMemMove()
*/
-LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B,
+LLVMValueRef LLVMBuildMemMove(LLVMBuilderRef B,
LLVMValueRef Dst, unsigned DstAlign,
LLVMValueRef Src, unsigned SrcAlign,
LLVMValueRef Size);
diff --git a/contrib/llvm-project/llvm/include/llvm-c/DataTypes.h b/contrib/llvm-project/llvm/include/llvm-c/DataTypes.h
index 893b22b49ffc..0f27ba81865e 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/DataTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/DataTypes.h
@@ -24,12 +24,6 @@
#ifndef LLVM_C_DATATYPES_H
#define LLVM_C_DATATYPES_H
-#ifdef __cplusplus
-#include <cmath>
-#else
-#include <math.h>
-#endif
-
#include <inttypes.h>
#include <stdint.h>
diff --git a/contrib/llvm-project/llvm/include/llvm-c/DebugInfo.h b/contrib/llvm-project/llvm/include/llvm-c/DebugInfo.h
index e933fe4b3f92..cdf5f5a0cca8 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/DebugInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/DebugInfo.h
@@ -250,6 +250,10 @@ void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder);
* \param SplitDebugInlining Whether to emit inline debug info.
* \param DebugInfoForProfiling Whether to emit extra debug info for
* profile collection.
+ * \param SysRoot The Clang system root (value of -isysroot).
+ * \param SysRootLen The length of the C string passed to \c SysRoot.
+ * \param SDK The SDK. On Darwin, the last component of the sysroot.
+ * \param SDKLen The length of the C string passed to \c SDK.
*/
LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,
@@ -257,7 +261,8 @@ LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
LLVMBool isOptimized, const char *Flags, size_t FlagsLen,
unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
- LLVMBool DebugInfoForProfiling);
+ LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen,
+ const char *SDK, size_t SDKLen);
/**
* Create a file descriptor to hold debugging information for a file.
@@ -283,15 +288,15 @@ LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
* \param ConfigMacrosLen The length of the C string passed to \c ConfigMacros.
* \param IncludePath The path to the module map file.
* \param IncludePathLen The length of the C string passed to \c IncludePath.
- * \param SysRoot The Clang system root (value of -isysroot).
- * \param SysRootLen The length of the C string passed to \c SysRoot.
+ * \param APINotesFile The path to an API notes file for the module.
+ * \param APINotesFileLen The length of the C string passed to \c APINotestFile.
*/
LLVMMetadataRef
LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope,
const char *Name, size_t NameLen,
const char *ConfigMacros, size_t ConfigMacrosLen,
const char *IncludePath, size_t IncludePathLen,
- const char *SysRoot, size_t SysRootLen);
+ const char *APINotesFile, size_t APINotesFileLen);
/**
* Creates a new descriptor for a namespace with the specified parent scope.
diff --git a/contrib/llvm-project/llvm/include/llvm-c/ExecutionEngine.h b/contrib/llvm-project/llvm/include/llvm-c/ExecutionEngine.h
index f31b97ad7623..c5fc9bdb4d07 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/ExecutionEngine.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/ExecutionEngine.h
@@ -149,6 +149,11 @@ uint64_t LLVMGetGlobalValueAddress(LLVMExecutionEngineRef EE, const char *Name);
uint64_t LLVMGetFunctionAddress(LLVMExecutionEngineRef EE, const char *Name);
+/// Returns true on error, false on success. If true is returned then the error
+/// message is copied to OutStr and cleared in the ExecutionEngine instance.
+LLVMBool LLVMExecutionEngineGetErrMsg(LLVMExecutionEngineRef EE,
+ char **OutError);
+
/*===-- Operations on memory managers -------------------------------------===*/
typedef uint8_t *(*LLVMMemoryManagerAllocateCodeSectionCallback)(
diff --git a/contrib/llvm-project/llvm/include/llvm-c/Orc.h b/contrib/llvm-project/llvm/include/llvm-c/Orc.h
new file mode 100644
index 000000000000..09a058846108
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm-c/Orc.h
@@ -0,0 +1,335 @@
+/*===---------------- llvm-c/Orc.h - OrcV2 C bindings -----------*- C++ -*-===*\
+|* *|
+|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
+|* Exceptions. *|
+|* See https://llvm.org/LICENSE.txt for license information. *|
+|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
+|* *|
+|*===----------------------------------------------------------------------===*|
+|* *|
+|* This header declares the C interface to libLLVMOrcJIT.a, which implements *|
+|* JIT compilation of LLVM IR. Minimal documentation of C API specific issues *|
+|* (especially memory ownership rules) is provided. Core Orc concepts are *|
+|* documented in llvm/docs/ORCv2.rst and APIs are documented in the C++ *|
+|* headers *|
+|* *|
+|* Many exotic languages can interoperate with C code but have a harder time *|
+|* with C++ due to name mangling. So in addition to C, this interface enables *|
+|* tools written in such languages. *|
+|* *|
+|* Note: This interface is experimental. It is *NOT* stable, and may be *|
+|* changed without warning. Only C API usage documentation is *|
+|* provided. See the C++ documentation for all higher level ORC API *|
+|* details. *|
+|* *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_ORC_H
+#define LLVM_C_ORC_H
+
+#include "llvm-c/Error.h"
+#include "llvm-c/TargetMachine.h"
+#include "llvm-c/Types.h"
+
+LLVM_C_EXTERN_C_BEGIN
+
+/**
+ * Represents an address in the target process.
+ */
+typedef uint64_t LLVMOrcJITTargetAddress;
+
+/**
+ * A reference to an orc::ExecutionSession instance.
+ */
+typedef struct LLVMOrcOpaqueExecutionSession *LLVMOrcExecutionSessionRef;
+
+/**
+ * A reference to an orc::SymbolStringPool table entry.
+ */
+typedef struct LLVMOrcQuaqueSymbolStringPoolEntryPtr
+ *LLVMOrcSymbolStringPoolEntryRef;
+
+/**
+ * A reference to an orc::JITDylib instance.
+ */
+typedef struct LLVMOrcOpaqueJITDylib *LLVMOrcJITDylibRef;
+
+/**
+ * A reference to an orc::JITDylib::DefinitionGenerator.
+ */
+typedef struct LLVMOrcOpaqueJITDylibDefinitionGenerator
+ *LLVMOrcJITDylibDefinitionGeneratorRef;
+
+/**
+ * Predicate function for SymbolStringPoolEntries.
+ */
+typedef int (*LLVMOrcSymbolPredicate)(LLVMOrcSymbolStringPoolEntryRef Sym,
+ void *Ctx);
+
+/**
+ * A reference to an orc::ThreadSafeContext instance.
+ */
+typedef struct LLVMOrcOpaqueThreadSafeContext *LLVMOrcThreadSafeContextRef;
+
+/**
+ * A reference to an orc::ThreadSafeModule instance.
+ */
+typedef struct LLVMOrcOpaqueThreadSafeModule *LLVMOrcThreadSafeModuleRef;
+
+/**
+ * A reference to an orc::JITTargetMachineBuilder instance.
+ */
+typedef struct LLVMOrcOpaqueJITTargetMachineBuilder
+ *LLVMOrcJITTargetMachineBuilderRef;
+
+/**
+ * A reference to an orc::LLJITBuilder instance.
+ */
+typedef struct LLVMOrcOpaqueLLJITBuilder *LLVMOrcLLJITBuilderRef;
+
+/**
+ * A reference to an orc::LLJIT instance.
+ */
+typedef struct LLVMOrcOpaqueLLJIT *LLVMOrcLLJITRef;
+
+/**
+ * Intern a string in the ExecutionSession's SymbolStringPool and return a
+ * reference to it. This increments the ref-count of the pool entry, and the
+ * returned value should be released once the client is done with it by
+ * calling LLVMOrReleaseSymbolStringPoolEntry.
+ *
+ * Since strings are uniqued within the SymbolStringPool
+ * LLVMOrcSymbolStringPoolEntryRefs can be compared by value to test string
+ * equality.
+ *
+ * Note that this function does not perform linker-mangling on the string.
+ */
+LLVMOrcSymbolStringPoolEntryRef
+LLVMOrcExecutionSessionIntern(LLVMOrcExecutionSessionRef ES, const char *Name);
+
+/**
+ * Reduces the ref-count for of a SymbolStringPool entry.
+ */
+void LLVMOrcReleaseSymbolStringPoolEntry(LLVMOrcSymbolStringPoolEntryRef S);
+
+/**
+ * Dispose of a JITDylib::DefinitionGenerator. This should only be called if
+ * ownership has not been passed to a JITDylib (e.g. because some error
+ * prevented the client from calling LLVMOrcJITDylibAddGenerator).
+ */
+void LLVMOrcDisposeJITDylibDefinitionGenerator(
+ LLVMOrcJITDylibDefinitionGeneratorRef DG);
+
+/**
+ * Add a JITDylib::DefinitionGenerator to the given JITDylib.
+ *
+ * The JITDylib will take ownership of the given generator: The client is no
+ * longer responsible for managing its memory.
+ */
+void LLVMOrcJITDylibAddGenerator(LLVMOrcJITDylibRef JD,
+ LLVMOrcJITDylibDefinitionGeneratorRef DG);
+
+/**
+ * Get a DynamicLibrarySearchGenerator that will reflect process symbols into
+ * the JITDylib. On success the resulting generator is owned by the client.
+ * Ownership is typically transferred by adding the instance to a JITDylib
+ * using LLVMOrcJITDylibAddGenerator,
+ *
+ * The GlobalPrefix argument specifies the character that appears on the front
+ * of linker-mangled symbols for the target platform (e.g. '_' on MachO).
+ * If non-null, this character will be stripped from the start of all symbol
+ * strings before passing the remaining substring to dlsym.
+ *
+ * The optional Filter and Ctx arguments can be used to supply a symbol name
+ * filter: Only symbols for which the filter returns true will be visible to
+ * JIT'd code. If the Filter argument is null then all process symbols will
+ * be visible to JIT'd code. Note that the symbol name passed to the Filter
+ * function is the full mangled symbol: The client is responsible for stripping
+ * the global prefix if present.
+ */
+LLVMErrorRef LLVMOrcCreateDynamicLibrarySearchGeneratorForProcess(
+ LLVMOrcJITDylibDefinitionGeneratorRef *Result, char GlobalPrefx,
+ LLVMOrcSymbolPredicate Filter, void *FilterCtx);
+
+/**
+ * Create a ThreadSafeContext containing a new LLVMContext.
+ *
+ * Ownership of the underlying ThreadSafeContext data is shared: Clients
+ * can and should dispose of their ThreadSafeContext as soon as they no longer
+ * need to refer to it directly. Other references (e.g. from ThreadSafeModules
+ * will keep the data alive as long as it is needed.
+ */
+LLVMOrcThreadSafeContextRef LLVMOrcCreateNewThreadSafeContext(void);
+
+/**
+ * Get a reference to the wrapped LLVMContext.
+ */
+LLVMContextRef
+LLVMOrcThreadSafeContextGetContext(LLVMOrcThreadSafeContextRef TSCtx);
+
+/**
+ * Dispose of a ThreadSafeContext.
+ */
+void LLVMOrcDisposeThreadSafeContext(LLVMOrcThreadSafeContextRef TSCtx);
+
+/**
+ * Create a ThreadSafeModule wrapper around the given LLVM module. This takes
+ * ownership of the M argument which should not be disposed of or referenced
+ * after this function returns.
+ *
+ * Ownership of the ThreadSafeModule is unique: If it is transferred to the JIT
+ * (e.g. by LLVMOrcLLJITAddLLVMIRModule), in which case the client is no longer
+ * responsible for it. If it is not transferred to the JIT then the client
+ * should call LLVMOrcDisposeThreadSafeModule to dispose of it.
+ */
+LLVMOrcThreadSafeModuleRef
+LLVMOrcCreateNewThreadSafeModule(LLVMModuleRef M,
+ LLVMOrcThreadSafeContextRef TSCtx);
+
+/**
+ * Dispose of a ThreadSafeModule. This should only be called if ownership has
+ * not been passed to LLJIT (e.g. because some error prevented the client from
+ * adding this to the JIT).
+ */
+void LLVMOrcDisposeThreadSafeModule(LLVMOrcThreadSafeModuleRef TSM);
+
+/**
+ * Create a JITTargetMachineBuilder by detecting the host.
+ *
+ * On success the client owns the resulting JITTargetMachineBuilder. It must be
+ * passed to a consuming operation (e.g. LLVMOrcCreateLLJITBuilder) or disposed
+ * of by calling LLVMOrcDisposeJITTargetMachineBuilder.
+ */
+LLVMErrorRef LLVMOrcJITTargetMachineBuilderDetectHost(
+ LLVMOrcJITTargetMachineBuilderRef *Result);
+
+/**
+ * Create a JITTargetMachineBuilder from the given TargetMachine template.
+ *
+ * This operation takes ownership of the given TargetMachine and destroys it
+ * before returing. The resulting JITTargetMachineBuilder is owned by the client
+ * and must be passed to a consuming operation (e.g. LLVMOrcCreateLLJITBuilder)
+ * or disposed of by calling LLVMOrcDisposeJITTargetMachineBuilder.
+ */
+LLVMOrcJITTargetMachineBuilderRef
+LLVMOrcJITTargetMachineBuilderCreateFromTargetMachine(LLVMTargetMachineRef TM);
+
+/**
+ * Dispose of a JITTargetMachineBuilder.
+ */
+void LLVMOrcDisposeJITTargetMachineBuilder(
+ LLVMOrcJITTargetMachineBuilderRef JTMB);
+
+/**
+ * Create an LLJITTargetMachineBuilder.
+ *
+ * The client owns the resulting LLJITBuilder and should dispose of it using
+ * LLVMOrcDisposeLLJITBuilder once they are done with it.
+ */
+LLVMOrcLLJITBuilderRef LLVMOrcCreateLLJITBuilder(void);
+
+/**
+ * Dispose of an LLVMOrcLLJITBuilderRef. This should only be called if ownership
+ * has not been passed to LLVMOrcCreateLLJIT (e.g. because some error prevented
+ * that function from being called).
+ */
+void LLVMOrcDisposeLLJITBuilder(LLVMOrcLLJITBuilderRef Builder);
+
+/**
+ * Set the JITTargetMachineBuilder to be used when constructing the LLJIT
+ * instance. Calling this function is optional: if it is not called then the
+ * LLJITBuilder will use JITTargeTMachineBuilder::detectHost to construct a
+ * JITTargetMachineBuilder.
+ */
+void LLVMOrcLLJITBuilderSetJITTargetMachineBuilder(
+ LLVMOrcLLJITBuilderRef Builder, LLVMOrcJITTargetMachineBuilderRef JTMB);
+
+/**
+ * Create an LLJIT instance from an LLJITBuilder.
+ *
+ * This operation takes ownership of the Builder argument: clients should not
+ * dispose of the builder after calling this function (even if the function
+ * returns an error). If a null Builder argument is provided then a
+ * default-constructed LLJITBuilder will be used.
+ *
+ * On success the resulting LLJIT instance is uniquely owned by the client and
+ * automatically manages the memory of all JIT'd code and all modules that are
+ * transferred to it (e.g. via LLVMOrcLLJITAddLLVMIRModule). Disposing of the
+ * LLJIT instance will free all memory managed by the JIT, including JIT'd code
+ * and not-yet compiled modules.
+ */
+LLVMErrorRef LLVMOrcCreateLLJIT(LLVMOrcLLJITRef *Result,
+ LLVMOrcLLJITBuilderRef Builder);
+
+/**
+ * Dispose of an LLJIT instance.
+ */
+LLVMErrorRef LLVMOrcDisposeLLJIT(LLVMOrcLLJITRef J);
+
+/**
+ * Get a reference to the ExecutionSession for this LLJIT instance.
+ *
+ * The ExecutionSession is owned by the LLJIT instance. The client is not
+ * responsible for managing its memory.
+ */
+LLVMOrcExecutionSessionRef LLVMOrcLLJITGetExecutionSession(LLVMOrcLLJITRef J);
+
+/**
+ * Return a reference to the Main JITDylib.
+ *
+ * The JITDylib is owned by the LLJIT instance. The client is not responsible
+ * for managing its memory.
+ */
+LLVMOrcJITDylibRef LLVMOrcLLJITGetMainJITDylib(LLVMOrcLLJITRef J);
+
+/**
+ * Return the target triple for this LLJIT instance. This string is owned by
+ * the LLJIT instance and should not be freed by the client.
+ */
+const char *LLVMOrcLLJITGetTripleString(LLVMOrcLLJITRef J);
+
+/**
+ * Returns the global prefix character according to the LLJIT's DataLayout.
+ */
+char LLVMOrcLLJITGetGlobalPrefix(LLVMOrcLLJITRef J);
+
+/**
+ * Mangles the given string according to the LLJIT instance's DataLayout, then
+ * interns the result in the SymbolStringPool and returns a reference to the
+ * pool entry. Clients should call LLVMOrcReleaseSymbolStringPoolEntry to
+ * decrement the ref-count on the pool entry once they are finished with this
+ * value.
+ */
+LLVMOrcSymbolStringPoolEntryRef
+LLVMOrcLLJITMangleAndIntern(LLVMOrcLLJITRef J, const char *UnmangledName);
+
+/**
+ * Add a buffer representing an object file to the given JITDylib in the given
+ * LLJIT instance. This operation transfers ownership of the buffer to the
+ * LLJIT instance. The buffer should not be disposed of or referenced once this
+ * function returns.
+ */
+LLVMErrorRef LLVMOrcLLJITAddObjectFile(LLVMOrcLLJITRef J, LLVMOrcJITDylibRef JD,
+ LLVMMemoryBufferRef ObjBuffer);
+
+/**
+ * Add an IR module to the given JITDylib of the given LLJIT instance. This
+ * operation transfers ownership of the TSM argument to the LLJIT instance.
+ * The TSM argument should not be 3disposed of or referenced once this
+ * function returns.
+ */
+LLVMErrorRef LLVMOrcLLJITAddLLVMIRModule(LLVMOrcLLJITRef J,
+ LLVMOrcJITDylibRef JD,
+ LLVMOrcThreadSafeModuleRef TSM);
+/**
+ * Look up the given symbol in the main JITDylib of the given LLJIT instance.
+ *
+ * This operation does not take ownership of the Name argument.
+ */
+LLVMErrorRef LLVMOrcLLJITLookup(LLVMOrcLLJITRef J,
+ LLVMOrcJITTargetAddress *Result,
+ const char *Name);
+
+LLVM_C_EXTERN_C_END
+
+#endif /* LLVM_C_ORC_H */
diff --git a/contrib/llvm-project/llvm/include/llvm-c/Transforms/Coroutines.h b/contrib/llvm-project/llvm/include/llvm-c/Transforms/Coroutines.h
index 15798af7d661..03b6822033c9 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/Transforms/Coroutines.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/Transforms/Coroutines.h
@@ -21,6 +21,7 @@
#include "llvm-c/ExternC.h"
#include "llvm-c/Types.h"
+#include "llvm-c/Transforms/PassManagerBuilder.h"
LLVM_C_EXTERN_C_BEGIN
@@ -43,6 +44,9 @@ void LLVMAddCoroElidePass(LLVMPassManagerRef PM);
/** See llvm::createCoroCleanupLegacyPass function. */
void LLVMAddCoroCleanupPass(LLVMPassManagerRef PM);
+/** See llvm::addCoroutinePassesToExtensionPoints. */
+void LLVMPassManagerBuilderAddCoroutinePassesToExtensionPoints(LLVMPassManagerBuilderRef PMB);
+
/**
* @}
*/
diff --git a/contrib/llvm-project/llvm/include/llvm-c/lto.h b/contrib/llvm-project/llvm/include/llvm-c/lto.h
index 97a8f4823320..4dbc77f294c6 100644
--- a/contrib/llvm-project/llvm/include/llvm-c/lto.h
+++ b/contrib/llvm-project/llvm/include/llvm-c/lto.h
@@ -46,7 +46,7 @@ typedef bool lto_bool_t;
* @{
*/
-#define LTO_API_VERSION 26
+#define LTO_API_VERSION 27
/**
* \since prior to LTO_API_VERSION=3
@@ -298,6 +298,21 @@ extern const char*
lto_module_get_linkeropts(lto_module_t mod);
/**
+ * If targeting mach-o on darwin, this function gets the CPU type and subtype
+ * that will end up being encoded in the mach-o header. These are the values
+ * that can be found in mach/machine.h.
+ *
+ * \p out_cputype and \p out_cpusubtype must be non-NULL.
+ *
+ * Returns true on error (check lto_get_error_message() for details).
+ *
+ * \since LTO_API_VERSION=27
+ */
+extern lto_bool_t lto_module_get_macho_cputype(lto_module_t mod,
+ unsigned int *out_cputype,
+ unsigned int *out_cpusubtype);
+
+/**
* Diagnostic severity.
*
* \since LTO_API_VERSION=7
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/APFloat.h b/contrib/llvm-project/llvm/include/llvm/ADT/APFloat.h
index ed25b2cd89f1..876e52c150a0 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/APFloat.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/APFloat.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/Support/ErrorHandling.h"
#include <memory>
@@ -141,7 +142,7 @@ enum lostFraction { // Example of truncated bits:
// members.
struct APFloatBase {
typedef APInt::WordType integerPart;
- static const unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
+ static constexpr unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD;
/// A signed type to represent a floating point numbers unbiased exponent.
typedef int32_t ExponentType;
@@ -150,6 +151,7 @@ struct APFloatBase {
/// @{
enum Semantics {
S_IEEEhalf,
+ S_BFloat,
S_IEEEsingle,
S_IEEEdouble,
S_x87DoubleExtended,
@@ -161,6 +163,7 @@ struct APFloatBase {
static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
static const fltSemantics &IEEEhalf() LLVM_READNONE;
+ static const fltSemantics &BFloat() LLVM_READNONE;
static const fltSemantics &IEEEsingle() LLVM_READNONE;
static const fltSemantics &IEEEdouble() LLVM_READNONE;
static const fltSemantics &IEEEquad() LLVM_READNONE;
@@ -182,13 +185,15 @@ struct APFloatBase {
};
/// IEEE-754R 4.3: Rounding-direction attributes.
- enum roundingMode {
- rmNearestTiesToEven,
- rmTowardPositive,
- rmTowardNegative,
- rmTowardZero,
- rmNearestTiesToAway
- };
+ using roundingMode = llvm::RoundingMode;
+
+ static constexpr roundingMode rmNearestTiesToEven =
+ RoundingMode::NearestTiesToEven;
+ static constexpr roundingMode rmTowardPositive = RoundingMode::TowardPositive;
+ static constexpr roundingMode rmTowardNegative = RoundingMode::TowardNegative;
+ static constexpr roundingMode rmTowardZero = RoundingMode::TowardZero;
+ static constexpr roundingMode rmNearestTiesToAway =
+ RoundingMode::NearestTiesToAway;
/// IEEE-754R 7: Default exception handling.
///
@@ -511,6 +516,7 @@ private:
opStatus divideSpecials(const IEEEFloat &);
opStatus multiplySpecials(const IEEEFloat &);
opStatus modSpecials(const IEEEFloat &);
+ opStatus remainderSpecials(const IEEEFloat&);
/// @}
@@ -537,6 +543,7 @@ private:
/// @}
APInt convertHalfAPFloatToAPInt() const;
+ APInt convertBFloatAPFloatToAPInt() const;
APInt convertFloatAPFloatToAPInt() const;
APInt convertDoubleAPFloatToAPInt() const;
APInt convertQuadrupleAPFloatToAPInt() const;
@@ -544,6 +551,7 @@ private:
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
void initFromAPInt(const fltSemantics *Sem, const APInt &api);
void initFromHalfAPInt(const APInt &api);
+ void initFromBFloatAPInt(const APInt &api);
void initFromFloatAPInt(const APInt &api);
void initFromDoubleAPInt(const APInt &api);
void initFromQuadrupleAPInt(const APInt &api);
@@ -585,7 +593,7 @@ IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode);
IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM);
// This mode implements more precise float in terms of two APFloats.
-// The interface and layout is designed for arbitray underlying semantics,
+// The interface and layout is designed for arbitrary underlying semantics,
// though currently only PPCDoubleDouble semantics are supported, whose
// corresponding underlying semantics are IEEEdouble.
class DoubleAPFloat final : public APFloatBase {
@@ -853,8 +861,8 @@ public:
APFloat(const fltSemantics &Semantics) : U(Semantics) {}
APFloat(const fltSemantics &Semantics, StringRef S);
APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
- template <typename T, typename = typename std::enable_if<
- std::is_floating_point<T>::value>::type>
+ template <typename T,
+ typename = std::enable_if_t<std::is_floating_point<T>::value>>
APFloat(const fltSemantics &Semantics, T V) = delete;
// TODO: Remove this constructor. This isn't faster than the first one.
APFloat(const fltSemantics &Semantics, uninitializedTag)
@@ -950,9 +958,10 @@ public:
/// Returns a float which is bitcasted from an all one value int.
///
+ /// \param Semantics - type float semantics
/// \param BitWidth - Select float type
- /// \param isIEEE - If 128 bit number, select between PPC and IEEE
- static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
+ static APFloat getAllOnesValue(const fltSemantics &Semantics,
+ unsigned BitWidth);
/// Used to insert APFloat objects, or objects that contain APFloat objects,
/// into FoldingSets.
@@ -1035,6 +1044,13 @@ public:
APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown));
}
+ /// Negate an APFloat.
+ APFloat operator-() const {
+ APFloat Result(*this);
+ Result.changeSign();
+ return Result;
+ }
+
/// Add two APFloats, rounding ties to the nearest even.
/// No error checking.
APFloat operator+(const APFloat &RHS) const {
@@ -1117,7 +1133,27 @@ public:
double convertToDouble() const { return getIEEE().convertToDouble(); }
float convertToFloat() const { return getIEEE().convertToFloat(); }
- bool operator==(const APFloat &) const = delete;
+ bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; }
+
+ bool operator!=(const APFloat &RHS) const { return compare(RHS) != cmpEqual; }
+
+ bool operator<(const APFloat &RHS) const {
+ return compare(RHS) == cmpLessThan;
+ }
+
+ bool operator>(const APFloat &RHS) const {
+ return compare(RHS) == cmpGreaterThan;
+ }
+
+ bool operator<=(const APFloat &RHS) const {
+ cmpResult Res = compare(RHS);
+ return Res == cmpLessThan || Res == cmpEqual;
+ }
+
+ bool operator>=(const APFloat &RHS) const {
+ cmpResult Res = compare(RHS);
+ return Res == cmpGreaterThan || Res == cmpEqual;
+ }
cmpResult compare(const APFloat &RHS) const {
assert(&getSemantics() == &RHS.getSemantics() &&
@@ -1249,7 +1285,7 @@ inline APFloat minnum(const APFloat &A, const APFloat &B) {
return B;
if (B.isNaN())
return A;
- return (B.compare(A) == APFloat::cmpLessThan) ? B : A;
+ return B < A ? B : A;
}
/// Implements IEEE maxNum semantics. Returns the larger of the 2 arguments if
@@ -1260,7 +1296,7 @@ inline APFloat maxnum(const APFloat &A, const APFloat &B) {
return B;
if (B.isNaN())
return A;
- return (A.compare(B) == APFloat::cmpLessThan) ? B : A;
+ return A < B ? B : A;
}
/// Implements IEEE 754-2018 minimum semantics. Returns the smaller of 2
@@ -1273,7 +1309,7 @@ inline APFloat minimum(const APFloat &A, const APFloat &B) {
return B;
if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
return A.isNegative() ? A : B;
- return (B.compare(A) == APFloat::cmpLessThan) ? B : A;
+ return B < A ? B : A;
}
/// Implements IEEE 754-2018 maximum semantics. Returns the larger of 2
@@ -1286,7 +1322,7 @@ inline APFloat maximum(const APFloat &A, const APFloat &B) {
return B;
if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative()))
return A.isNegative() ? B : A;
- return (A.compare(B) == APFloat::cmpLessThan) ? B : A;
+ return A < B ? B : A;
}
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/APInt.h b/contrib/llvm-project/llvm/include/llvm/ADT/APInt.h
index 0791a6d686a3..f7df648d27ed 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/APInt.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/APInt.h
@@ -84,7 +84,7 @@ public:
UP,
};
- static const WordType WORDTYPE_MAX = ~WordType(0);
+ static constexpr WordType WORDTYPE_MAX = ~WordType(0);
private:
/// This union is used to store the integer value. When the
@@ -616,9 +616,11 @@ public:
}
/// Wrap version of getBitsSet.
- /// If \p hiBit is no less than \p loBit, this is same with getBitsSet.
- /// If \p hiBit is less than \p loBit, the set bits "wrap". For example, with
- /// parameters (32, 28, 4), you would get 0xF000000F.
+ /// If \p hiBit is bigger than \p loBit, this is same with getBitsSet.
+ /// If \p hiBit is not bigger than \p loBit, the set bits "wrap". For example,
+ /// with parameters (32, 28, 4), you would get 0xF000000F.
+ /// If \p hiBit is equal to \p loBit, you would get a result with all bits
+ /// set.
static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit,
unsigned hiBit) {
APInt Res(numBits, 0);
@@ -1448,12 +1450,13 @@ public:
}
/// Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
- /// This function handles "wrap" case when \p loBit > \p hiBit, and calls
- /// setBits when \p loBit <= \p hiBit.
+ /// This function handles "wrap" case when \p loBit >= \p hiBit, and calls
+ /// setBits when \p loBit < \p hiBit.
+ /// For \p loBit == \p hiBit wrap case, set every bit to 1.
void setBitsWithWrap(unsigned loBit, unsigned hiBit) {
assert(hiBit <= BitWidth && "hiBit out of range");
assert(loBit <= BitWidth && "loBit out of range");
- if (loBit <= hiBit) {
+ if (loBit < hiBit) {
setBits(loBit, hiBit);
return;
}
@@ -2283,7 +2286,7 @@ void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
/// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
/// from Src into IntVal, which is assumed to be wide enough and to hold zero.
-void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes);
+void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes);
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/AllocatorList.h b/contrib/llvm-project/llvm/include/llvm/ADT/AllocatorList.h
index 405a2e4264df..447d7a7538db 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/AllocatorList.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/AllocatorList.h
@@ -110,8 +110,8 @@ private:
template <class OtherValueT, class OtherIteratorBase>
IteratorImpl(const IteratorImpl<OtherValueT, OtherIteratorBase> &X,
- typename std::enable_if<std::is_convertible<
- OtherIteratorBase, IteratorBase>::value>::type * = nullptr)
+ std::enable_if_t<std::is_convertible<
+ OtherIteratorBase, IteratorBase>::value> * = nullptr)
: base_type(X.wrapped()) {}
~IteratorImpl() = default;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Any.h b/contrib/llvm-project/llvm/include/llvm/ADT/Any.h
index 49657e02a991..0aded628cda4 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/Any.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Any.h
@@ -59,26 +59,26 @@ public:
// When T is Any or T is not copy-constructible we need to explicitly disable
// the forwarding constructor so that the copy constructor gets selected
// instead.
- template <
- typename T,
- typename std::enable_if<
- llvm::conjunction<
- llvm::negation<std::is_same<typename std::decay<T>::type, Any>>,
- // We also disable this overload when an `Any` object can be
- // converted to the parameter type because in that case, this
- // constructor may combine with that conversion during overload
- // resolution for determining copy constructibility, and then
- // when we try to determine copy constructibility below we may
- // infinitely recurse. This is being evaluated by the standards
- // committee as a potential DR in `std::any` as well, but we're
- // going ahead and adopting it to work-around usage of `Any` with
- // types that need to be implicitly convertible from an `Any`.
- llvm::negation<std::is_convertible<Any, typename std::decay<T>::type>>,
- std::is_copy_constructible<typename std::decay<T>::type>>::value,
- int>::type = 0>
+ template <typename T,
+ std::enable_if_t<
+ llvm::conjunction<
+ llvm::negation<std::is_same<std::decay_t<T>, Any>>,
+ // We also disable this overload when an `Any` object can be
+ // converted to the parameter type because in that case,
+ // this constructor may combine with that conversion during
+ // overload resolution for determining copy
+ // constructibility, and then when we try to determine copy
+ // constructibility below we may infinitely recurse. This is
+ // being evaluated by the standards committee as a potential
+ // DR in `std::any` as well, but we're going ahead and
+ // adopting it to work-around usage of `Any` with types that
+ // need to be implicitly convertible from an `Any`.
+ llvm::negation<std::is_convertible<Any, std::decay_t<T>>>,
+ std::is_copy_constructible<std::decay_t<T>>>::value,
+ int> = 0>
Any(T &&Value) {
- using U = typename std::decay<T>::type;
- Storage = std::make_unique<StorageImpl<U>>(std::forward<T>(Value));
+ Storage =
+ std::make_unique<StorageImpl<std::decay_t<T>>>(std::forward<T>(Value));
}
Any(Any &&Other) : Storage(std::move(Other.Storage)) {}
@@ -114,32 +114,27 @@ template <typename T> const char Any::TypeId<T>::Id = 0;
template <typename T> bool any_isa(const Any &Value) {
if (!Value.Storage)
return false;
- using U =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
- return Value.Storage->id() == &Any::TypeId<U>::Id;
+ return Value.Storage->id() ==
+ &Any::TypeId<std::remove_cv_t<std::remove_reference_t<T>>>::Id;
}
template <class T> T any_cast(const Any &Value) {
- using U =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
- return static_cast<T>(*any_cast<U>(&Value));
+ return static_cast<T>(
+ *any_cast<std::remove_cv_t<std::remove_reference_t<T>>>(&Value));
}
template <class T> T any_cast(Any &Value) {
- using U =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
- return static_cast<T>(*any_cast<U>(&Value));
+ return static_cast<T>(
+ *any_cast<std::remove_cv_t<std::remove_reference_t<T>>>(&Value));
}
template <class T> T any_cast(Any &&Value) {
- using U =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
- return static_cast<T>(std::move(*any_cast<U>(&Value)));
+ return static_cast<T>(std::move(
+ *any_cast<std::remove_cv_t<std::remove_reference_t<T>>>(&Value)));
}
template <class T> const T *any_cast(const Any *Value) {
- using U =
- typename std::remove_cv<typename std::remove_reference<T>::type>::type;
+ using U = std::remove_cv_t<std::remove_reference_t<T>>;
assert(Value && any_isa<T>(*Value) && "Bad any cast!");
if (!Value || !any_isa<U>(*Value))
return nullptr;
@@ -147,7 +142,7 @@ template <class T> const T *any_cast(const Any *Value) {
}
template <class T> T *any_cast(Any *Value) {
- using U = typename std::decay<T>::type;
+ using U = std::decay_t<T>;
assert(Value && any_isa<U>(*Value) && "Bad any cast!");
if (!Value || !any_isa<U>(*Value))
return nullptr;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h b/contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h
index 3d22442918cd..5ed4d0766c34 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ArrayRef.h
@@ -38,7 +38,7 @@ namespace llvm {
/// This is intended to be trivially copyable, so it should be passed by
/// value.
template<typename T>
- class LLVM_NODISCARD ArrayRef {
+ class LLVM_GSL_POINTER LLVM_NODISCARD ArrayRef {
public:
using iterator = const T *;
using const_iterator = const T *;
@@ -114,30 +114,28 @@ namespace llvm {
/// Construct an ArrayRef<const T*> from ArrayRef<T*>. This uses SFINAE to
/// ensure that only ArrayRefs of pointers can be converted.
template <typename U>
- ArrayRef(
- const ArrayRef<U *> &A,
- typename std::enable_if<
- std::is_convertible<U *const *, T const *>::value>::type * = nullptr)
- : Data(A.data()), Length(A.size()) {}
+ ArrayRef(const ArrayRef<U *> &A,
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
+ * = nullptr)
+ : Data(A.data()), Length(A.size()) {}
/// Construct an ArrayRef<const T*> from a SmallVector<T*>. This is
/// templated in order to avoid instantiating SmallVectorTemplateCommon<T>
/// whenever we copy-construct an ArrayRef.
- template<typename U, typename DummyT>
+ template <typename U, typename DummyT>
/*implicit*/ ArrayRef(
- const SmallVectorTemplateCommon<U *, DummyT> &Vec,
- typename std::enable_if<
- std::is_convertible<U *const *, T const *>::value>::type * = nullptr)
- : Data(Vec.data()), Length(Vec.size()) {
- }
+ const SmallVectorTemplateCommon<U *, DummyT> &Vec,
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value> * =
+ nullptr)
+ : Data(Vec.data()), Length(Vec.size()) {}
/// Construct an ArrayRef<const T*> from std::vector<T*>. This uses SFINAE
/// to ensure that only vectors of pointers can be converted.
- template<typename U, typename A>
+ template <typename U, typename A>
ArrayRef(const std::vector<U *, A> &Vec,
- typename std::enable_if<
- std::is_convertible<U *const *, T const *>::value>::type* = 0)
- : Data(Vec.data()), Length(Vec.size()) {}
+ std::enable_if_t<std::is_convertible<U *const *, T const *>::value>
+ * = 0)
+ : Data(Vec.data()), Length(Vec.size()) {}
/// @}
/// @name Simple Operations
@@ -256,7 +254,7 @@ namespace llvm {
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
- typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
+ std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
operator=(U &&Temporary) = delete;
/// Disallow accidental assignment from a temporary.
@@ -264,7 +262,7 @@ namespace llvm {
/// The declaration here is extra complicated so that "arrayRef = {}"
/// continues to select the move assignment operator.
template <typename U>
- typename std::enable_if<std::is_same<U, T>::value, ArrayRef<T>>::type &
+ std::enable_if_t<std::is_same<U, T>::value, ArrayRef<T>> &
operator=(std::initializer_list<U>) = delete;
/// @}
@@ -308,17 +306,17 @@ namespace llvm {
/// Construct an empty MutableArrayRef from None.
/*implicit*/ MutableArrayRef(NoneType) : ArrayRef<T>() {}
- /// Construct an MutableArrayRef from a single element.
+ /// Construct a MutableArrayRef from a single element.
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
- /// Construct an MutableArrayRef from a pointer and length.
+ /// Construct a MutableArrayRef from a pointer and length.
/*implicit*/ MutableArrayRef(T *data, size_t length)
: ArrayRef<T>(data, length) {}
- /// Construct an MutableArrayRef from a range.
+ /// Construct a MutableArrayRef from a range.
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
- /// Construct an MutableArrayRef from a SmallVector.
+ /// Construct a MutableArrayRef from a SmallVector.
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
: ArrayRef<T>(Vec) {}
@@ -326,12 +324,12 @@ namespace llvm {
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
: ArrayRef<T>(Vec) {}
- /// Construct an ArrayRef from a std::array
+ /// Construct a MutableArrayRef from a std::array
template <size_t N>
/*implicit*/ constexpr MutableArrayRef(std::array<T, N> &Arr)
: ArrayRef<T>(Arr) {}
- /// Construct an MutableArrayRef from a C array.
+ /// Construct a MutableArrayRef from a C array.
template <size_t N>
/*implicit*/ constexpr MutableArrayRef(T (&Arr)[N]) : ArrayRef<T>(Arr) {}
@@ -534,11 +532,21 @@ namespace llvm {
return LHS.equals(RHS);
}
- template<typename T>
+ template <typename T>
+ inline bool operator==(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
+ return ArrayRef<T>(LHS).equals(RHS);
+ }
+
+ template <typename T>
inline bool operator!=(ArrayRef<T> LHS, ArrayRef<T> RHS) {
return !(LHS == RHS);
}
+ template <typename T>
+ inline bool operator!=(SmallVectorImpl<T> &LHS, ArrayRef<T> RHS) {
+ return !(LHS == RHS);
+ }
+
/// @}
template <typename T> hash_code hash_value(ArrayRef<T> S) {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/BitVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/BitVector.h
index 5284be8c4a02..a8d0f07af94a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/BitVector.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/BitVector.h
@@ -14,6 +14,7 @@
#define LLVM_ADT_BITVECTOR_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/MathExtras.h"
#include <algorithm>
@@ -531,24 +532,10 @@ public:
// Comparison operators.
bool operator==(const BitVector &RHS) const {
- unsigned ThisWords = NumBitWords(size());
- unsigned RHSWords = NumBitWords(RHS.size());
- unsigned i;
- for (i = 0; i != std::min(ThisWords, RHSWords); ++i)
- if (Bits[i] != RHS.Bits[i])
- return false;
-
- // Verify that any extra words are all zeros.
- if (i != ThisWords) {
- for (; i != ThisWords; ++i)
- if (Bits[i])
- return false;
- } else if (i != RHSWords) {
- for (; i != RHSWords; ++i)
- if (RHS.Bits[i])
- return false;
- }
- return true;
+ if (size() != RHS.size())
+ return false;
+ unsigned NumWords = NumBitWords(size());
+ return Bits.take_front(NumWords) == RHS.Bits.take_front(NumWords);
}
bool operator!=(const BitVector &RHS) const {
@@ -719,6 +706,14 @@ public:
if (this == &RHS) return *this;
Size = RHS.size();
+
+ // Handle tombstone when the BitVector is a key of a DenseHash.
+ if (RHS.isInvalid()) {
+ std::free(Bits.data());
+ Bits = None;
+ return *this;
+ }
+
unsigned RHSWords = NumBitWords(Size);
if (Size <= getBitCapacity()) {
if (Size)
@@ -758,6 +753,16 @@ public:
std::swap(Size, RHS.Size);
}
+ void invalid() {
+ assert(!Size && Bits.empty());
+ Size = (unsigned)-1;
+ }
+ bool isInvalid() const { return Size == (unsigned)-1; }
+
+ ArrayRef<BitWord> getData() const {
+ return Bits.take_front(NumBitWords(size()));
+ }
+
//===--------------------------------------------------------------------===//
// Portable bit mask operations.
//===--------------------------------------------------------------------===//
@@ -932,6 +937,23 @@ inline size_t capacity_in_bytes(const BitVector &X) {
return X.getMemorySize();
}
+template <> struct DenseMapInfo<BitVector> {
+ static inline BitVector getEmptyKey() { return BitVector(); }
+ static inline BitVector getTombstoneKey() {
+ BitVector V;
+ V.invalid();
+ return V;
+ }
+ static unsigned getHashValue(const BitVector &V) {
+ return DenseMapInfo<std::pair<unsigned, ArrayRef<uintptr_t>>>::getHashValue(
+ std::make_pair(V.size(), V.getData()));
+ }
+ static bool isEqual(const BitVector &LHS, const BitVector &RHS) {
+ if (LHS.isInvalid() || RHS.isInvalid())
+ return LHS.isInvalid() == RHS.isInvalid();
+ return LHS == RHS;
+ }
+};
} // end namespace llvm
namespace std {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Bitfields.h b/contrib/llvm-project/llvm/include/llvm/ADT/Bitfields.h
new file mode 100644
index 000000000000..d93f6483fa52
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Bitfields.h
@@ -0,0 +1,289 @@
+//===-- llvm/ADT/Bitfield.h - Get and Set bits in an integer ---*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file implements methods to test, set and extract typed bits from packed
+/// unsigned integers.
+///
+/// Why not C++ bitfields?
+/// ----------------------
+/// C++ bitfields do not offer control over the bit layout nor consistent
+/// behavior when it comes to out of range values.
+/// For instance, the layout is implementation defined and adjacent bits may be
+/// packed together but are not required to. This is problematic when storage is
+/// sparse and data must be stored in a particular integer type.
+///
+/// The methods provided in this file ensure precise control over the
+/// layout/storage as well as protection against out of range values.
+///
+/// Usage example
+/// -------------
+/// \code{.cpp}
+/// uint8_t Storage = 0;
+///
+/// // Store and retrieve a single bit as bool.
+/// using Bool = Bitfield::Element<bool, 0, 1>;
+/// Bitfield::set<Bool>(Storage, true);
+/// EXPECT_EQ(Storage, 0b00000001);
+/// // ^
+/// EXPECT_EQ(Bitfield::get<Bool>(Storage), true);
+///
+/// // Store and retrieve a 2 bit typed enum.
+/// // Note: enum underlying type must be unsigned.
+/// enum class SuitEnum : uint8_t { CLUBS, DIAMONDS, HEARTS, SPADES };
+/// // Note: enum maximum value needs to be passed in as last parameter.
+/// using Suit = Bitfield::Element<SuitEnum, 1, 2, SuitEnum::SPADES>;
+/// Bitfield::set<Suit>(Storage, SuitEnum::HEARTS);
+/// EXPECT_EQ(Storage, 0b00000101);
+/// // ^^
+/// EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::HEARTS);
+///
+/// // Store and retrieve a 5 bit value as unsigned.
+/// using Value = Bitfield::Element<unsigned, 3, 5>;
+/// Bitfield::set<Value>(Storage, 10);
+/// EXPECT_EQ(Storage, 0b01010101);
+/// // ^^^^^
+/// EXPECT_EQ(Bitfield::get<Value>(Storage), 10U);
+///
+/// // Interpret the same 5 bit value as signed.
+/// using SignedValue = Bitfield::Element<int, 3, 5>;
+/// Bitfield::set<SignedValue>(Storage, -2);
+/// EXPECT_EQ(Storage, 0b11110101);
+/// // ^^^^^
+/// EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -2);
+///
+/// // Ability to efficiently test if a field is non zero.
+/// EXPECT_TRUE(Bitfield::test<Value>(Storage));
+///
+/// // Alter Storage changes value.
+/// Storage = 0;
+/// EXPECT_EQ(Bitfield::get<Bool>(Storage), false);
+/// EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::CLUBS);
+/// EXPECT_EQ(Bitfield::get<Value>(Storage), 0U);
+/// EXPECT_EQ(Bitfield::get<SignedValue>(Storage), 0);
+///
+/// Storage = 255;
+/// EXPECT_EQ(Bitfield::get<Bool>(Storage), true);
+/// EXPECT_EQ(Bitfield::get<Suit>(Storage), SuitEnum::SPADES);
+/// EXPECT_EQ(Bitfield::get<Value>(Storage), 31U);
+/// EXPECT_EQ(Bitfield::get<SignedValue>(Storage), -1);
+/// \endcode
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITFIELDS_H
+#define LLVM_ADT_BITFIELDS_H
+
+#include <cassert>
+#include <climits> // CHAR_BIT
+#include <cstddef> // size_t
+#include <cstdint> // uintXX_t
+#include <limits> // numeric_limits
+#include <type_traits>
+
+namespace llvm {
+
+namespace bitfields_details {
+
+/// A struct defining useful bit patterns for n-bits integer types.
+template <typename T, unsigned Bits> struct BitPatterns {
+ /// Bit patterns are forged using the equivalent `Unsigned` type because of
+ /// undefined operations over signed types (e.g. Bitwise shift operators).
+ /// Moreover same size casting from unsigned to signed is well defined but not
+ /// the other way around.
+ using Unsigned = typename std::make_unsigned<T>::type;
+ static_assert(sizeof(Unsigned) == sizeof(T), "Types must have same size");
+
+ static constexpr unsigned TypeBits = sizeof(Unsigned) * CHAR_BIT;
+ static_assert(TypeBits >= Bits, "n-bit must fit in T");
+
+ /// e.g. with TypeBits == 8 and Bits == 6.
+ static constexpr Unsigned AllZeros = Unsigned(0); // 00000000
+ static constexpr Unsigned AllOnes = ~Unsigned(0); // 11111111
+ static constexpr Unsigned Umin = AllZeros; // 00000000
+ static constexpr Unsigned Umax = AllOnes >> (TypeBits - Bits); // 00111111
+ static constexpr Unsigned SignBitMask = Unsigned(1) << (Bits - 1); // 00100000
+ static constexpr Unsigned Smax = Umax >> 1U; // 00011111
+ static constexpr Unsigned Smin = ~Smax; // 11100000
+ static constexpr Unsigned SignExtend = Unsigned(Smin << 1U); // 11000000
+};
+
+/// `Compressor` is used to manipulate the bits of a (possibly signed) integer
+/// type so it can be packed and unpacked into a `bits` sized integer,
+/// `Compressor` is specialized on signed-ness so no runtime cost is incurred.
+/// The `pack` method also checks that the passed in `UserValue` is valid.
+template <typename T, unsigned Bits, bool = std::is_unsigned<T>::value>
+struct Compressor {
+ static_assert(std::is_unsigned<T>::value, "T is unsigned");
+ using BP = BitPatterns<T, Bits>;
+
+ static T pack(T UserValue, T UserMaxValue) {
+ assert(UserValue <= UserMaxValue && "value is too big");
+ assert(UserValue <= BP::Umax && "value is too big");
+ return UserValue;
+ }
+
+ static T unpack(T StorageValue) { return StorageValue; }
+};
+
+template <typename T, unsigned Bits> struct Compressor<T, Bits, false> {
+ static_assert(std::is_signed<T>::value, "T is signed");
+ using BP = BitPatterns<T, Bits>;
+
+ static T pack(T UserValue, T UserMaxValue) {
+ assert(UserValue <= UserMaxValue && "value is too big");
+ assert(UserValue <= T(BP::Smax) && "value is too big");
+ assert(UserValue >= T(BP::Smin) && "value is too small");
+ if (UserValue < 0)
+ UserValue &= ~BP::SignExtend;
+ return UserValue;
+ }
+
+ static T unpack(T StorageValue) {
+ if (StorageValue >= T(BP::SignBitMask))
+ StorageValue |= BP::SignExtend;
+ return StorageValue;
+ }
+};
+
+/// Impl is where Bifield description and Storage are put together to interact
+/// with values.
+template <typename Bitfield, typename StorageType> struct Impl {
+ static_assert(std::is_unsigned<StorageType>::value,
+ "Storage must be unsigned");
+ using IntegerType = typename Bitfield::IntegerType;
+ using C = Compressor<IntegerType, Bitfield::Bits>;
+ using BP = BitPatterns<StorageType, Bitfield::Bits>;
+
+ static constexpr size_t StorageBits = sizeof(StorageType) * CHAR_BIT;
+ static_assert(Bitfield::FirstBit <= StorageBits, "Data must fit in mask");
+ static_assert(Bitfield::LastBit <= StorageBits, "Data must fit in mask");
+ static constexpr StorageType Mask = BP::Umax << Bitfield::Shift;
+
+ /// Checks `UserValue` is within bounds and packs it between `FirstBit` and
+ /// `LastBit` of `Packed` leaving the rest unchanged.
+ static void update(StorageType &Packed, IntegerType UserValue) {
+ const StorageType StorageValue = C::pack(UserValue, Bitfield::UserMaxValue);
+ Packed &= ~Mask;
+ Packed |= StorageValue << Bitfield::Shift;
+ }
+
+ /// Interprets bits between `FirstBit` and `LastBit` of `Packed` as
+ /// an`IntegerType`.
+ static IntegerType extract(StorageType Packed) {
+ const StorageType StorageValue = (Packed & Mask) >> Bitfield::Shift;
+ return C::unpack(StorageValue);
+ }
+
+ /// Interprets bits between `FirstBit` and `LastBit` of `Packed` as
+ /// an`IntegerType`.
+ static StorageType test(StorageType Packed) { return Packed & Mask; }
+};
+
+/// `Bitfield` deals with the following type:
+/// - unsigned enums
+/// - signed and unsigned integer
+/// - `bool`
+/// Internally though we only manipulate integer with well defined and
+/// consistent semantics, this excludes typed enums and `bool` that are replaced
+/// with their unsigned counterparts. The correct type is restored in the public
+/// API.
+template <typename T, bool = std::is_enum<T>::value>
+struct ResolveUnderlyingType {
+ using type = typename std::underlying_type<T>::type;
+};
+template <typename T> struct ResolveUnderlyingType<T, false> {
+ using type = T;
+};
+template <> struct ResolveUnderlyingType<bool, false> {
+ /// In case sizeof(bool) != 1, replace `void` by an additionnal
+ /// std::conditional.
+ using type = std::conditional<sizeof(bool) == 1, uint8_t, void>::type;
+};
+
+} // namespace bitfields_details
+
+/// Holds functions to get, set or test bitfields.
+struct Bitfield {
+ /// Describes an element of a Bitfield. This type is then used with the
+ /// Bitfield static member functions.
+ /// \tparam T The type of the field once in unpacked form.
+ /// \tparam Offset The position of the first bit.
+ /// \tparam Size The size of the field.
+ /// \tparam MaxValue For enums the maximum enum allowed.
+ template <typename T, unsigned Offset, unsigned Size,
+ T MaxValue = std::is_enum<T>::value
+ ? T(0) // coupled with static_assert below
+ : std::numeric_limits<T>::max()>
+ struct Element {
+ using Type = T;
+ using IntegerType =
+ typename bitfields_details::ResolveUnderlyingType<T>::type;
+ static constexpr unsigned Shift = Offset;
+ static constexpr unsigned Bits = Size;
+ static constexpr unsigned FirstBit = Offset;
+ static constexpr unsigned LastBit = Shift + Bits - 1;
+ static constexpr unsigned NextBit = Shift + Bits;
+
+ private:
+ template <typename, typename> friend struct bitfields_details::Impl;
+
+ static_assert(Bits > 0, "Bits must be non zero");
+ static constexpr size_t TypeBits = sizeof(IntegerType) * CHAR_BIT;
+ static_assert(Bits <= TypeBits, "Bits may not be greater than T size");
+ static_assert(!std::is_enum<T>::value || MaxValue != T(0),
+ "Enum Bitfields must provide a MaxValue");
+ static_assert(!std::is_enum<T>::value ||
+ std::is_unsigned<IntegerType>::value,
+ "Enum must be unsigned");
+ static_assert(std::is_integral<IntegerType>::value &&
+ std::numeric_limits<IntegerType>::is_integer,
+ "IntegerType must be an integer type");
+
+ static constexpr IntegerType UserMaxValue =
+ static_cast<IntegerType>(MaxValue);
+ };
+
+ /// Unpacks the field from the `Packed` value.
+ template <typename Bitfield, typename StorageType>
+ static typename Bitfield::Type get(StorageType Packed) {
+ using I = bitfields_details::Impl<Bitfield, StorageType>;
+ return static_cast<typename Bitfield::Type>(I::extract(Packed));
+ }
+
+ /// Return a non-zero value if the field is non-zero.
+ /// It is more efficient than `getField`.
+ template <typename Bitfield, typename StorageType>
+ static StorageType test(StorageType Packed) {
+ using I = bitfields_details::Impl<Bitfield, StorageType>;
+ return I::test(Packed);
+ }
+
+ /// Sets the typed value in the provided `Packed` value.
+ /// The method will asserts if the provided value is too big to fit in.
+ template <typename Bitfield, typename StorageType>
+ static void set(StorageType &Packed, typename Bitfield::Type Value) {
+ using I = bitfields_details::Impl<Bitfield, StorageType>;
+ I::update(Packed, static_cast<typename Bitfield::IntegerType>(Value));
+ }
+
+ /// Returns whether the two bitfields share common bits.
+ template <typename A, typename B> static constexpr bool isOverlapping() {
+ return A::LastBit >= B::FirstBit && B::LastBit >= A::FirstBit;
+ }
+
+ template <typename A> static constexpr bool areContiguous() { return true; }
+ template <typename A, typename B, typename... Others>
+ static constexpr bool areContiguous() {
+ return A::NextBit == B::FirstBit && areContiguous<B, Others...>();
+ }
+};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_BITFIELDS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/BitmaskEnum.h b/contrib/llvm-project/llvm/include/llvm/ADT/BitmaskEnum.h
index 1a18bc721b21..89e5508e08e1 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/BitmaskEnum.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/BitmaskEnum.h
@@ -71,49 +71,49 @@ struct is_bitmask_enum : std::false_type {};
template <typename E>
struct is_bitmask_enum<
- E, typename std::enable_if<sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >=
- 0>::type> : std::true_type {};
+ E, std::enable_if_t<sizeof(E::LLVM_BITMASK_LARGEST_ENUMERATOR) >= 0>>
+ : std::true_type {};
namespace BitmaskEnumDetail {
/// Get a bitmask with 1s in all places up to the high-order bit of E's largest
/// value.
-template <typename E> typename std::underlying_type<E>::type Mask() {
+template <typename E> std::underlying_type_t<E> Mask() {
// On overflow, NextPowerOf2 returns zero with the type uint64_t, so
// subtracting 1 gives us the mask with all bits set, like we want.
- return NextPowerOf2(static_cast<typename std::underlying_type<E>::type>(
+ return NextPowerOf2(static_cast<std::underlying_type_t<E>>(
E::LLVM_BITMASK_LARGEST_ENUMERATOR)) -
1;
}
/// Check that Val is in range for E, and return Val cast to E's underlying
/// type.
-template <typename E> typename std::underlying_type<E>::type Underlying(E Val) {
- auto U = static_cast<typename std::underlying_type<E>::type>(Val);
+template <typename E> std::underlying_type_t<E> Underlying(E Val) {
+ auto U = static_cast<std::underlying_type_t<E>>(Val);
assert(U >= 0 && "Negative enum values are not allowed.");
assert(U <= Mask<E>() && "Enum value too large (or largest val too small?)");
return U;
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+constexpr unsigned bitWidth(uint64_t Value) {
+ return Value ? 1 + bitWidth(Value >> 1) : 0;
+}
+
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E operator~(E Val) {
return static_cast<E>(~Underlying(Val) & Mask<E>());
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E operator|(E LHS, E RHS) {
return static_cast<E>(Underlying(LHS) | Underlying(RHS));
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E operator&(E LHS, E RHS) {
return static_cast<E>(Underlying(LHS) & Underlying(RHS));
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E operator^(E LHS, E RHS) {
return static_cast<E>(Underlying(LHS) ^ Underlying(RHS));
}
@@ -121,22 +121,19 @@ E operator^(E LHS, E RHS) {
// |=, &=, and ^= return a reference to LHS, to match the behavior of the
// operators on builtin types.
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E &operator|=(E &LHS, E RHS) {
LHS = LHS | RHS;
return LHS;
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E &operator&=(E &LHS, E RHS) {
LHS = LHS & RHS;
return LHS;
}
-template <typename E,
- typename = typename std::enable_if<is_bitmask_enum<E>::value>::type>
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
E &operator^=(E &LHS, E RHS) {
LHS = LHS ^ RHS;
return LHS;
@@ -146,6 +143,10 @@ E &operator^=(E &LHS, E RHS) {
// Enable bitmask enums in namespace ::llvm and all nested namespaces.
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+template <typename E, typename = std::enable_if_t<is_bitmask_enum<E>::value>>
+constexpr unsigned BitWidth = BitmaskEnumDetail::bitWidth(uint64_t{
+ static_cast<std::underlying_type_t<E>>(
+ E::LLVM_BITMASK_LARGEST_ENUMERATOR)});
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/CachedHashString.h b/contrib/llvm-project/llvm/include/llvm/ADT/CachedHashString.h
index 80144fb87e0e..6233d0fc08fd 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/CachedHashString.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/CachedHashString.h
@@ -19,9 +19,8 @@
#ifndef LLVM_ADT_CACHED_HASH_STRING_H
#define LLVM_ADT_CACHED_HASH_STRING_H
-#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/CoalescingBitVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/CoalescingBitVector.h
new file mode 100644
index 000000000000..f8c8fec0ec9e
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/CoalescingBitVector.h
@@ -0,0 +1,444 @@
+//===- llvm/ADT/CoalescingBitVector.h - A coalescing bitvector --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file A bitvector that uses an IntervalMap to coalesce adjacent elements
+/// into intervals.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_COALESCINGBITVECTOR_H
+#define LLVM_ADT_COALESCINGBITVECTOR_H
+
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <algorithm>
+#include <initializer_list>
+
+namespace llvm {
+
+/// A bitvector that, under the hood, relies on an IntervalMap to coalesce
+/// elements into intervals. Good for representing sets which predominantly
+/// contain contiguous ranges. Bad for representing sets with lots of gaps
+/// between elements.
+///
+/// Compared to SparseBitVector, CoalescingBitVector offers more predictable
+/// performance for non-sequential find() operations.
+///
+/// \tparam IndexT - The type of the index into the bitvector.
+/// \tparam N - The first N coalesced intervals of set bits are stored in-place.
+template <typename IndexT, unsigned N = 16> class CoalescingBitVector {
+ static_assert(std::is_unsigned<IndexT>::value,
+ "Index must be an unsigned integer.");
+
+ using ThisT = CoalescingBitVector<IndexT, N>;
+
+ /// An interval map for closed integer ranges. The mapped values are unused.
+ using MapT = IntervalMap<IndexT, char, N>;
+
+ using UnderlyingIterator = typename MapT::const_iterator;
+
+ using IntervalT = std::pair<IndexT, IndexT>;
+
+public:
+ using Allocator = typename MapT::Allocator;
+
+ /// Construct by passing in a CoalescingBitVector<IndexT>::Allocator
+ /// reference.
+ CoalescingBitVector(Allocator &Alloc)
+ : Alloc(&Alloc), Intervals(Alloc) {}
+
+ /// \name Copy/move constructors and assignment operators.
+ /// @{
+
+ CoalescingBitVector(const ThisT &Other)
+ : Alloc(Other.Alloc), Intervals(*Other.Alloc) {
+ set(Other);
+ }
+
+ ThisT &operator=(const ThisT &Other) {
+ clear();
+ set(Other);
+ return *this;
+ }
+
+ CoalescingBitVector(ThisT &&Other) = delete;
+ ThisT &operator=(ThisT &&Other) = delete;
+
+ /// @}
+
+ /// Clear all the bits.
+ void clear() { Intervals.clear(); }
+
+ /// Check whether no bits are set.
+ bool empty() const { return Intervals.empty(); }
+
+ /// Count the number of set bits.
+ unsigned count() const {
+ unsigned Bits = 0;
+ for (auto It = Intervals.begin(), End = Intervals.end(); It != End; ++It)
+ Bits += 1 + It.stop() - It.start();
+ return Bits;
+ }
+
+ /// Set the bit at \p Index.
+ ///
+ /// This method does /not/ support setting a bit that has already been set,
+ /// for efficiency reasons. If possible, restructure your code to not set the
+ /// same bit multiple times, or use \ref test_and_set.
+ void set(IndexT Index) {
+ assert(!test(Index) && "Setting already-set bits not supported/efficient, "
+ "IntervalMap will assert");
+ insert(Index, Index);
+ }
+
+ /// Set the bits set in \p Other.
+ ///
+ /// This method does /not/ support setting already-set bits, see \ref set
+ /// for the rationale. For a safe set union operation, use \ref operator|=.
+ void set(const ThisT &Other) {
+ for (auto It = Other.Intervals.begin(), End = Other.Intervals.end();
+ It != End; ++It)
+ insert(It.start(), It.stop());
+ }
+
+ /// Set the bits at \p Indices. Used for testing, primarily.
+ void set(std::initializer_list<IndexT> Indices) {
+ for (IndexT Index : Indices)
+ set(Index);
+ }
+
+ /// Check whether the bit at \p Index is set.
+ bool test(IndexT Index) const {
+ const auto It = Intervals.find(Index);
+ if (It == Intervals.end())
+ return false;
+ assert(It.stop() >= Index && "Interval must end after Index");
+ return It.start() <= Index;
+ }
+
+ /// Set the bit at \p Index. Supports setting an already-set bit.
+ void test_and_set(IndexT Index) {
+ if (!test(Index))
+ set(Index);
+ }
+
+ /// Reset the bit at \p Index. Supports resetting an already-unset bit.
+ void reset(IndexT Index) {
+ auto It = Intervals.find(Index);
+ if (It == Intervals.end())
+ return;
+
+ // Split the interval containing Index into up to two parts: one from
+ // [Start, Index-1] and another from [Index+1, Stop]. If Index is equal to
+ // either Start or Stop, we create one new interval. If Index is equal to
+ // both Start and Stop, we simply erase the existing interval.
+ IndexT Start = It.start();
+ if (Index < Start)
+ // The index was not set.
+ return;
+ IndexT Stop = It.stop();
+ assert(Index <= Stop && "Wrong interval for index");
+ It.erase();
+ if (Start < Index)
+ insert(Start, Index - 1);
+ if (Index < Stop)
+ insert(Index + 1, Stop);
+ }
+
+ /// Set union. If \p RHS is guaranteed to not overlap with this, \ref set may
+ /// be a faster alternative.
+ void operator|=(const ThisT &RHS) {
+ // Get the overlaps between the two interval maps.
+ SmallVector<IntervalT, 8> Overlaps;
+ getOverlaps(RHS, Overlaps);
+
+ // Insert the non-overlapping parts of all the intervals from RHS.
+ for (auto It = RHS.Intervals.begin(), End = RHS.Intervals.end();
+ It != End; ++It) {
+ IndexT Start = It.start();
+ IndexT Stop = It.stop();
+ SmallVector<IntervalT, 8> NonOverlappingParts;
+ getNonOverlappingParts(Start, Stop, Overlaps, NonOverlappingParts);
+ for (IntervalT AdditivePortion : NonOverlappingParts)
+ insert(AdditivePortion.first, AdditivePortion.second);
+ }
+ }
+
+ /// Set intersection.
+ void operator&=(const ThisT &RHS) {
+ // Get the overlaps between the two interval maps (i.e. the intersection).
+ SmallVector<IntervalT, 8> Overlaps;
+ getOverlaps(RHS, Overlaps);
+ // Rebuild the interval map, including only the overlaps.
+ clear();
+ for (IntervalT Overlap : Overlaps)
+ insert(Overlap.first, Overlap.second);
+ }
+
+ /// Reset all bits present in \p Other.
+ void intersectWithComplement(const ThisT &Other) {
+ SmallVector<IntervalT, 8> Overlaps;
+ if (!getOverlaps(Other, Overlaps)) {
+ // If there is no overlap with Other, the intersection is empty.
+ return;
+ }
+
+ // Delete the overlapping intervals. Split up intervals that only partially
+ // intersect an overlap.
+ for (IntervalT Overlap : Overlaps) {
+ IndexT OlapStart, OlapStop;
+ std::tie(OlapStart, OlapStop) = Overlap;
+
+ auto It = Intervals.find(OlapStart);
+ IndexT CurrStart = It.start();
+ IndexT CurrStop = It.stop();
+ assert(CurrStart <= OlapStart && OlapStop <= CurrStop &&
+ "Expected some intersection!");
+
+ // Split the overlap interval into up to two parts: one from [CurrStart,
+ // OlapStart-1] and another from [OlapStop+1, CurrStop]. If OlapStart is
+ // equal to CurrStart, the first split interval is unnecessary. Ditto for
+ // when OlapStop is equal to CurrStop, we omit the second split interval.
+ It.erase();
+ if (CurrStart < OlapStart)
+ insert(CurrStart, OlapStart - 1);
+ if (OlapStop < CurrStop)
+ insert(OlapStop + 1, CurrStop);
+ }
+ }
+
+ bool operator==(const ThisT &RHS) const {
+ // We cannot just use std::equal because it checks the dereferenced values
+ // of an iterator pair for equality, not the iterators themselves. In our
+ // case that results in comparison of the (unused) IntervalMap values.
+ auto ItL = Intervals.begin();
+ auto ItR = RHS.Intervals.begin();
+ while (ItL != Intervals.end() && ItR != RHS.Intervals.end() &&
+ ItL.start() == ItR.start() && ItL.stop() == ItR.stop()) {
+ ++ItL;
+ ++ItR;
+ }
+ return ItL == Intervals.end() && ItR == RHS.Intervals.end();
+ }
+
+ bool operator!=(const ThisT &RHS) const { return !operator==(RHS); }
+
+ class const_iterator
+ : public std::iterator<std::forward_iterator_tag, IndexT> {
+ friend class CoalescingBitVector;
+
+ // For performance reasons, make the offset at the end different than the
+ // one used in \ref begin, to optimize the common `It == end()` pattern.
+ static constexpr unsigned kIteratorAtTheEndOffset = ~0u;
+
+ UnderlyingIterator MapIterator;
+ unsigned OffsetIntoMapIterator = 0;
+
+ // Querying the start/stop of an IntervalMap iterator can be very expensive.
+ // Cache these values for performance reasons.
+ IndexT CachedStart = IndexT();
+ IndexT CachedStop = IndexT();
+
+ void setToEnd() {
+ OffsetIntoMapIterator = kIteratorAtTheEndOffset;
+ CachedStart = IndexT();
+ CachedStop = IndexT();
+ }
+
+ /// MapIterator has just changed, reset the cached state to point to the
+ /// start of the new underlying iterator.
+ void resetCache() {
+ if (MapIterator.valid()) {
+ OffsetIntoMapIterator = 0;
+ CachedStart = MapIterator.start();
+ CachedStop = MapIterator.stop();
+ } else {
+ setToEnd();
+ }
+ }
+
+ /// Advance the iterator to \p Index, if it is contained within the current
+ /// interval. The public-facing method which supports advancing past the
+ /// current interval is \ref advanceToLowerBound.
+ void advanceTo(IndexT Index) {
+ assert(Index <= CachedStop && "Cannot advance to OOB index");
+ if (Index < CachedStart)
+ // We're already past this index.
+ return;
+ OffsetIntoMapIterator = Index - CachedStart;
+ }
+
+ const_iterator(UnderlyingIterator MapIt) : MapIterator(MapIt) {
+ resetCache();
+ }
+
+ public:
+ const_iterator() { setToEnd(); }
+
+ bool operator==(const const_iterator &RHS) const {
+ // Do /not/ compare MapIterator for equality, as this is very expensive.
+ // The cached start/stop values make that check unnecessary.
+ return std::tie(OffsetIntoMapIterator, CachedStart, CachedStop) ==
+ std::tie(RHS.OffsetIntoMapIterator, RHS.CachedStart,
+ RHS.CachedStop);
+ }
+
+ bool operator!=(const const_iterator &RHS) const {
+ return !operator==(RHS);
+ }
+
+ IndexT operator*() const { return CachedStart + OffsetIntoMapIterator; }
+
+ const_iterator &operator++() { // Pre-increment (++It).
+ if (CachedStart + OffsetIntoMapIterator < CachedStop) {
+ // Keep going within the current interval.
+ ++OffsetIntoMapIterator;
+ } else {
+ // We reached the end of the current interval: advance.
+ ++MapIterator;
+ resetCache();
+ }
+ return *this;
+ }
+
+ const_iterator operator++(int) { // Post-increment (It++).
+ const_iterator tmp = *this;
+ operator++();
+ return tmp;
+ }
+
+ /// Advance the iterator to the first set bit AT, OR AFTER, \p Index. If
+ /// no such set bit exists, advance to end(). This is like std::lower_bound.
+ /// This is useful if \p Index is close to the current iterator position.
+ /// However, unlike \ref find(), this has worst-case O(n) performance.
+ void advanceToLowerBound(IndexT Index) {
+ if (OffsetIntoMapIterator == kIteratorAtTheEndOffset)
+ return;
+
+ // Advance to the first interval containing (or past) Index, or to end().
+ while (Index > CachedStop) {
+ ++MapIterator;
+ resetCache();
+ if (OffsetIntoMapIterator == kIteratorAtTheEndOffset)
+ return;
+ }
+
+ advanceTo(Index);
+ }
+ };
+
+ const_iterator begin() const { return const_iterator(Intervals.begin()); }
+
+ const_iterator end() const { return const_iterator(); }
+
+ /// Return an iterator pointing to the first set bit AT, OR AFTER, \p Index.
+ /// If no such set bit exists, return end(). This is like std::lower_bound.
+ /// This has worst-case logarithmic performance (roughly O(log(gaps between
+ /// contiguous ranges))).
+ const_iterator find(IndexT Index) const {
+ auto UnderlyingIt = Intervals.find(Index);
+ if (UnderlyingIt == Intervals.end())
+ return end();
+ auto It = const_iterator(UnderlyingIt);
+ It.advanceTo(Index);
+ return It;
+ }
+
+ /// Return a range iterator which iterates over all of the set bits in the
+ /// half-open range [Start, End).
+ iterator_range<const_iterator> half_open_range(IndexT Start,
+ IndexT End) const {
+ assert(Start < End && "Not a valid range");
+ auto StartIt = find(Start);
+ if (StartIt == end() || *StartIt >= End)
+ return {end(), end()};
+ auto EndIt = StartIt;
+ EndIt.advanceToLowerBound(End);
+ return {StartIt, EndIt};
+ }
+
+ void print(raw_ostream &OS) const {
+ OS << "{";
+ for (auto It = Intervals.begin(), End = Intervals.end(); It != End;
+ ++It) {
+ OS << "[" << It.start();
+ if (It.start() != It.stop())
+ OS << ", " << It.stop();
+ OS << "]";
+ }
+ OS << "}";
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const {
+ // LLDB swallows the first line of output after callling dump(). Add
+ // newlines before/after the braces to work around this.
+ dbgs() << "\n";
+ print(dbgs());
+ dbgs() << "\n";
+ }
+#endif
+
+private:
+ void insert(IndexT Start, IndexT End) { Intervals.insert(Start, End, 0); }
+
+ /// Record the overlaps between \p this and \p Other in \p Overlaps. Return
+ /// true if there is any overlap.
+ bool getOverlaps(const ThisT &Other,
+ SmallVectorImpl<IntervalT> &Overlaps) const {
+ for (IntervalMapOverlaps<MapT, MapT> I(Intervals, Other.Intervals);
+ I.valid(); ++I)
+ Overlaps.emplace_back(I.start(), I.stop());
+ assert(llvm::is_sorted(Overlaps,
+ [](IntervalT LHS, IntervalT RHS) {
+ return LHS.second < RHS.first;
+ }) &&
+ "Overlaps must be sorted");
+ return !Overlaps.empty();
+ }
+
+ /// Given the set of overlaps between this and some other bitvector, and an
+ /// interval [Start, Stop] from that bitvector, determine the portions of the
+ /// interval which do not overlap with this.
+ void getNonOverlappingParts(IndexT Start, IndexT Stop,
+ const SmallVectorImpl<IntervalT> &Overlaps,
+ SmallVectorImpl<IntervalT> &NonOverlappingParts) {
+ IndexT NextUncoveredBit = Start;
+ for (IntervalT Overlap : Overlaps) {
+ IndexT OlapStart, OlapStop;
+ std::tie(OlapStart, OlapStop) = Overlap;
+
+ // [Start;Stop] and [OlapStart;OlapStop] overlap iff OlapStart <= Stop
+ // and Start <= OlapStop.
+ bool DoesOverlap = OlapStart <= Stop && Start <= OlapStop;
+ if (!DoesOverlap)
+ continue;
+
+ // Cover the range [NextUncoveredBit, OlapStart). This puts the start of
+ // the next uncovered range at OlapStop+1.
+ if (NextUncoveredBit < OlapStart)
+ NonOverlappingParts.emplace_back(NextUncoveredBit, OlapStart - 1);
+ NextUncoveredBit = OlapStop + 1;
+ if (NextUncoveredBit > Stop)
+ break;
+ }
+ if (NextUncoveredBit <= Stop)
+ NonOverlappingParts.emplace_back(NextUncoveredBit, Stop);
+ }
+
+ Allocator *Alloc;
+ MapT Intervals;
+};
+
+} // namespace llvm
+
+#endif // LLVM_ADT_COALESCINGBITVECTOR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h b/contrib/llvm-project/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
index d4cdc3c86048..c3872af2a0b4 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -29,7 +29,7 @@ namespace llvm {
///
/// P(S) => P(S union pred(S))
///
-/// The minization algorithm uses this dependency information to attempt to
+/// The minimization algorithm uses this dependency information to attempt to
/// eagerly prune large subsets of changes. As with \see DeltaAlgorithm, the DAG
/// is not required to satisfy this property, but the algorithm will run
/// substantially fewer tests with appropriate dependencies. \see DeltaAlgorithm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/DeltaAlgorithm.h b/contrib/llvm-project/llvm/include/llvm/ADT/DeltaAlgorithm.h
index 114b95499530..e1743fd00196 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/DeltaAlgorithm.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/DeltaAlgorithm.h
@@ -54,7 +54,7 @@ private:
/// Split - Partition a set of changes \p S into one or two subsets.
void Split(const changeset_ty &S, changesetlist_ty &Res);
- /// Delta - Minimize a set of \p Changes which has been partioned into
+ /// Delta - Minimize a set of \p Changes which has been partitioned into
/// smaller sets, by attempting to remove individual subsets.
changeset_ty Delta(const changeset_ty &Changes,
const changesetlist_ty &Sets);
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/DenseMap.h b/contrib/llvm-project/llvm/include/llvm/ADT/DenseMap.h
index 148d319c8603..34d397cc9793 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/DenseMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/DenseMap.h
@@ -18,6 +18,7 @@
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/ReverseIteration.h"
#include "llvm/Support/type_traits.h"
#include <algorithm>
@@ -119,9 +120,8 @@ public:
}
const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
- if (is_trivially_copyable<KeyT>::value &&
- is_trivially_copyable<ValueT>::value) {
- // Use a simpler loop when these are trivial types.
+ if (std::is_trivially_destructible<ValueT>::value) {
+ // Use a simpler loop when values don't need destruction.
for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P)
P->getFirst() = EmptyKey;
} else {
@@ -150,13 +150,19 @@ public:
iterator find(const_arg_type_t<KeyT> Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return makeIterator(TheBucket, getBucketsEnd(), *this, true);
+ return makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>() ? getBuckets()
+ : getBucketsEnd(),
+ *this, true);
return end();
}
const_iterator find(const_arg_type_t<KeyT> Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return makeConstIterator(TheBucket, getBucketsEnd(), *this, true);
+ return makeConstIterator(TheBucket,
+ shouldReverseIterate<KeyT>() ? getBuckets()
+ : getBucketsEnd(),
+ *this, true);
return end();
}
@@ -169,14 +175,20 @@ public:
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return makeIterator(TheBucket, getBucketsEnd(), *this, true);
+ return makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>() ? getBuckets()
+ : getBucketsEnd(),
+ *this, true);
return end();
}
template<class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return makeConstIterator(TheBucket, getBucketsEnd(), *this, true);
+ return makeConstIterator(TheBucket,
+ shouldReverseIterate<KeyT>() ? getBuckets()
+ : getBucketsEnd(),
+ *this, true);
return end();
}
@@ -210,16 +222,22 @@ public:
std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- false); // Already in map.
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ false); // Already in map.
// Otherwise, insert the new element.
TheBucket =
InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...);
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- true);
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ true);
}
// Inserts key,value pair into the map if the key isn't already in the map.
@@ -229,15 +247,21 @@ public:
std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
BucketT *TheBucket;
if (LookupBucketFor(Key, TheBucket))
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- false); // Already in map.
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...);
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- true);
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ true);
}
/// Alternate version of insert() which allows a different, and possibly
@@ -250,16 +274,22 @@ public:
const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- false); // Already in map.
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
std::move(KV.second), Val);
- return std::make_pair(
- makeIterator(TheBucket, getBucketsEnd(), *this, true),
- true);
+ return std::make_pair(makeIterator(TheBucket,
+ shouldReverseIterate<KeyT>()
+ ? getBuckets()
+ : getBucketsEnd(),
+ *this, true),
+ true);
}
/// insert - Range insertion of pairs.
@@ -695,7 +725,7 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
unsigned NumBuckets;
public:
- /// Create a DenseMap wth an optional \p InitialReserve that guarantee that
+ /// Create a DenseMap with an optional \p InitialReserve that guarantee that
/// this number of elements can be inserted in the map without grow()
explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); }
@@ -1194,19 +1224,21 @@ public:
// for const iterator destinations so it doesn't end up as a user defined copy
// constructor.
template <bool IsConstSrc,
- typename = typename std::enable_if<!IsConstSrc && IsConst>::type>
+ typename = std::enable_if_t<!IsConstSrc && IsConst>>
DenseMapIterator(
const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
: DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
reference operator*() const {
assert(isHandleInSync() && "invalid iterator access!");
+ assert(Ptr != End && "dereferencing end() iterator");
if (shouldReverseIterate<KeyT>())
return Ptr[-1];
return *Ptr;
}
pointer operator->() const {
assert(isHandleInSync() && "invalid iterator access!");
+ assert(Ptr != End && "dereferencing end() iterator");
if (shouldReverseIterate<KeyT>())
return &(Ptr[-1]);
return Ptr;
@@ -1229,6 +1261,7 @@ public:
inline DenseMapIterator& operator++() { // Preincrement
assert(isHandleInSync() && "invalid iterator access!");
+ assert(Ptr != End && "incrementing end() iterator");
if (shouldReverseIterate<KeyT>()) {
--Ptr;
RetreatPastEmptyBuckets();
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/DenseMapInfo.h b/contrib/llvm-project/llvm/include/llvm/ADT/DenseMapInfo.h
index bd4c60c8f13e..e465331ac6f7 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/DenseMapInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/DenseMapInfo.h
@@ -16,8 +16,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/Support/TypeSize.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
@@ -25,6 +23,24 @@
namespace llvm {
+namespace detail {
+
+/// Simplistic combination of 32-bit hash values into 32-bit hash values.
+static inline unsigned combineHashValue(unsigned a, unsigned b) {
+ uint64_t key = (uint64_t)a << 32 | (uint64_t)b;
+ key += ~(key << 32);
+ key ^= (key >> 22);
+ key += ~(key << 13);
+ key ^= (key >> 8);
+ key += (key << 3);
+ key ^= (key >> 15);
+ key += ~(key << 27);
+ key ^= (key >> 31);
+ return (unsigned)key;
+}
+
+} // end namespace detail
+
template<typename T>
struct DenseMapInfo {
//static inline T getEmptyKey();
@@ -33,18 +49,28 @@ struct DenseMapInfo {
//static bool isEqual(const T &LHS, const T &RHS);
};
-// Provide DenseMapInfo for all pointers.
+// Provide DenseMapInfo for all pointers. Come up with sentinel pointer values
+// that are aligned to alignof(T) bytes, but try to avoid requiring T to be
+// complete. This allows clients to instantiate DenseMap<T*, ...> with forward
+// declared key types. Assume that no pointer key type requires more than 4096
+// bytes of alignment.
template<typename T>
struct DenseMapInfo<T*> {
+ // The following should hold, but it would require T to be complete:
+ // static_assert(alignof(T) <= (1 << Log2MaxAlign),
+ // "DenseMap does not support pointer keys requiring more than "
+ // "Log2MaxAlign bits of alignment");
+ static constexpr uintptr_t Log2MaxAlign = 12;
+
static inline T* getEmptyKey() {
uintptr_t Val = static_cast<uintptr_t>(-1);
- Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ Val <<= Log2MaxAlign;
return reinterpret_cast<T*>(Val);
}
static inline T* getTombstoneKey() {
uintptr_t Val = static_cast<uintptr_t>(-2);
- Val <<= PointerLikeTypeTraits<T*>::NumLowBitsAvailable;
+ Val <<= Log2MaxAlign;
return reinterpret_cast<T*>(Val);
}
@@ -198,17 +224,8 @@ struct DenseMapInfo<std::pair<T, U>> {
}
static unsigned getHashValue(const Pair& PairVal) {
- uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32
- | (uint64_t)SecondInfo::getHashValue(PairVal.second);
- key += ~(key << 32);
- key ^= (key >> 22);
- key += ~(key << 13);
- key ^= (key >> 8);
- key += (key << 3);
- key ^= (key >> 15);
- key += ~(key << 27);
- key ^= (key >> 31);
- return (unsigned)key;
+ return detail::combineHashValue(FirstInfo::getHashValue(PairVal.first),
+ SecondInfo::getHashValue(PairVal.second));
}
static bool isEqual(const Pair &LHS, const Pair &RHS) {
@@ -217,6 +234,56 @@ struct DenseMapInfo<std::pair<T, U>> {
}
};
+// Provide DenseMapInfo for all tuples whose members have info.
+template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
+ using Tuple = std::tuple<Ts...>;
+
+ static inline Tuple getEmptyKey() {
+ return Tuple(DenseMapInfo<Ts>::getEmptyKey()...);
+ }
+
+ static inline Tuple getTombstoneKey() {
+ return Tuple(DenseMapInfo<Ts>::getTombstoneKey()...);
+ }
+
+ template <unsigned I>
+ static unsigned getHashValueImpl(const Tuple &values, std::false_type) {
+ using EltType = typename std::tuple_element<I, Tuple>::type;
+ std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
+ return detail::combineHashValue(
+ DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
+ getHashValueImpl<I + 1>(values, atEnd));
+ }
+
+ template <unsigned I>
+ static unsigned getHashValueImpl(const Tuple &values, std::true_type) {
+ return 0;
+ }
+
+ static unsigned getHashValue(const std::tuple<Ts...> &values) {
+ std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
+ return getHashValueImpl<0>(values, atEnd);
+ }
+
+ template <unsigned I>
+ static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) {
+ using EltType = typename std::tuple_element<I, Tuple>::type;
+ std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
+ return DenseMapInfo<EltType>::isEqual(std::get<I>(lhs), std::get<I>(rhs)) &&
+ isEqualImpl<I + 1>(lhs, rhs, atEnd);
+ }
+
+ template <unsigned I>
+ static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::true_type) {
+ return true;
+ }
+
+ static bool isEqual(const Tuple &lhs, const Tuple &rhs) {
+ std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
+ return isEqualImpl<0>(lhs, rhs, atEnd);
+ }
+};
+
// Provide DenseMapInfo for StringRefs.
template <> struct DenseMapInfo<StringRef> {
static inline StringRef getEmptyKey() {
@@ -280,21 +347,6 @@ template <> struct DenseMapInfo<hash_code> {
static bool isEqual(hash_code LHS, hash_code RHS) { return LHS == RHS; }
};
-template <> struct DenseMapInfo<ElementCount> {
- static inline ElementCount getEmptyKey() { return {~0U, true}; }
- static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; }
- static unsigned getHashValue(const ElementCount& EltCnt) {
- if (EltCnt.Scalable)
- return (EltCnt.Min * 37U) - 1U;
-
- return EltCnt.Min * 37U;
- }
-
- static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) {
- return LHS == RHS;
- }
-};
-
} // end namespace llvm
#endif // LLVM_ADT_DENSEMAPINFO_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/DenseSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/DenseSet.h
index 9afb715ae1db..07edc3d8e4ec 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/DenseSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/DenseSet.h
@@ -66,6 +66,12 @@ public:
explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {}
+ template <typename InputIt>
+ DenseSetImpl(const InputIt &I, const InputIt &E)
+ : DenseSetImpl(PowerOf2Ceil(std::distance(I, E))) {
+ insert(I, E);
+ }
+
DenseSetImpl(std::initializer_list<ValueT> Elems)
: DenseSetImpl(PowerOf2Ceil(Elems.size())) {
insert(Elems.begin(), Elems.end());
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/EnumeratedArray.h b/contrib/llvm-project/llvm/include/llvm/ADT/EnumeratedArray.h
index a9528115618c..a66ec9d08c37 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/EnumeratedArray.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/EnumeratedArray.h
@@ -38,6 +38,7 @@ public:
static_cast<const EnumeratedArray<ValueType, Enumeration, LargestEnum,
IndexType, Size> &>(*this)[Index]);
}
+ inline IndexType size() { return Size; }
private:
ValueType Underlying[Size];
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h b/contrib/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h
index 670b2368da9f..3ba8ae1b2855 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/FloatingPointMode.h
@@ -14,28 +14,123 @@
#define LLVM_FLOATINGPOINTMODE_H
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
-/// Represent handled modes for denormal (aka subnormal) modes in the floating
-/// point environment.
-enum class DenormalMode {
- Invalid = -1,
+/// Rounding mode.
+///
+/// Enumerates supported rounding modes, as well as some special values. The set
+/// of the modes must agree with IEEE-754, 4.3.1 and 4.3.2. The constants
+/// assigned to the IEEE rounding modes must agree with the values used by
+/// FLT_ROUNDS (C11, 5.2.4.2.2p8).
+///
+/// This value is packed into bitfield in some cases, including \c FPOptions, so
+/// the rounding mode values and the special value \c Dynamic must fit into the
+/// the bit field (now - 3 bits). The value \c Invalid is used only in values
+/// returned by intrinsics to indicate errors, it should never be stored as
+/// rounding mode value, so it does not need to fit the bit fields.
+///
+enum class RoundingMode : int8_t {
+ // Rounding mode defined in IEEE-754.
+ TowardZero = 0, ///< roundTowardZero.
+ NearestTiesToEven = 1, ///< roundTiesToEven.
+ TowardPositive = 2, ///< roundTowardPositive.
+ TowardNegative = 3, ///< roundTowardNegative.
+ NearestTiesToAway = 4, ///< roundTiesToAway.
- /// IEEE-754 denormal numbers preserved.
- IEEE,
+ // Special values.
+ Dynamic = 7, ///< Denotes mode unknown at compile time.
+ Invalid = -1 ///< Denotes invalid value.
+};
+
+/// Represent subnormal handling kind for floating point instruction inputs and
+/// outputs.
+struct DenormalMode {
+ /// Represent handled modes for denormal (aka subnormal) modes in the floating
+ /// point environment.
+ enum DenormalModeKind : int8_t {
+ Invalid = -1,
+
+ /// IEEE-754 denormal numbers preserved.
+ IEEE,
+
+ /// The sign of a flushed-to-zero number is preserved in the sign of 0
+ PreserveSign,
+
+ /// Denormals are flushed to positive zero.
+ PositiveZero
+ };
- /// The sign of a flushed-to-zero number is preserved in the sign of 0
- PreserveSign,
+ /// Denormal flushing mode for floating point instruction results in the
+ /// default floating point environment.
+ DenormalModeKind Output = DenormalModeKind::Invalid;
+
+ /// Denormal treatment kind for floating point instruction inputs in the
+ /// default floating-point environment. If this is not DenormalModeKind::IEEE,
+ /// floating-point instructions implicitly treat the input value as 0.
+ DenormalModeKind Input = DenormalModeKind::Invalid;
+
+ constexpr DenormalMode() = default;
+ constexpr DenormalMode(DenormalModeKind Out, DenormalModeKind In) :
+ Output(Out), Input(In) {}
+
+
+ static constexpr DenormalMode getInvalid() {
+ return DenormalMode(DenormalModeKind::Invalid, DenormalModeKind::Invalid);
+ }
- /// Denormals are flushed to positive zero.
- PositiveZero
+ static constexpr DenormalMode getIEEE() {
+ return DenormalMode(DenormalModeKind::IEEE, DenormalModeKind::IEEE);
+ }
+
+ static constexpr DenormalMode getPreserveSign() {
+ return DenormalMode(DenormalModeKind::PreserveSign,
+ DenormalModeKind::PreserveSign);
+ }
+
+ static constexpr DenormalMode getPositiveZero() {
+ return DenormalMode(DenormalModeKind::PositiveZero,
+ DenormalModeKind::PositiveZero);
+ }
+
+ bool operator==(DenormalMode Other) const {
+ return Output == Other.Output && Input == Other.Input;
+ }
+
+ bool operator!=(DenormalMode Other) const {
+ return !(*this == Other);
+ }
+
+ bool isSimple() const {
+ return Input == Output;
+ }
+
+ bool isValid() const {
+ return Output != DenormalModeKind::Invalid &&
+ Input != DenormalModeKind::Invalid;
+ }
+
+ inline void print(raw_ostream &OS) const;
+
+ inline std::string str() const {
+ std::string storage;
+ raw_string_ostream OS(storage);
+ print(OS);
+ return OS.str();
+ }
};
+inline raw_ostream& operator<<(raw_ostream &OS, DenormalMode Mode) {
+ Mode.print(OS);
+ return OS;
+}
+
/// Parse the expected names from the denormal-fp-math attribute.
-inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
+inline DenormalMode::DenormalModeKind
+parseDenormalFPAttributeComponent(StringRef Str) {
// Assume ieee on unspecified attribute.
- return StringSwitch<DenormalMode>(Str)
+ return StringSwitch<DenormalMode::DenormalModeKind>(Str)
.Cases("", "ieee", DenormalMode::IEEE)
.Case("preserve-sign", DenormalMode::PreserveSign)
.Case("positive-zero", DenormalMode::PositiveZero)
@@ -44,7 +139,7 @@ inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
/// Return the name used for the denormal handling mode used by the the
/// expected names from the denormal-fp-math attribute.
-inline StringRef denormalModeName(DenormalMode Mode) {
+inline StringRef denormalModeKindName(DenormalMode::DenormalModeKind Mode) {
switch (Mode) {
case DenormalMode::IEEE:
return "ieee";
@@ -57,6 +152,26 @@ inline StringRef denormalModeName(DenormalMode Mode) {
}
}
+/// Returns the denormal mode to use for inputs and outputs.
+inline DenormalMode parseDenormalFPAttribute(StringRef Str) {
+ StringRef OutputStr, InputStr;
+ std::tie(OutputStr, InputStr) = Str.split(',');
+
+ DenormalMode Mode;
+ Mode.Output = parseDenormalFPAttributeComponent(OutputStr);
+
+ // Maintain compatability with old form of the attribute which only specified
+ // one component.
+ Mode.Input = InputStr.empty() ? Mode.Output :
+ parseDenormalFPAttributeComponent(InputStr);
+
+ return Mode;
+}
+
+void DenormalMode::print(raw_ostream &OS) const {
+ OS << denormalModeKindName(Output) << ',' << denormalModeKindName(Input);
+}
+
}
#endif // LLVM_FLOATINGPOINTMODE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/FoldingSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/FoldingSet.h
index 4968b1ea7780..fb1cb03a4b5c 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/FoldingSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/FoldingSet.h
@@ -110,8 +110,6 @@ class StringRef;
/// back to the bucket to facilitate node removal.
///
class FoldingSetBase {
- virtual void anchor(); // Out of line virtual method.
-
protected:
/// Buckets - Array of bucket chains.
void **Buckets;
@@ -154,11 +152,6 @@ public:
/// empty - Returns true if there are no nodes in the folding set.
bool empty() const { return NumNodes == 0; }
- /// reserve - Increase the number of buckets such that adding the
- /// EltCount-th node won't cause a rebucket operation. reserve is permitted
- /// to allocate more space than requested by EltCount.
- void reserve(unsigned EltCount);
-
/// capacity - Returns the number of nodes permitted in the folding set
/// before a rebucket operation is performed.
unsigned capacity() {
@@ -167,32 +160,46 @@ public:
return NumBuckets * 2;
}
+protected:
+ /// Functions provided by the derived class to compute folding properties.
+ /// This is effectively a vtable for FoldingSetBase, except that we don't
+ /// actually store a pointer to it in the object.
+ struct FoldingSetInfo {
+ /// GetNodeProfile - Instantiations of the FoldingSet template implement
+ /// this function to gather data bits for the given node.
+ void (*GetNodeProfile)(const FoldingSetBase *Self, Node *N,
+ FoldingSetNodeID &ID);
+
+ /// NodeEquals - Instantiations of the FoldingSet template implement
+ /// this function to compare the given node with the given ID.
+ bool (*NodeEquals)(const FoldingSetBase *Self, Node *N,
+ const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID);
+
+ /// ComputeNodeHash - Instantiations of the FoldingSet template implement
+ /// this function to compute a hash value for the given node.
+ unsigned (*ComputeNodeHash)(const FoldingSetBase *Self, Node *N,
+ FoldingSetNodeID &TempID);
+ };
+
private:
/// GrowHashTable - Double the size of the hash table and rehash everything.
- void GrowHashTable();
+ void GrowHashTable(const FoldingSetInfo &Info);
/// GrowBucketCount - resize the hash table and rehash everything.
/// NewBucketCount must be a power of two, and must be greater than the old
/// bucket count.
- void GrowBucketCount(unsigned NewBucketCount);
+ void GrowBucketCount(unsigned NewBucketCount, const FoldingSetInfo &Info);
protected:
- /// GetNodeProfile - Instantiations of the FoldingSet template implement
- /// this function to gather data bits for the given node.
- virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
-
- /// NodeEquals - Instantiations of the FoldingSet template implement
- /// this function to compare the given node with the given ID.
- virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
- FoldingSetNodeID &TempID) const=0;
-
- /// ComputeNodeHash - Instantiations of the FoldingSet template implement
- /// this function to compute a hash value for the given node.
- virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
-
// The below methods are protected to encourage subclasses to provide a more
// type-safe API.
+ /// reserve - Increase the number of buckets such that adding the
+ /// EltCount-th node won't cause a rebucket operation. reserve is permitted
+ /// to allocate more space than requested by EltCount.
+ void reserve(unsigned EltCount, const FoldingSetInfo &Info);
+
/// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set.
bool RemoveNode(Node *N);
@@ -200,17 +207,18 @@ protected:
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and return
/// it instead.
- Node *GetOrInsertNode(Node *N);
+ Node *GetOrInsertNode(Node *N, const FoldingSetInfo &Info);
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
- Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
+ Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos,
+ const FoldingSetInfo &Info);
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos.
- void InsertNode(Node *N, void *InsertPos);
+ void InsertNode(Node *N, void *InsertPos, const FoldingSetInfo &Info);
};
//===----------------------------------------------------------------------===//
@@ -397,7 +405,7 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
//===----------------------------------------------------------------------===//
/// FoldingSetImpl - An implementation detail that lets us share code between
/// FoldingSet and ContextualFoldingSet.
-template <class T> class FoldingSetImpl : public FoldingSetBase {
+template <class Derived, class T> class FoldingSetImpl : public FoldingSetBase {
protected:
explicit FoldingSetImpl(unsigned Log2InitSize)
: FoldingSetBase(Log2InitSize) {}
@@ -427,29 +435,40 @@ public:
return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
}
+ /// reserve - Increase the number of buckets such that adding the
+ /// EltCount-th node won't cause a rebucket operation. reserve is permitted
+ /// to allocate more space than requested by EltCount.
+ void reserve(unsigned EltCount) {
+ return FoldingSetBase::reserve(EltCount, Derived::getFoldingSetInfo());
+ }
+
/// RemoveNode - Remove a node from the folding set, returning true if one
/// was removed or false if the node was not in the folding set.
- bool RemoveNode(T *N) { return FoldingSetBase::RemoveNode(N); }
+ bool RemoveNode(T *N) {
+ return FoldingSetBase::RemoveNode(N);
+ }
/// GetOrInsertNode - If there is an existing simple Node exactly
/// equal to the specified node, return it. Otherwise, insert 'N' and
/// return it instead.
T *GetOrInsertNode(T *N) {
- return static_cast<T *>(FoldingSetBase::GetOrInsertNode(N));
+ return static_cast<T *>(
+ FoldingSetBase::GetOrInsertNode(N, Derived::getFoldingSetInfo()));
}
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
- return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(ID, InsertPos));
+ return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(
+ ID, InsertPos, Derived::getFoldingSetInfo()));
}
/// InsertNode - Insert the specified node into the folding set, knowing that
/// it is not already in the folding set. InsertPos must be obtained from
/// FindNodeOrInsertPos.
void InsertNode(T *N, void *InsertPos) {
- FoldingSetBase::InsertNode(N, InsertPos);
+ FoldingSetBase::InsertNode(N, InsertPos, Derived::getFoldingSetInfo());
}
/// InsertNode - Insert the specified node into the folding set, knowing that
@@ -470,32 +489,43 @@ public:
/// moved-from state is not a valid state for anything other than
/// move-assigning and destroying. This is primarily to enable movable APIs
/// that incorporate these objects.
-template <class T> class FoldingSet final : public FoldingSetImpl<T> {
- using Super = FoldingSetImpl<T>;
+template <class T>
+class FoldingSet : public FoldingSetImpl<FoldingSet<T>, T> {
+ using Super = FoldingSetImpl<FoldingSet, T>;
using Node = typename Super::Node;
- /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// GetNodeProfile - Each instantiation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
- void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
+ static void GetNodeProfile(const FoldingSetBase *, Node *N,
+ FoldingSetNodeID &ID) {
T *TN = static_cast<T *>(N);
FoldingSetTrait<T>::Profile(*TN, ID);
}
/// NodeEquals - Instantiations may optionally provide a way to compare a
/// node with a specified ID.
- bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
- FoldingSetNodeID &TempID) const override {
+ static bool NodeEquals(const FoldingSetBase *, Node *N,
+ const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
}
/// ComputeNodeHash - Instantiations may optionally provide a way to compute a
/// hash value directly from a node.
- unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
+ static unsigned ComputeNodeHash(const FoldingSetBase *, Node *N,
+ FoldingSetNodeID &TempID) {
T *TN = static_cast<T *>(N);
return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
}
+ static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
+ static constexpr FoldingSetBase::FoldingSetInfo Info = {
+ GetNodeProfile, NodeEquals, ComputeNodeHash};
+ return Info;
+ }
+ friend Super;
+
public:
explicit FoldingSet(unsigned Log2InitSize = 6) : Super(Log2InitSize) {}
FoldingSet(FoldingSet &&Arg) = default;
@@ -512,35 +542,51 @@ public:
/// function with signature
/// void Profile(FoldingSetNodeID &, Ctx);
template <class T, class Ctx>
-class ContextualFoldingSet final : public FoldingSetImpl<T> {
+class ContextualFoldingSet
+ : public FoldingSetImpl<ContextualFoldingSet<T, Ctx>, T> {
// Unfortunately, this can't derive from FoldingSet<T> because the
// construction of the vtable for FoldingSet<T> requires
// FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
// requires a single-argument T::Profile().
- using Super = FoldingSetImpl<T>;
+ using Super = FoldingSetImpl<ContextualFoldingSet, T>;
using Node = typename Super::Node;
Ctx Context;
+ static const Ctx &getContext(const FoldingSetBase *Base) {
+ return static_cast<const ContextualFoldingSet*>(Base)->Context;
+ }
+
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
- void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const override {
+ static void GetNodeProfile(const FoldingSetBase *Base, Node *N,
+ FoldingSetNodeID &ID) {
T *TN = static_cast<T *>(N);
- ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, Context);
+ ContextualFoldingSetTrait<T, Ctx>::Profile(*TN, ID, getContext(Base));
}
- bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
- FoldingSetNodeID &TempID) const override {
+ static bool NodeEquals(const FoldingSetBase *Base, Node *N,
+ const FoldingSetNodeID &ID, unsigned IDHash,
+ FoldingSetNodeID &TempID) {
T *TN = static_cast<T *>(N);
return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
- Context);
+ getContext(Base));
}
- unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const override {
+ static unsigned ComputeNodeHash(const FoldingSetBase *Base, Node *N,
+ FoldingSetNodeID &TempID) {
T *TN = static_cast<T *>(N);
- return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
+ return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID,
+ getContext(Base));
+ }
+
+ static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
+ static constexpr FoldingSetBase::FoldingSetInfo Info = {
+ GetNodeProfile, NodeEquals, ComputeNodeHash};
+ return Info;
}
+ friend Super;
public:
explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h b/contrib/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h
index 121aa527a5da..4c75e4d2547b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/FunctionExtras.h
@@ -11,11 +11,11 @@
/// in `<function>`.
///
/// It provides `unique_function`, which works like `std::function` but supports
-/// move-only callable objects.
+/// move-only callable objects and const-qualification.
///
/// Future plans:
-/// - Add a `function` that provides const, volatile, and ref-qualified support,
-/// which doesn't work with `std::function`.
+/// - Add a `function` that provides ref-qualified support, which doesn't work
+/// with `std::function`.
/// - Provide support for specifying multiple signatures to type erase callable
/// objects with an overload set, such as those produced by generic lambdas.
/// - Expand to include a copyable utility that directly replaces std::function
@@ -34,15 +34,34 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/type_traits.h"
#include <memory>
+#include <type_traits>
namespace llvm {
+/// unique_function is a type-erasing functor similar to std::function.
+///
+/// It can hold move-only function objects, like lambdas capturing unique_ptrs.
+/// Accordingly, it is movable but not copyable.
+///
+/// It supports const-qualification:
+/// - unique_function<int() const> has a const operator().
+/// It can only hold functions which themselves have a const operator().
+/// - unique_function<int()> has a non-const operator().
+/// It can hold functions with a non-const operator(), like mutable lambdas.
template <typename FunctionT> class unique_function;
-template <typename ReturnT, typename... ParamTs>
-class unique_function<ReturnT(ParamTs...)> {
+namespace detail {
+
+template <typename T>
+using EnableIfTrivial =
+ std::enable_if_t<llvm::is_trivially_move_constructible<T>::value &&
+ std::is_trivially_destructible<T>::value>;
+
+template <typename ReturnT, typename... ParamTs> class UniqueFunctionBase {
+protected:
static constexpr size_t InlineStorageSize = sizeof(void *) * 3;
// MSVC has a bug and ICEs if we give it a particular dependent value
@@ -112,8 +131,11 @@ class unique_function<ReturnT(ParamTs...)> {
// For in-line storage, we just provide an aligned character buffer. We
// provide three pointers worth of storage here.
- typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type
- InlineStorage;
+ // This is mutable as an inlined `const unique_function<void() const>` may
+ // still modify its own mutable members.
+ mutable
+ typename std::aligned_storage<InlineStorageSize, alignof(void *)>::type
+ InlineStorage;
} StorageUnion;
// A compressed pointer to either our dispatching callback or our table of
@@ -136,11 +158,25 @@ class unique_function<ReturnT(ParamTs...)> {
.template get<NonTrivialCallbacks *>();
}
- void *getInlineStorage() { return &StorageUnion.InlineStorage; }
+ CallPtrT getCallPtr() const {
+ return isTrivialCallback() ? getTrivialCallback()
+ : getNonTrivialCallbacks()->CallPtr;
+ }
- void *getOutOfLineStorage() {
+ // These three functions are only const in the narrow sense. They return
+ // mutable pointers to function state.
+ // This allows unique_function<T const>::operator() to be const, even if the
+ // underlying functor may be internally mutable.
+ //
+ // const callers must ensure they're only used in const-correct ways.
+ void *getCalleePtr() const {
+ return isInlineStorage() ? getInlineStorage() : getOutOfLineStorage();
+ }
+ void *getInlineStorage() const { return &StorageUnion.InlineStorage; }
+ void *getOutOfLineStorage() const {
return StorageUnion.OutOfLineStorage.StoragePtr;
}
+
size_t getOutOfLineStorageSize() const {
return StorageUnion.OutOfLineStorage.Size;
}
@@ -152,10 +188,11 @@ class unique_function<ReturnT(ParamTs...)> {
StorageUnion.OutOfLineStorage = {Ptr, Size, Alignment};
}
- template <typename CallableT>
- static ReturnT CallImpl(void *CallableAddr, AdjustedParamT<ParamTs>... Params) {
- return (*reinterpret_cast<CallableT *>(CallableAddr))(
- std::forward<ParamTs>(Params)...);
+ template <typename CalledAsT>
+ static ReturnT CallImpl(void *CallableAddr,
+ AdjustedParamT<ParamTs>... Params) {
+ auto &Func = *reinterpret_cast<CalledAsT *>(CallableAddr);
+ return Func(std::forward<ParamTs>(Params)...);
}
template <typename CallableT>
@@ -169,11 +206,54 @@ class unique_function<ReturnT(ParamTs...)> {
reinterpret_cast<CallableT *>(CallableAddr)->~CallableT();
}
-public:
- unique_function() = default;
- unique_function(std::nullptr_t /*null_callable*/) {}
+ // The pointers to call/move/destroy functions are determined for each
+ // callable type (and called-as type, which determines the overload chosen).
+ // (definitions are out-of-line).
+
+ // By default, we need an object that contains all the different
+ // type erased behaviors needed. Create a static instance of the struct type
+ // here and each instance will contain a pointer to it.
+ // Wrap in a struct to avoid https://gcc.gnu.org/PR71954
+ template <typename CallableT, typename CalledAs, typename Enable = void>
+ struct CallbacksHolder {
+ static NonTrivialCallbacks Callbacks;
+ };
+ // See if we can create a trivial callback. We need the callable to be
+ // trivially moved and trivially destroyed so that we don't have to store
+ // type erased callbacks for those operations.
+ template <typename CallableT, typename CalledAs>
+ struct CallbacksHolder<CallableT, CalledAs, EnableIfTrivial<CallableT>> {
+ static TrivialCallback Callbacks;
+ };
+
+ // A simple tag type so the call-as type to be passed to the constructor.
+ template <typename T> struct CalledAs {};
+
+ // Essentially the "main" unique_function constructor, but subclasses
+ // provide the qualified type to be used for the call.
+ // (We always store a T, even if the call will use a pointer to const T).
+ template <typename CallableT, typename CalledAsT>
+ UniqueFunctionBase(CallableT Callable, CalledAs<CalledAsT>) {
+ bool IsInlineStorage = true;
+ void *CallableAddr = getInlineStorage();
+ if (sizeof(CallableT) > InlineStorageSize ||
+ alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
+ IsInlineStorage = false;
+ // Allocate out-of-line storage. FIXME: Use an explicit alignment
+ // parameter in C++17 mode.
+ auto Size = sizeof(CallableT);
+ auto Alignment = alignof(CallableT);
+ CallableAddr = allocate_buffer(Size, Alignment);
+ setOutOfLineStorage(CallableAddr, Size, Alignment);
+ }
+
+ // Now move into the storage.
+ new (CallableAddr) CallableT(std::move(Callable));
+ CallbackAndInlineFlag.setPointerAndInt(
+ &CallbacksHolder<CallableT, CalledAsT>::Callbacks, IsInlineStorage);
+ }
- ~unique_function() {
+ ~UniqueFunctionBase() {
if (!CallbackAndInlineFlag.getPointer())
return;
@@ -189,7 +269,7 @@ public:
getOutOfLineStorageAlignment());
}
- unique_function(unique_function &&RHS) noexcept {
+ UniqueFunctionBase(UniqueFunctionBase &&RHS) noexcept {
// Copy the callback and inline flag.
CallbackAndInlineFlag = RHS.CallbackAndInlineFlag;
@@ -218,72 +298,83 @@ public:
#endif
}
- unique_function &operator=(unique_function &&RHS) noexcept {
+ UniqueFunctionBase &operator=(UniqueFunctionBase &&RHS) noexcept {
if (this == &RHS)
return *this;
// Because we don't try to provide any exception safety guarantees we can
// implement move assignment very simply by first destroying the current
// object and then move-constructing over top of it.
- this->~unique_function();
- new (this) unique_function(std::move(RHS));
+ this->~UniqueFunctionBase();
+ new (this) UniqueFunctionBase(std::move(RHS));
return *this;
}
- template <typename CallableT> unique_function(CallableT Callable) {
- bool IsInlineStorage = true;
- void *CallableAddr = getInlineStorage();
- if (sizeof(CallableT) > InlineStorageSize ||
- alignof(CallableT) > alignof(decltype(StorageUnion.InlineStorage))) {
- IsInlineStorage = false;
- // Allocate out-of-line storage. FIXME: Use an explicit alignment
- // parameter in C++17 mode.
- auto Size = sizeof(CallableT);
- auto Alignment = alignof(CallableT);
- CallableAddr = allocate_buffer(Size, Alignment);
- setOutOfLineStorage(CallableAddr, Size, Alignment);
- }
+ UniqueFunctionBase() = default;
- // Now move into the storage.
- new (CallableAddr) CallableT(std::move(Callable));
+public:
+ explicit operator bool() const {
+ return (bool)CallbackAndInlineFlag.getPointer();
+ }
+};
- // See if we can create a trivial callback. We need the callable to be
- // trivially moved and trivially destroyed so that we don't have to store
- // type erased callbacks for those operations.
- //
- // FIXME: We should use constexpr if here and below to avoid instantiating
- // the non-trivial static objects when unnecessary. While the linker should
- // remove them, it is still wasteful.
- if (llvm::is_trivially_move_constructible<CallableT>::value &&
- std::is_trivially_destructible<CallableT>::value) {
- // We need to create a nicely aligned object. We use a static variable
- // for this because it is a trivial struct.
- static TrivialCallback Callback = { &CallImpl<CallableT> };
-
- CallbackAndInlineFlag = {&Callback, IsInlineStorage};
- return;
- }
+template <typename R, typename... P>
+template <typename CallableT, typename CalledAsT, typename Enable>
+typename UniqueFunctionBase<R, P...>::NonTrivialCallbacks UniqueFunctionBase<
+ R, P...>::CallbacksHolder<CallableT, CalledAsT, Enable>::Callbacks = {
+ &CallImpl<CalledAsT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
- // Otherwise, we need to point at an object that contains all the different
- // type erased behaviors needed. Create a static instance of the struct type
- // here and then use a pointer to that.
- static NonTrivialCallbacks Callbacks = {
- &CallImpl<CallableT>, &MoveImpl<CallableT>, &DestroyImpl<CallableT>};
+template <typename R, typename... P>
+template <typename CallableT, typename CalledAsT>
+typename UniqueFunctionBase<R, P...>::TrivialCallback
+ UniqueFunctionBase<R, P...>::CallbacksHolder<
+ CallableT, CalledAsT, EnableIfTrivial<CallableT>>::Callbacks{
+ &CallImpl<CalledAsT>};
- CallbackAndInlineFlag = {&Callbacks, IsInlineStorage};
- }
+} // namespace detail
+
+template <typename R, typename... P>
+class unique_function<R(P...)> : public detail::UniqueFunctionBase<R, P...> {
+ using Base = detail::UniqueFunctionBase<R, P...>;
+
+public:
+ unique_function() = default;
+ unique_function(std::nullptr_t) {}
+ unique_function(unique_function &&) = default;
+ unique_function(const unique_function &) = delete;
+ unique_function &operator=(unique_function &&) = default;
+ unique_function &operator=(const unique_function &) = delete;
- ReturnT operator()(ParamTs... Params) {
- void *CallableAddr =
- isInlineStorage() ? getInlineStorage() : getOutOfLineStorage();
+ template <typename CallableT>
+ unique_function(CallableT Callable)
+ : Base(std::forward<CallableT>(Callable),
+ typename Base::template CalledAs<CallableT>{}) {}
- return (isTrivialCallback()
- ? getTrivialCallback()
- : getNonTrivialCallbacks()->CallPtr)(CallableAddr, Params...);
+ R operator()(P... Params) {
+ return this->getCallPtr()(this->getCalleePtr(), Params...);
}
+};
- explicit operator bool() const {
- return (bool)CallbackAndInlineFlag.getPointer();
+template <typename R, typename... P>
+class unique_function<R(P...) const>
+ : public detail::UniqueFunctionBase<R, P...> {
+ using Base = detail::UniqueFunctionBase<R, P...>;
+
+public:
+ unique_function() = default;
+ unique_function(std::nullptr_t) {}
+ unique_function(unique_function &&) = default;
+ unique_function(const unique_function &) = delete;
+ unique_function &operator=(unique_function &&) = default;
+ unique_function &operator=(const unique_function &) = delete;
+
+ template <typename CallableT>
+ unique_function(CallableT Callable)
+ : Base(std::forward<CallableT>(Callable),
+ typename Base::template CalledAs<const CallableT>{}) {}
+
+ R operator()(P... Params) const {
+ return this->getCallPtr()(this->getCalleePtr(), Params...);
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Hashing.h b/contrib/llvm-project/llvm/include/llvm/ADT/Hashing.h
index adcc5cf54da9..9ee310c879fd 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/Hashing.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Hashing.h
@@ -101,8 +101,7 @@ public:
/// differing argument types even if they would implicit promote to a common
/// type without changing the value.
template <typename T>
-typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
-hash_value(T value);
+std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value);
/// Compute a hash_code for a pointer's address.
///
@@ -158,10 +157,10 @@ inline uint32_t fetch32(const char *p) {
}
/// Some primes between 2^63 and 2^64 for various uses.
-static const uint64_t k0 = 0xc3a5c85c97cb3127ULL;
-static const uint64_t k1 = 0xb492b66fbe98f273ULL;
-static const uint64_t k2 = 0x9ae16a3b2f90404fULL;
-static const uint64_t k3 = 0xc949d7c7509e6557ULL;
+static constexpr uint64_t k0 = 0xc3a5c85c97cb3127ULL;
+static constexpr uint64_t k1 = 0xb492b66fbe98f273ULL;
+static constexpr uint64_t k2 = 0x9ae16a3b2f90404fULL;
+static constexpr uint64_t k3 = 0xc949d7c7509e6557ULL;
/// Bitwise right rotate.
/// Normally this will compile to a single instruction, especially if the
@@ -360,7 +359,7 @@ template <typename T, typename U> struct is_hashable_data<std::pair<T, U> >
/// Helper to get the hashable data representation for a type.
/// This variant is enabled when the type itself can be used.
template <typename T>
-typename std::enable_if<is_hashable_data<T>::value, T>::type
+std::enable_if_t<is_hashable_data<T>::value, T>
get_hashable_data(const T &value) {
return value;
}
@@ -368,7 +367,7 @@ get_hashable_data(const T &value) {
/// This variant is enabled when we must first call hash_value and use the
/// result as our data.
template <typename T>
-typename std::enable_if<!is_hashable_data<T>::value, size_t>::type
+std::enable_if_t<!is_hashable_data<T>::value, size_t>
get_hashable_data(const T &value) {
using ::llvm::hash_value;
return hash_value(value);
@@ -442,7 +441,7 @@ hash_code hash_combine_range_impl(InputIteratorT first, InputIteratorT last) {
/// are stored in contiguous memory, this routine avoids copying each value
/// and directly reads from the underlying memory.
template <typename ValueT>
-typename std::enable_if<is_hashable_data<ValueT>::value, hash_code>::type
+std::enable_if_t<is_hashable_data<ValueT>::value, hash_code>
hash_combine_range_impl(ValueT *first, ValueT *last) {
const uint64_t seed = get_execution_seed();
const char *s_begin = reinterpret_cast<const char *>(first);
@@ -627,8 +626,7 @@ inline hash_code hash_integer_value(uint64_t value) {
// Declared and documented above, but defined here so that any of the hashing
// infrastructure is available.
template <typename T>
-typename std::enable_if<is_integral_or_enum<T>::value, hash_code>::type
-hash_value(T value) {
+std::enable_if_t<is_integral_or_enum<T>::value, hash_code> hash_value(T value) {
return ::llvm::hashing::detail::hash_integer_value(
static_cast<uint64_t>(value));
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableMap.h b/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableMap.h
index 86fd7fefaec3..30689d2274a8 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableMap.h
@@ -70,33 +70,14 @@ public:
using TreeTy = ImutAVLTree<ValInfo>;
protected:
- TreeTy* Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
public:
/// Constructs a map from a pointer to a tree root. In general one
/// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableMap(const TreeTy* R) : Root(const_cast<TreeTy*>(R)) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableMap(const ImmutableMap &X) : Root(X.Root) {
- if (Root) { Root->retain(); }
- }
-
- ~ImmutableMap() {
- if (Root) { Root->release(); }
- }
-
- ImmutableMap &operator=(const ImmutableMap &X) {
- if (Root != X.Root) {
- if (X.Root) { X.Root->retain(); }
- if (Root) { Root->release(); }
- Root = X.Root;
- }
- return *this;
- }
+ explicit ImmutableMap(const TreeTy *R) : Root(const_cast<TreeTy *>(R)) {}
class Factory {
typename TreeTy::Factory F;
@@ -115,12 +96,12 @@ public:
LLVM_NODISCARD ImmutableMap add(ImmutableMap Old, key_type_ref K,
data_type_ref D) {
- TreeTy *T = F.add(Old.Root, std::pair<key_type,data_type>(K,D));
+ TreeTy *T = F.add(Old.Root.get(), std::pair<key_type, data_type>(K, D));
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
LLVM_NODISCARD ImmutableMap remove(ImmutableMap Old, key_type_ref K) {
- TreeTy *T = F.remove(Old.Root,K);
+ TreeTy *T = F.remove(Old.Root.get(), K);
return ImmutableMap(Canonicalize ? F.getCanonicalTree(T): T);
}
@@ -134,19 +115,20 @@ public:
}
bool operator==(const ImmutableMap &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableMap &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
TreeTy *getRoot() const {
if (Root) { Root->retain(); }
- return Root;
+ return Root.get();
}
- TreeTy *getRootWithoutRetain() const { return Root; }
+ TreeTy *getRootWithoutRetain() const { return Root.get(); }
void manualRetain() {
if (Root) Root->retain();
@@ -217,7 +199,7 @@ public:
data_type_ref getData() const { return (*this)->second; }
};
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
data_type* lookup(key_type_ref K) const {
@@ -243,7 +225,7 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static inline void Profile(FoldingSetNodeID& ID, const ImmutableMap& M) {
- ID.AddPointer(M.Root);
+ ID.AddPointer(M.Root.get());
}
inline void Profile(FoldingSetNodeID& ID) const {
@@ -266,7 +248,7 @@ public:
using FactoryTy = typename TreeTy::Factory;
protected:
- TreeTy *Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
FactoryTy *Factory;
public:
@@ -274,44 +256,12 @@ public:
/// should use a Factory object to create maps instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableMapRef(const TreeTy *R, FactoryTy *F)
- : Root(const_cast<TreeTy *>(R)), Factory(F) {
- if (Root) {
- Root->retain();
- }
- }
+ ImmutableMapRef(const TreeTy *R, FactoryTy *F)
+ : Root(const_cast<TreeTy *>(R)), Factory(F) {}
- explicit ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
- typename ImmutableMap<KeyT, ValT>::Factory &F)
- : Root(X.getRootWithoutRetain()),
- Factory(F.getTreeFactory()) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableMapRef(const ImmutableMapRef &X) : Root(X.Root), Factory(X.Factory) {
- if (Root) {
- Root->retain();
- }
- }
-
- ~ImmutableMapRef() {
- if (Root)
- Root->release();
- }
-
- ImmutableMapRef &operator=(const ImmutableMapRef &X) {
- if (Root != X.Root) {
- if (X.Root)
- X.Root->retain();
-
- if (Root)
- Root->release();
-
- Root = X.Root;
- Factory = X.Factory;
- }
- return *this;
- }
+ ImmutableMapRef(const ImmutableMap<KeyT, ValT> &X,
+ typename ImmutableMap<KeyT, ValT>::Factory &F)
+ : Root(X.getRootWithoutRetain()), Factory(F.getTreeFactory()) {}
static inline ImmutableMapRef getEmptyMap(FactoryTy *F) {
return ImmutableMapRef(0, F);
@@ -326,12 +276,13 @@ public:
}
ImmutableMapRef add(key_type_ref K, data_type_ref D) const {
- TreeTy *NewT = Factory->add(Root, std::pair<key_type, data_type>(K, D));
+ TreeTy *NewT =
+ Factory->add(Root.get(), std::pair<key_type, data_type>(K, D));
return ImmutableMapRef(NewT, Factory);
}
ImmutableMapRef remove(key_type_ref K) const {
- TreeTy *NewT = Factory->remove(Root, K);
+ TreeTy *NewT = Factory->remove(Root.get(), K);
return ImmutableMapRef(NewT, Factory);
}
@@ -340,15 +291,16 @@ public:
}
ImmutableMap<KeyT, ValT> asImmutableMap() const {
- return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root));
+ return ImmutableMap<KeyT, ValT>(Factory->getCanonicalTree(Root.get()));
}
bool operator==(const ImmutableMapRef &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableMapRef &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
bool isEmpty() const { return !Root; }
@@ -377,7 +329,7 @@ public:
data_type_ref getData() const { return (*this)->second; }
};
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
data_type *lookup(key_type_ref K) const {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableSet.h
index a6a6abfd9600..f19913f8dcdd 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ImmutableSet.h
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Allocator.h"
@@ -169,7 +170,7 @@ public:
bool contains(key_type_ref K) { return (bool) find(K); }
/// foreach - A member template the accepts invokes operator() on a functor
- /// object (specifed by Callback) for every node/subtree in the tree.
+ /// object (specified by Callback) for every node/subtree in the tree.
/// Nodes are visited using an inorder traversal.
template <typename Callback>
void foreach(Callback& C) {
@@ -183,7 +184,7 @@ public:
}
/// validateTree - A utility method that checks that the balancing and
- /// ordering invariants of the tree are satisifed. It is a recursive
+ /// ordering invariants of the tree are satisfied. It is a recursive
/// method that returns the height of the tree, which is then consumed
/// by the enclosing validateTree call. External callers should ignore the
/// return value. An invalid tree will cause an assertion to fire in
@@ -357,6 +358,12 @@ public:
}
};
+template <typename ImutInfo>
+struct IntrusiveRefCntPtrInfo<ImutAVLTree<ImutInfo>> {
+ static void retain(ImutAVLTree<ImutInfo> *Tree) { Tree->retain(); }
+ static void release(ImutAVLTree<ImutInfo> *Tree) { Tree->release(); }
+};
+
//===----------------------------------------------------------------------===//
// Immutable AVL-Tree Factory class.
//===----------------------------------------------------------------------===//
@@ -450,7 +457,7 @@ protected:
//===--------------------------------------------------===//
// "createNode" is used to generate new tree roots that link
- // to other trees. The functon may also simply move links
+ // to other trees. The function may also simply move links
// in an existing root if that root is still marked mutable.
// This is necessary because otherwise our balancing code
// would leak memory as it would create nodes that are
@@ -961,33 +968,14 @@ public:
using TreeTy = ImutAVLTree<ValInfo>;
private:
- TreeTy *Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
public:
/// Constructs a set from a pointer to a tree root. In general one
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableSet(TreeTy* R) : Root(R) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableSet(const ImmutableSet &X) : Root(X.Root) {
- if (Root) { Root->retain(); }
- }
-
- ~ImmutableSet() {
- if (Root) { Root->release(); }
- }
-
- ImmutableSet &operator=(const ImmutableSet &X) {
- if (Root != X.Root) {
- if (X.Root) { X.Root->retain(); }
- if (Root) { Root->release(); }
- Root = X.Root;
- }
- return *this;
- }
+ explicit ImmutableSet(TreeTy *R) : Root(R) {}
class Factory {
typename TreeTy::Factory F;
@@ -1016,7 +1004,7 @@ public:
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
LLVM_NODISCARD ImmutableSet add(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.add(Old.Root, V);
+ TreeTy *NewT = F.add(Old.Root.get(), V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
@@ -1028,7 +1016,7 @@ public:
/// The memory allocated to represent the set is released when the
/// factory object that created the set is destroyed.
LLVM_NODISCARD ImmutableSet remove(ImmutableSet Old, value_type_ref V) {
- TreeTy *NewT = F.remove(Old.Root, V);
+ TreeTy *NewT = F.remove(Old.Root.get(), V);
return ImmutableSet(Canonicalize ? F.getCanonicalTree(NewT) : NewT);
}
@@ -1047,21 +1035,20 @@ public:
}
bool operator==(const ImmutableSet &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableSet &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
TreeTy *getRoot() {
if (Root) { Root->retain(); }
- return Root;
+ return Root.get();
}
- TreeTy *getRootWithoutRetain() const {
- return Root;
- }
+ TreeTy *getRootWithoutRetain() const { return Root.get(); }
/// isEmpty - Return true if the set contains no elements.
bool isEmpty() const { return !Root; }
@@ -1082,7 +1069,7 @@ public:
using iterator = ImutAVLValueIterator<ImmutableSet>;
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
@@ -1092,7 +1079,7 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) {
- ID.AddPointer(S.Root);
+ ID.AddPointer(S.Root.get());
}
void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
@@ -1114,7 +1101,7 @@ public:
using FactoryTy = typename TreeTy::Factory;
private:
- TreeTy *Root;
+ IntrusiveRefCntPtr<TreeTy> Root;
FactoryTy *Factory;
public:
@@ -1122,42 +1109,18 @@ public:
/// should use a Factory object to create sets instead of directly
/// invoking the constructor, but there are cases where make this
/// constructor public is useful.
- explicit ImmutableSetRef(TreeTy* R, FactoryTy *F)
- : Root(R),
- Factory(F) {
- if (Root) { Root->retain(); }
- }
-
- ImmutableSetRef(const ImmutableSetRef &X)
- : Root(X.Root),
- Factory(X.Factory) {
- if (Root) { Root->retain(); }
- }
-
- ~ImmutableSetRef() {
- if (Root) { Root->release(); }
- }
-
- ImmutableSetRef &operator=(const ImmutableSetRef &X) {
- if (Root != X.Root) {
- if (X.Root) { X.Root->retain(); }
- if (Root) { Root->release(); }
- Root = X.Root;
- Factory = X.Factory;
- }
- return *this;
- }
+ ImmutableSetRef(TreeTy *R, FactoryTy *F) : Root(R), Factory(F) {}
static ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
ImmutableSetRef add(value_type_ref V) {
- return ImmutableSetRef(Factory->add(Root, V), Factory);
+ return ImmutableSetRef(Factory->add(Root.get(), V), Factory);
}
ImmutableSetRef remove(value_type_ref V) {
- return ImmutableSetRef(Factory->remove(Root, V), Factory);
+ return ImmutableSetRef(Factory->remove(Root.get(), V), Factory);
}
/// Returns true if the set contains the specified value.
@@ -1166,20 +1129,19 @@ public:
}
ImmutableSet<ValT> asImmutableSet(bool canonicalize = true) const {
- return ImmutableSet<ValT>(canonicalize ?
- Factory->getCanonicalTree(Root) : Root);
+ return ImmutableSet<ValT>(
+ canonicalize ? Factory->getCanonicalTree(Root.get()) : Root.get());
}
- TreeTy *getRootWithoutRetain() const {
- return Root;
- }
+ TreeTy *getRootWithoutRetain() const { return Root.get(); }
bool operator==(const ImmutableSetRef &RHS) const {
- return Root && RHS.Root ? Root->isEqual(*RHS.Root) : Root == RHS.Root;
+ return Root && RHS.Root ? Root->isEqual(*RHS.Root.get()) : Root == RHS.Root;
}
bool operator!=(const ImmutableSetRef &RHS) const {
- return Root && RHS.Root ? Root->isNotEqual(*RHS.Root) : Root != RHS.Root;
+ return Root && RHS.Root ? Root->isNotEqual(*RHS.Root.get())
+ : Root != RHS.Root;
}
/// isEmpty - Return true if the set contains no elements.
@@ -1195,7 +1157,7 @@ public:
using iterator = ImutAVLValueIterator<ImmutableSetRef>;
- iterator begin() const { return iterator(Root); }
+ iterator begin() const { return iterator(Root.get()); }
iterator end() const { return iterator(); }
//===--------------------------------------------------===//
@@ -1205,7 +1167,7 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) {
- ID.AddPointer(S.Root);
+ ID.AddPointer(S.Root.get());
}
void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/IntervalMap.h b/contrib/llvm-project/llvm/include/llvm/ADT/IntervalMap.h
index a02876ee77f3..db7804d0a551 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/IntervalMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/IntervalMap.h
@@ -491,7 +491,7 @@ class NodeRef {
struct CacheAlignedPointerTraits {
static inline void *getAsVoidPointer(void *P) { return P; }
static inline void *getFromVoidPointer(void *P) { return P; }
- enum { NumLowBitsAvailable = Log2CacheLine };
+ static constexpr int NumLowBitsAvailable = Log2CacheLine;
};
PointerIntPair<void*, Log2CacheLine, unsigned, CacheAlignedPointerTraits> pip;
@@ -823,7 +823,7 @@ public:
}
/// reset - Reset cached information about node(Level) from subtree(Level -1).
- /// @param Level 1..height. THe node to update after parent node changed.
+ /// @param Level 1..height. The node to update after parent node changed.
void reset(unsigned Level) {
path[Level] = Entry(subtree(Level - 1), offset(Level));
}
@@ -884,7 +884,7 @@ public:
}
/// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
- /// @param Level Get the sinbling to node(Level).
+ /// @param Level Get the sibling to node(Level).
/// @return Left sibling, or NodeRef().
NodeRef getRightSibling(unsigned Level) const;
@@ -1396,7 +1396,7 @@ public:
setRoot(map->rootSize);
}
- /// preincrement - move to the next interval.
+ /// preincrement - Move to the next interval.
const_iterator &operator++() {
assert(valid() && "Cannot increment end()");
if (++path.leafOffset() == path.leafSize() && branched())
@@ -1404,14 +1404,14 @@ public:
return *this;
}
- /// postincrement - Dont do that!
+ /// postincrement - Don't do that!
const_iterator operator++(int) {
const_iterator tmp = *this;
operator++();
return tmp;
}
- /// predecrement - move to the previous interval.
+ /// predecrement - Move to the previous interval.
const_iterator &operator--() {
if (path.leafOffset() && (valid() || !branched()))
--path.leafOffset();
@@ -1420,7 +1420,7 @@ public:
return *this;
}
- /// postdecrement - Dont do that!
+ /// postdecrement - Don't do that!
const_iterator operator--(int) {
const_iterator tmp = *this;
operator--();
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Optional.h b/contrib/llvm-project/llvm/include/llvm/ADT/Optional.h
index c84f9aa8b342..c64b82352397 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/Optional.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Optional.h
@@ -269,7 +269,7 @@ public:
/// Apply a function to the value if present; otherwise return None.
template <class Function>
- auto map(const Function &F) const
+ auto map(const Function &F) const LLVM_LVALUE_FUNCTION
-> Optional<decltype(F(getValue()))> {
if (*this) return F(getValue());
return None;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PointerEmbeddedInt.h b/contrib/llvm-project/llvm/include/llvm/ADT/PointerEmbeddedInt.h
index 3eb6edb03430..fbc48af79da1 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PointerEmbeddedInt.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PointerEmbeddedInt.h
@@ -94,7 +94,7 @@ struct PointerLikeTypeTraits<PointerEmbeddedInt<IntT, Bits>> {
return T(reinterpret_cast<uintptr_t>(P), typename T::RawValueTag());
}
- enum { NumLowBitsAvailable = T::Shift };
+ static constexpr int NumLowBitsAvailable = T::Shift;
};
// Teach DenseMap how to use PointerEmbeddedInt objects as keys if the Int type
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h b/contrib/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h
index fa6bf1504469..cb8b202c48b7 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PointerIntPair.h
@@ -147,7 +147,7 @@ struct PointerIntPairInfo {
"cannot use a pointer type that has all bits free");
static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
"PointerIntPair with integer size too large for pointer");
- enum : uintptr_t {
+ enum MaskAndShiftConstants : uintptr_t {
/// PointerBitMask - The bits that come from the pointer.
PointerBitMask =
~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
@@ -235,7 +235,8 @@ struct PointerLikeTypeTraits<
return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
}
- enum { NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits };
+ static constexpr int NumLowBitsAvailable =
+ PtrTraits::NumLowBitsAvailable - IntBits;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PointerSumType.h b/contrib/llvm-project/llvm/include/llvm/ADT/PointerSumType.h
index d467f83f58ac..a7ef774e205e 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PointerSumType.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PointerSumType.h
@@ -214,7 +214,7 @@ struct PointerSumTypeHelper : MemberTs... {
LookupOverload(PointerSumTypeMember<N, PointerT, TraitsT> *);
template <TagT N> static void LookupOverload(...);
template <TagT N> struct Lookup {
- // Compute a particular member type by resolving the lookup helper ovorload.
+ // Compute a particular member type by resolving the lookup helper overload.
using MemberT = decltype(
LookupOverload<N>(static_cast<PointerSumTypeHelper *>(nullptr)));
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PointerUnion.h b/contrib/llvm-project/llvm/include/llvm/ADT/PointerUnion.h
index 40b7b000da40..6fecff8d756f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PointerUnion.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PointerUnion.h
@@ -181,7 +181,7 @@ public:
explicit operator bool() const { return !isNull(); }
/// Test if the Union currently holds the type matching T.
- template <typename T> int is() const {
+ template <typename T> bool is() const {
constexpr int Index = pointer_union_detail::TypeIndex<T, PTs...>::Index;
static_assert(Index < sizeof...(PTs),
"PointerUnion::is<T> given type not in the union");
@@ -197,7 +197,7 @@ public:
}
/// Returns the current pointer if it is of the specified pointer type,
- /// otherwises returns null.
+ /// otherwise returns null.
template <typename T> T dyn_cast() const {
if (is<T>())
return get<T>();
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PostOrderIterator.h b/contrib/llvm-project/llvm/include/llvm/ADT/PostOrderIterator.h
index 2fe7447a8e77..bb413a956d9f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PostOrderIterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PostOrderIterator.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
#include <iterator>
#include <set>
@@ -101,7 +102,7 @@ class po_iterator
// VisitStack - Used to maintain the ordering. Top = current block
// First element is basic block pointer, second is the 'next child' to visit
- std::vector<std::pair<NodeRef, ChildItTy>> VisitStack;
+ SmallVector<std::pair<NodeRef, ChildItTy>, 8> VisitStack;
po_iterator(NodeRef BB) {
this->insertEdge(Optional<NodeRef>(), BB);
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/PriorityWorklist.h b/contrib/llvm-project/llvm/include/llvm/ADT/PriorityWorklist.h
index 96d22c87557e..01dd59a2e71a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/PriorityWorklist.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/PriorityWorklist.h
@@ -110,7 +110,7 @@ public:
/// Insert a sequence of new elements into the PriorityWorklist.
template <typename SequenceT>
- typename std::enable_if<!std::is_convertible<SequenceT, T>::value>::type
+ std::enable_if_t<!std::is_convertible<SequenceT, T>::value>
insert(SequenceT &&Input) {
if (std::begin(Input) == std::end(Input))
// Nothing to do for an empty input sequence.
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SCCIterator.h b/contrib/llvm-project/llvm/include/llvm/ADT/SCCIterator.h
index 1e642b9f75d3..8a7c0a78a0fc 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SCCIterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SCCIterator.h
@@ -124,11 +124,11 @@ public:
return CurrentSCC;
}
- /// Test if the current SCC has a loop.
+ /// Test if the current SCC has a cycle.
///
/// If the SCC has more than one node, this is trivially true. If not, it may
- /// still contain a loop if the node has an edge back to itself.
- bool hasLoop() const;
+ /// still contain a cycle if the node has an edge back to itself.
+ bool hasCycle() const;
/// This informs the \c scc_iterator that the specified \c Old node
/// has been deleted, and \c New is to be used in its place.
@@ -212,7 +212,7 @@ template <class GraphT, class GT> void scc_iterator<GraphT, GT>::GetNextSCC() {
}
template <class GraphT, class GT>
-bool scc_iterator<GraphT, GT>::hasLoop() const {
+bool scc_iterator<GraphT, GT>::hasCycle() const {
assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
if (CurrentSCC.size() > 1)
return true;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h b/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h
index b61dab2459d1..50b688b36648 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/STLExtras.h
@@ -50,6 +50,10 @@ namespace detail {
template <typename RangeT>
using IterOfRange = decltype(std::begin(std::declval<RangeT &>()));
+template <typename RangeT>
+using ValueOfRange = typename std::remove_reference<decltype(
+ *std::begin(std::declval<RangeT &>()))>::type;
+
} // end namespace detail
//===----------------------------------------------------------------------===//
@@ -75,6 +79,79 @@ template <typename T> struct make_const_ref {
typename std::add_const<T>::type>::type;
};
+/// Utilities for detecting if a given trait holds for some set of arguments
+/// 'Args'. For example, the given trait could be used to detect if a given type
+/// has a copy assignment operator:
+/// template<class T>
+/// using has_copy_assign_t = decltype(std::declval<T&>()
+/// = std::declval<const T&>());
+/// bool fooHasCopyAssign = is_detected<has_copy_assign_t, FooClass>::value;
+namespace detail {
+template <typename...> using void_t = void;
+template <class, template <class...> class Op, class... Args> struct detector {
+ using value_t = std::false_type;
+};
+template <template <class...> class Op, class... Args>
+struct detector<void_t<Op<Args...>>, Op, Args...> {
+ using value_t = std::true_type;
+};
+} // end namespace detail
+
+template <template <class...> class Op, class... Args>
+using is_detected = typename detail::detector<void, Op, Args...>::value_t;
+
+/// Check if a Callable type can be invoked with the given set of arg types.
+namespace detail {
+template <typename Callable, typename... Args>
+using is_invocable =
+ decltype(std::declval<Callable &>()(std::declval<Args>()...));
+} // namespace detail
+
+template <typename Callable, typename... Args>
+using is_invocable = is_detected<detail::is_invocable, Callable, Args...>;
+
+/// This class provides various trait information about a callable object.
+/// * To access the number of arguments: Traits::num_args
+/// * To access the type of an argument: Traits::arg_t<Index>
+/// * To access the type of the result: Traits::result_t
+template <typename T, bool isClass = std::is_class<T>::value>
+struct function_traits : public function_traits<decltype(&T::operator())> {};
+
+/// Overload for class function types.
+template <typename ClassType, typename ReturnType, typename... Args>
+struct function_traits<ReturnType (ClassType::*)(Args...) const, false> {
+ /// The number of arguments to this function.
+ enum { num_args = sizeof...(Args) };
+
+ /// The result type of this function.
+ using result_t = ReturnType;
+
+ /// The type of an argument to this function.
+ template <size_t Index>
+ using arg_t = typename std::tuple_element<Index, std::tuple<Args...>>::type;
+};
+/// Overload for class function types.
+template <typename ClassType, typename ReturnType, typename... Args>
+struct function_traits<ReturnType (ClassType::*)(Args...), false>
+ : function_traits<ReturnType (ClassType::*)(Args...) const> {};
+/// Overload for non-class function types.
+template <typename ReturnType, typename... Args>
+struct function_traits<ReturnType (*)(Args...), false> {
+ /// The number of arguments to this function.
+ enum { num_args = sizeof...(Args) };
+
+ /// The result type of this function.
+ using result_t = ReturnType;
+
+ /// The type of an argument to this function.
+ template <size_t i>
+ using arg_t = typename std::tuple_element<i, std::tuple<Args...>>::type;
+};
+/// Overload for non-class function type references.
+template <typename ReturnType, typename... Args>
+struct function_traits<ReturnType (&)(Args...), false>
+ : public function_traits<ReturnType (*)(Args...)> {};
+
//===----------------------------------------------------------------------===//
// Extra additions to <functional>
//===----------------------------------------------------------------------===//
@@ -114,10 +191,11 @@ public:
function_ref(std::nullptr_t) {}
template <typename Callable>
- function_ref(Callable &&callable,
- typename std::enable_if<
- !std::is_same<typename std::remove_reference<Callable>::type,
- function_ref>::value>::type * = nullptr)
+ function_ref(
+ Callable &&callable,
+ std::enable_if_t<
+ !std::is_same<std::remove_cv_t<std::remove_reference_t<Callable>>,
+ function_ref>::value> * = nullptr)
: callback(callback_fn<typename std::remove_reference<Callable>::type>),
callable(reinterpret_cast<intptr_t>(&callable)) {}
@@ -125,7 +203,7 @@ public:
return callback(callable, std::forward<Params>(params)...);
}
- operator bool() const { return callback; }
+ explicit operator bool() const { return callback; }
};
// deleter - Very very very simple method that is used to invoke operator
@@ -146,16 +224,14 @@ namespace adl_detail {
using std::begin;
template <typename ContainerTy>
-auto adl_begin(ContainerTy &&container)
- -> decltype(begin(std::forward<ContainerTy>(container))) {
+decltype(auto) adl_begin(ContainerTy &&container) {
return begin(std::forward<ContainerTy>(container));
}
using std::end;
template <typename ContainerTy>
-auto adl_end(ContainerTy &&container)
- -> decltype(end(std::forward<ContainerTy>(container))) {
+decltype(auto) adl_end(ContainerTy &&container) {
return end(std::forward<ContainerTy>(container));
}
@@ -170,14 +246,12 @@ void adl_swap(T &&lhs, T &&rhs) noexcept(noexcept(swap(std::declval<T>(),
} // end namespace adl_detail
template <typename ContainerTy>
-auto adl_begin(ContainerTy &&container)
- -> decltype(adl_detail::adl_begin(std::forward<ContainerTy>(container))) {
+decltype(auto) adl_begin(ContainerTy &&container) {
return adl_detail::adl_begin(std::forward<ContainerTy>(container));
}
template <typename ContainerTy>
-auto adl_end(ContainerTy &&container)
- -> decltype(adl_detail::adl_end(std::forward<ContainerTy>(container))) {
+decltype(auto) adl_end(ContainerTy &&container) {
return adl_detail::adl_end(std::forward<ContainerTy>(container));
}
@@ -193,11 +267,15 @@ constexpr bool empty(const T &RangeOrContainer) {
return adl_begin(RangeOrContainer) == adl_end(RangeOrContainer);
}
+/// Returns true if the given container only contains a single element.
+template <typename ContainerTy> bool hasSingleElement(ContainerTy &&C) {
+ auto B = std::begin(C), E = std::end(C);
+ return B != E && std::next(B) == E;
+}
+
/// Return a range covering \p RangeOrContainer with the first N elements
/// excluded.
-template <typename T>
-auto drop_begin(T &&RangeOrContainer, size_t N) ->
- iterator_range<decltype(adl_begin(RangeOrContainer))> {
+template <typename T> auto drop_begin(T &&RangeOrContainer, size_t N) {
return make_range(std::next(adl_begin(RangeOrContainer), N),
adl_end(RangeOrContainer));
}
@@ -219,7 +297,7 @@ public:
ItTy getCurrent() { return this->I; }
- FuncReturnTy operator*() { return F(*this->I); }
+ FuncReturnTy operator*() const { return F(*this->I); }
private:
FuncTy F;
@@ -233,9 +311,7 @@ inline mapped_iterator<ItTy, FuncTy> map_iterator(ItTy I, FuncTy F) {
}
template <class ContainerTy, class FuncTy>
-auto map_range(ContainerTy &&C, FuncTy F)
- -> decltype(make_range(map_iterator(C.begin(), F),
- map_iterator(C.end(), F))) {
+auto map_range(ContainerTy &&C, FuncTy F) {
return make_range(map_iterator(C.begin(), F), map_iterator(C.end(), F));
}
@@ -263,8 +339,7 @@ struct has_rbegin : has_rbegin_impl<typename std::remove_reference<Ty>::type> {
// Note that the container must have rbegin()/rend() methods for this to work.
template <typename ContainerTy>
auto reverse(ContainerTy &&C,
- typename std::enable_if<has_rbegin<ContainerTy>::value>::type * =
- nullptr) -> decltype(make_range(C.rbegin(), C.rend())) {
+ std::enable_if_t<has_rbegin<ContainerTy>::value> * = nullptr) {
return make_range(C.rbegin(), C.rend());
}
@@ -278,11 +353,8 @@ std::reverse_iterator<IteratorTy> make_reverse_iterator(IteratorTy It) {
// Note that the container must have begin()/end() methods which return
// bidirectional iterators for this to work.
template <typename ContainerTy>
-auto reverse(
- ContainerTy &&C,
- typename std::enable_if<!has_rbegin<ContainerTy>::value>::type * = nullptr)
- -> decltype(make_range(llvm::make_reverse_iterator(std::end(C)),
- llvm::make_reverse_iterator(std::begin(C)))) {
+auto reverse(ContainerTy &&C,
+ std::enable_if_t<!has_rbegin<ContainerTy>::value> * = nullptr) {
return make_range(llvm::make_reverse_iterator(std::end(C)),
llvm::make_reverse_iterator(std::begin(C)));
}
@@ -673,16 +745,15 @@ detail::zippy<detail::zip_first, T, U, Args...> zip_first(T &&t, U &&u,
namespace detail {
template <typename Iter>
-static Iter next_or_end(const Iter &I, const Iter &End) {
+Iter next_or_end(const Iter &I, const Iter &End) {
if (I == End)
return End;
return std::next(I);
}
template <typename Iter>
-static auto deref_or_none(const Iter &I, const Iter &End)
- -> llvm::Optional<typename std::remove_const<
- typename std::remove_reference<decltype(*I)>::type>::type> {
+auto deref_or_none(const Iter &I, const Iter &End) -> llvm::Optional<
+ std::remove_const_t<std::remove_reference_t<decltype(*I)>>> {
if (I == End)
return None;
return *I;
@@ -887,7 +958,7 @@ class concat_iterator
}
public:
- /// Constructs an iterator from a squence of ranges.
+ /// Constructs an iterator from a sequence of ranges.
///
/// We need the full range to know how to switch between each of the
/// iterators.
@@ -956,6 +1027,234 @@ detail::concat_range<ValueT, RangeTs...> concat(RangeTs &&... Ranges) {
std::forward<RangeTs>(Ranges)...);
}
+/// A utility class used to implement an iterator that contains some base object
+/// and an index. The iterator moves the index but keeps the base constant.
+template <typename DerivedT, typename BaseT, typename T,
+ typename PointerT = T *, typename ReferenceT = T &>
+class indexed_accessor_iterator
+ : public llvm::iterator_facade_base<DerivedT,
+ std::random_access_iterator_tag, T,
+ std::ptrdiff_t, PointerT, ReferenceT> {
+public:
+ ptrdiff_t operator-(const indexed_accessor_iterator &rhs) const {
+ assert(base == rhs.base && "incompatible iterators");
+ return index - rhs.index;
+ }
+ bool operator==(const indexed_accessor_iterator &rhs) const {
+ return base == rhs.base && index == rhs.index;
+ }
+ bool operator<(const indexed_accessor_iterator &rhs) const {
+ assert(base == rhs.base && "incompatible iterators");
+ return index < rhs.index;
+ }
+
+ DerivedT &operator+=(ptrdiff_t offset) {
+ this->index += offset;
+ return static_cast<DerivedT &>(*this);
+ }
+ DerivedT &operator-=(ptrdiff_t offset) {
+ this->index -= offset;
+ return static_cast<DerivedT &>(*this);
+ }
+
+ /// Returns the current index of the iterator.
+ ptrdiff_t getIndex() const { return index; }
+
+ /// Returns the current base of the iterator.
+ const BaseT &getBase() const { return base; }
+
+protected:
+ indexed_accessor_iterator(BaseT base, ptrdiff_t index)
+ : base(base), index(index) {}
+ BaseT base;
+ ptrdiff_t index;
+};
+
+namespace detail {
+/// The class represents the base of a range of indexed_accessor_iterators. It
+/// provides support for many different range functionalities, e.g.
+/// drop_front/slice/etc.. Derived range classes must implement the following
+/// static methods:
+/// * ReferenceT dereference_iterator(const BaseT &base, ptrdiff_t index)
+/// - Dereference an iterator pointing to the base object at the given
+/// index.
+/// * BaseT offset_base(const BaseT &base, ptrdiff_t index)
+/// - Return a new base that is offset from the provide base by 'index'
+/// elements.
+template <typename DerivedT, typename BaseT, typename T,
+ typename PointerT = T *, typename ReferenceT = T &>
+class indexed_accessor_range_base {
+public:
+ using RangeBaseT =
+ indexed_accessor_range_base<DerivedT, BaseT, T, PointerT, ReferenceT>;
+
+ /// An iterator element of this range.
+ class iterator : public indexed_accessor_iterator<iterator, BaseT, T,
+ PointerT, ReferenceT> {
+ public:
+ // Index into this iterator, invoking a static method on the derived type.
+ ReferenceT operator*() const {
+ return DerivedT::dereference_iterator(this->getBase(), this->getIndex());
+ }
+
+ private:
+ iterator(BaseT owner, ptrdiff_t curIndex)
+ : indexed_accessor_iterator<iterator, BaseT, T, PointerT, ReferenceT>(
+ owner, curIndex) {}
+
+ /// Allow access to the constructor.
+ friend indexed_accessor_range_base<DerivedT, BaseT, T, PointerT,
+ ReferenceT>;
+ };
+
+ indexed_accessor_range_base(iterator begin, iterator end)
+ : base(offset_base(begin.getBase(), begin.getIndex())),
+ count(end.getIndex() - begin.getIndex()) {}
+ indexed_accessor_range_base(const iterator_range<iterator> &range)
+ : indexed_accessor_range_base(range.begin(), range.end()) {}
+ indexed_accessor_range_base(BaseT base, ptrdiff_t count)
+ : base(base), count(count) {}
+
+ iterator begin() const { return iterator(base, 0); }
+ iterator end() const { return iterator(base, count); }
+ ReferenceT operator[](unsigned index) const {
+ assert(index < size() && "invalid index for value range");
+ return DerivedT::dereference_iterator(base, index);
+ }
+ ReferenceT front() const {
+ assert(!empty() && "expected non-empty range");
+ return (*this)[0];
+ }
+ ReferenceT back() const {
+ assert(!empty() && "expected non-empty range");
+ return (*this)[size() - 1];
+ }
+
+ /// Compare this range with another.
+ template <typename OtherT> bool operator==(const OtherT &other) const {
+ return size() ==
+ static_cast<size_t>(std::distance(other.begin(), other.end())) &&
+ std::equal(begin(), end(), other.begin());
+ }
+ template <typename OtherT> bool operator!=(const OtherT &other) const {
+ return !(*this == other);
+ }
+
+ /// Return the size of this range.
+ size_t size() const { return count; }
+
+ /// Return if the range is empty.
+ bool empty() const { return size() == 0; }
+
+ /// Drop the first N elements, and keep M elements.
+ DerivedT slice(size_t n, size_t m) const {
+ assert(n + m <= size() && "invalid size specifiers");
+ return DerivedT(offset_base(base, n), m);
+ }
+
+ /// Drop the first n elements.
+ DerivedT drop_front(size_t n = 1) const {
+ assert(size() >= n && "Dropping more elements than exist");
+ return slice(n, size() - n);
+ }
+ /// Drop the last n elements.
+ DerivedT drop_back(size_t n = 1) const {
+ assert(size() >= n && "Dropping more elements than exist");
+ return DerivedT(base, size() - n);
+ }
+
+ /// Take the first n elements.
+ DerivedT take_front(size_t n = 1) const {
+ return n < size() ? drop_back(size() - n)
+ : static_cast<const DerivedT &>(*this);
+ }
+
+ /// Take the last n elements.
+ DerivedT take_back(size_t n = 1) const {
+ return n < size() ? drop_front(size() - n)
+ : static_cast<const DerivedT &>(*this);
+ }
+
+ /// Allow conversion to any type accepting an iterator_range.
+ template <typename RangeT, typename = std::enable_if_t<std::is_constructible<
+ RangeT, iterator_range<iterator>>::value>>
+ operator RangeT() const {
+ return RangeT(iterator_range<iterator>(*this));
+ }
+
+ /// Returns the base of this range.
+ const BaseT &getBase() const { return base; }
+
+private:
+ /// Offset the given base by the given amount.
+ static BaseT offset_base(const BaseT &base, size_t n) {
+ return n == 0 ? base : DerivedT::offset_base(base, n);
+ }
+
+protected:
+ indexed_accessor_range_base(const indexed_accessor_range_base &) = default;
+ indexed_accessor_range_base(indexed_accessor_range_base &&) = default;
+ indexed_accessor_range_base &
+ operator=(const indexed_accessor_range_base &) = default;
+
+ /// The base that owns the provided range of values.
+ BaseT base;
+ /// The size from the owning range.
+ ptrdiff_t count;
+};
+} // end namespace detail
+
+/// This class provides an implementation of a range of
+/// indexed_accessor_iterators where the base is not indexable. Ranges with
+/// bases that are offsetable should derive from indexed_accessor_range_base
+/// instead. Derived range classes are expected to implement the following
+/// static method:
+/// * ReferenceT dereference(const BaseT &base, ptrdiff_t index)
+/// - Dereference an iterator pointing to a parent base at the given index.
+template <typename DerivedT, typename BaseT, typename T,
+ typename PointerT = T *, typename ReferenceT = T &>
+class indexed_accessor_range
+ : public detail::indexed_accessor_range_base<
+ DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT, ReferenceT> {
+public:
+ indexed_accessor_range(BaseT base, ptrdiff_t startIndex, ptrdiff_t count)
+ : detail::indexed_accessor_range_base<
+ DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT, ReferenceT>(
+ std::make_pair(base, startIndex), count) {}
+ using detail::indexed_accessor_range_base<
+ DerivedT, std::pair<BaseT, ptrdiff_t>, T, PointerT,
+ ReferenceT>::indexed_accessor_range_base;
+
+ /// Returns the current base of the range.
+ const BaseT &getBase() const { return this->base.first; }
+
+ /// Returns the current start index of the range.
+ ptrdiff_t getStartIndex() const { return this->base.second; }
+
+ /// See `detail::indexed_accessor_range_base` for details.
+ static std::pair<BaseT, ptrdiff_t>
+ offset_base(const std::pair<BaseT, ptrdiff_t> &base, ptrdiff_t index) {
+ // We encode the internal base as a pair of the derived base and a start
+ // index into the derived base.
+ return std::make_pair(base.first, base.second + index);
+ }
+ /// See `detail::indexed_accessor_range_base` for details.
+ static ReferenceT
+ dereference_iterator(const std::pair<BaseT, ptrdiff_t> &base,
+ ptrdiff_t index) {
+ return DerivedT::dereference(base.first, base.second + index);
+ }
+};
+
+/// Given a container of pairs, return a range over the second elements.
+template <typename ContainerTy> auto make_second_range(ContainerTy &&c) {
+ return llvm::map_range(
+ std::forward<ContainerTy>(c),
+ [](decltype((*std::begin(c))) elt) -> decltype((elt.second)) {
+ return elt.second;
+ });
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <utility>
//===----------------------------------------------------------------------===//
@@ -983,8 +1282,7 @@ struct on_first {
FuncTy func;
template <typename T>
- auto operator()(const T &lhs, const T &rhs) const
- -> decltype(func(lhs.first, rhs.first)) {
+ decltype(auto) operator()(const T &lhs, const T &rhs) const {
return func(lhs.first, rhs.first);
}
};
@@ -1022,6 +1320,16 @@ struct are_base_of<T, U, Ts...> {
// Extra additions for arrays
//===----------------------------------------------------------------------===//
+// We have a copy here so that LLVM behaves the same when using different
+// standard libraries.
+template <class Iterator, class RNG>
+void shuffle(Iterator first, Iterator last, RNG &&g) {
+ // It would be better to use a std::uniform_int_distribution,
+ // but that would be stdlib dependent.
+ for (auto size = last - first; size > 1; ++first, (void)--size)
+ std::iter_swap(first, first + g() % size);
+}
+
/// Find the length of an array.
template <class T, std::size_t N>
constexpr inline size_t array_lengthof(T (&)[N]) {
@@ -1108,9 +1416,20 @@ inline void array_pod_sort(
reinterpret_cast<int (*)(const void *, const void *)>(Compare));
}
+namespace detail {
+template <typename T>
+// We can use qsort if the iterator type is a pointer and the underlying value
+// is trivially copyable.
+using sort_trivially_copyable = conjunction<
+ std::is_pointer<T>,
+ is_trivially_copyable<typename std::iterator_traits<T>::value_type>>;
+} // namespace detail
+
// Provide wrappers to std::sort which shuffle the elements before sorting
// to help uncover non-deterministic behavior (PR35135).
-template <typename IteratorTy>
+template <typename IteratorTy,
+ std::enable_if_t<!detail::sort_trivially_copyable<IteratorTy>::value,
+ int> = 0>
inline void sort(IteratorTy Start, IteratorTy End) {
#ifdef EXPENSIVE_CHECKS
detail::presortShuffle<IteratorTy>(Start, End);
@@ -1118,6 +1437,15 @@ inline void sort(IteratorTy Start, IteratorTy End) {
std::sort(Start, End);
}
+// Forward trivially copyable types to array_pod_sort. This avoids a large
+// amount of code bloat for a minor performance hit.
+template <typename IteratorTy,
+ std::enable_if_t<detail::sort_trivially_copyable<IteratorTy>::value,
+ int> = 0>
+inline void sort(IteratorTy Start, IteratorTy End) {
+ array_pod_sort(Start, End);
+}
+
template <typename Container> inline void sort(Container &&C) {
llvm::sort(adl_begin(C), adl_end(C));
}
@@ -1139,33 +1467,14 @@ inline void sort(Container &&C, Compare Comp) {
// Extra additions to <algorithm>
//===----------------------------------------------------------------------===//
-/// For a container of pointers, deletes the pointers and then clears the
-/// container.
-template<typename Container>
-void DeleteContainerPointers(Container &C) {
- for (auto V : C)
- delete V;
- C.clear();
-}
-
-/// In a container of pairs (usually a map) whose second element is a pointer,
-/// deletes the second elements and then clears the container.
-template<typename Container>
-void DeleteContainerSeconds(Container &C) {
- for (auto &V : C)
- delete V.second;
- C.clear();
-}
-
/// Get the size of a range. This is a wrapper function around std::distance
/// which is only enabled when the operation is O(1).
template <typename R>
-auto size(R &&Range, typename std::enable_if<
- std::is_same<typename std::iterator_traits<decltype(
- Range.begin())>::iterator_category,
- std::random_access_iterator_tag>::value,
- void>::type * = nullptr)
- -> decltype(std::distance(Range.begin(), Range.end())) {
+auto size(R &&Range,
+ std::enable_if_t<std::is_same<typename std::iterator_traits<decltype(
+ Range.begin())>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void> * = nullptr) {
return std::distance(Range.begin(), Range.end());
}
@@ -1199,27 +1508,26 @@ bool none_of(R &&Range, UnaryPredicate P) {
/// Provide wrappers to std::find which take ranges instead of having to pass
/// begin/end explicitly.
-template <typename R, typename T>
-auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range)) {
+template <typename R, typename T> auto find(R &&Range, const T &Val) {
return std::find(adl_begin(Range), adl_end(Range), Val);
}
/// Provide wrappers to std::find_if which take ranges instead of having to pass
/// begin/end explicitly.
template <typename R, typename UnaryPredicate>
-auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
+auto find_if(R &&Range, UnaryPredicate P) {
return std::find_if(adl_begin(Range), adl_end(Range), P);
}
template <typename R, typename UnaryPredicate>
-auto find_if_not(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
+auto find_if_not(R &&Range, UnaryPredicate P) {
return std::find_if_not(adl_begin(Range), adl_end(Range), P);
}
/// Provide wrappers to std::remove_if which take ranges instead of having to
/// pass begin/end explicitly.
template <typename R, typename UnaryPredicate>
-auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
+auto remove_if(R &&Range, UnaryPredicate P) {
return std::remove_if(adl_begin(Range), adl_end(Range), P);
}
@@ -1242,19 +1550,28 @@ bool is_contained(R &&Range, const E &Element) {
return std::find(adl_begin(Range), adl_end(Range), Element) != adl_end(Range);
}
+/// Wrapper function around std::is_sorted to check if elements in a range \p R
+/// are sorted with respect to a comparator \p C.
+template <typename R, typename Compare> bool is_sorted(R &&Range, Compare C) {
+ return std::is_sorted(adl_begin(Range), adl_end(Range), C);
+}
+
+/// Wrapper function around std::is_sorted to check if elements in a range \p R
+/// are sorted in non-descending order.
+template <typename R> bool is_sorted(R &&Range) {
+ return std::is_sorted(adl_begin(Range), adl_end(Range));
+}
+
/// Wrapper function around std::count to count the number of times an element
/// \p Element occurs in the given range \p Range.
-template <typename R, typename E>
-auto count(R &&Range, const E &Element) ->
- typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
+template <typename R, typename E> auto count(R &&Range, const E &Element) {
return std::count(adl_begin(Range), adl_end(Range), Element);
}
/// Wrapper function around std::count_if to count the number of times an
/// element satisfying a given predicate occurs in a range.
template <typename R, typename UnaryPredicate>
-auto count_if(R &&Range, UnaryPredicate P) ->
- typename std::iterator_traits<decltype(adl_begin(Range))>::difference_type {
+auto count_if(R &&Range, UnaryPredicate P) {
return std::count_if(adl_begin(Range), adl_end(Range), P);
}
@@ -1268,36 +1585,32 @@ OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P) {
/// Provide wrappers to std::partition which take ranges instead of having to
/// pass begin/end explicitly.
template <typename R, typename UnaryPredicate>
-auto partition(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range)) {
+auto partition(R &&Range, UnaryPredicate P) {
return std::partition(adl_begin(Range), adl_end(Range), P);
}
/// Provide wrappers to std::lower_bound which take ranges instead of having to
/// pass begin/end explicitly.
-template <typename R, typename T>
-auto lower_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+template <typename R, typename T> auto lower_bound(R &&Range, T &&Value) {
return std::lower_bound(adl_begin(Range), adl_end(Range),
std::forward<T>(Value));
}
template <typename R, typename T, typename Compare>
-auto lower_bound(R &&Range, T &&Value, Compare C)
- -> decltype(adl_begin(Range)) {
+auto lower_bound(R &&Range, T &&Value, Compare C) {
return std::lower_bound(adl_begin(Range), adl_end(Range),
std::forward<T>(Value), C);
}
/// Provide wrappers to std::upper_bound which take ranges instead of having to
/// pass begin/end explicitly.
-template <typename R, typename T>
-auto upper_bound(R &&Range, T &&Value) -> decltype(adl_begin(Range)) {
+template <typename R, typename T> auto upper_bound(R &&Range, T &&Value) {
return std::upper_bound(adl_begin(Range), adl_end(Range),
std::forward<T>(Value));
}
template <typename R, typename T, typename Compare>
-auto upper_bound(R &&Range, T &&Value, Compare C)
- -> decltype(adl_begin(Range)) {
+auto upper_bound(R &&Range, T &&Value, Compare C) {
return std::upper_bound(adl_begin(Range), adl_end(Range),
std::forward<T>(Value), C);
}
@@ -1316,7 +1629,7 @@ void stable_sort(R &&Range, Compare C) {
/// Requires that C is always true below some limit, and always false above it.
template <typename R, typename Predicate,
typename Val = decltype(*adl_begin(std::declval<R>()))>
-auto partition_point(R &&Range, Predicate P) -> decltype(adl_begin(Range)) {
+auto partition_point(R &&Range, Predicate P) {
return std::partition_point(adl_begin(Range), adl_end(Range), P);
}
@@ -1368,6 +1681,69 @@ void replace(Container &Cont, typename Container::iterator ContIt,
replace(Cont, ContIt, ContEnd, R.begin(), R.end());
}
+/// An STL-style algorithm similar to std::for_each that applies a second
+/// functor between every pair of elements.
+///
+/// This provides the control flow logic to, for example, print a
+/// comma-separated list:
+/// \code
+/// interleave(names.begin(), names.end(),
+/// [&](StringRef name) { os << name; },
+/// [&] { os << ", "; });
+/// \endcode
+template <typename ForwardIterator, typename UnaryFunctor,
+ typename NullaryFunctor,
+ typename = typename std::enable_if<
+ !std::is_constructible<StringRef, UnaryFunctor>::value &&
+ !std::is_constructible<StringRef, NullaryFunctor>::value>::type>
+inline void interleave(ForwardIterator begin, ForwardIterator end,
+ UnaryFunctor each_fn, NullaryFunctor between_fn) {
+ if (begin == end)
+ return;
+ each_fn(*begin);
+ ++begin;
+ for (; begin != end; ++begin) {
+ between_fn();
+ each_fn(*begin);
+ }
+}
+
+template <typename Container, typename UnaryFunctor, typename NullaryFunctor,
+ typename = typename std::enable_if<
+ !std::is_constructible<StringRef, UnaryFunctor>::value &&
+ !std::is_constructible<StringRef, NullaryFunctor>::value>::type>
+inline void interleave(const Container &c, UnaryFunctor each_fn,
+ NullaryFunctor between_fn) {
+ interleave(c.begin(), c.end(), each_fn, between_fn);
+}
+
+/// Overload of interleave for the common case of string separator.
+template <typename Container, typename UnaryFunctor, typename StreamT,
+ typename T = detail::ValueOfRange<Container>>
+inline void interleave(const Container &c, StreamT &os, UnaryFunctor each_fn,
+ const StringRef &separator) {
+ interleave(c.begin(), c.end(), each_fn, [&] { os << separator; });
+}
+template <typename Container, typename StreamT,
+ typename T = detail::ValueOfRange<Container>>
+inline void interleave(const Container &c, StreamT &os,
+ const StringRef &separator) {
+ interleave(
+ c, os, [&](const T &a) { os << a; }, separator);
+}
+
+template <typename Container, typename UnaryFunctor, typename StreamT,
+ typename T = detail::ValueOfRange<Container>>
+inline void interleaveComma(const Container &c, StreamT &os,
+ UnaryFunctor each_fn) {
+ interleave(c, os, each_fn, ", ");
+}
+template <typename Container, typename StreamT,
+ typename T = detail::ValueOfRange<Container>>
+inline void interleaveComma(const Container &c, StreamT &os) {
+ interleaveComma(c, os, [&](const T &a) { os << a; });
+}
+
//===----------------------------------------------------------------------===//
// Extra additions to <memory>
//===----------------------------------------------------------------------===//
@@ -1393,8 +1769,7 @@ template <typename T> struct deref {
// Could be further improved to cope with non-derivable functors and
// non-binary functors (should be a variadic template member function
// operator()).
- template <typename A, typename B>
- auto operator()(A &lhs, B &rhs) const -> decltype(func(*lhs, *rhs)) {
+ template <typename A, typename B> auto operator()(A &lhs, B &rhs) const {
assert(lhs);
assert(rhs);
return func(*lhs, *rhs);
@@ -1515,8 +1890,7 @@ template <typename R> detail::enumerator<R> enumerate(R &&TheRange) {
namespace detail {
template <typename F, typename Tuple, std::size_t... I>
-auto apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence<I...>)
- -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...)) {
+decltype(auto) apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence<I...>) {
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
@@ -1526,10 +1900,7 @@ auto apply_tuple_impl(F &&f, Tuple &&t, std::index_sequence<I...>)
/// tuple variadically to f as if by calling f(a1, a2, ..., an) and
/// return the result.
template <typename F, typename Tuple>
-auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
- std::forward<F>(f), std::forward<Tuple>(t),
- std::make_index_sequence<
- std::tuple_size<typename std::decay<Tuple>::type>::value>{})) {
+decltype(auto) apply_tuple(F &&f, Tuple &&t) {
using Indices = std::make_index_sequence<
std::tuple_size<typename std::decay<Tuple>::type>::value>;
@@ -1539,49 +1910,89 @@ auto apply_tuple(F &&f, Tuple &&t) -> decltype(detail::apply_tuple_impl(
/// Return true if the sequence [Begin, End) has exactly N items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
-template <typename IterTy>
+/// Can optionally take a predicate to filter lazily some items.
+template<typename IterTy,
+ typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
bool hasNItems(
IterTy &&Begin, IterTy &&End, unsigned N,
- typename std::enable_if<
- !std::is_same<
- typename std::iterator_traits<typename std::remove_reference<
- decltype(Begin)>::type>::iterator_category,
- std::random_access_iterator_tag>::value,
- void>::type * = nullptr) {
- for (; N; --N, ++Begin)
+ Pred &&ShouldBeCounted =
+ [](const decltype(*std::declval<IterTy>()) &) { return true; },
+ std::enable_if_t<
+ !std::is_same<typename std::iterator_traits<std::remove_reference_t<
+ decltype(Begin)>>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void> * = nullptr) {
+ for (; N; ++Begin) {
if (Begin == End)
return false; // Too few.
- return Begin == End;
+ N -= ShouldBeCounted(*Begin);
+ }
+ for (; Begin != End; ++Begin)
+ if (ShouldBeCounted(*Begin))
+ return false; // Too many.
+ return true;
}
/// Return true if the sequence [Begin, End) has N or more items. Runs in O(N)
/// time. Not meant for use with random-access iterators.
-template <typename IterTy>
+/// Can optionally take a predicate to lazily filter some items.
+template<typename IterTy,
+ typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
bool hasNItemsOrMore(
IterTy &&Begin, IterTy &&End, unsigned N,
- typename std::enable_if<
- !std::is_same<
- typename std::iterator_traits<typename std::remove_reference<
- decltype(Begin)>::type>::iterator_category,
- std::random_access_iterator_tag>::value,
- void>::type * = nullptr) {
- for (; N; --N, ++Begin)
+ Pred &&ShouldBeCounted =
+ [](const decltype(*std::declval<IterTy>()) &) { return true; },
+ std::enable_if_t<
+ !std::is_same<typename std::iterator_traits<std::remove_reference_t<
+ decltype(Begin)>>::iterator_category,
+ std::random_access_iterator_tag>::value,
+ void> * = nullptr) {
+ for (; N; ++Begin) {
if (Begin == End)
return false; // Too few.
+ N -= ShouldBeCounted(*Begin);
+ }
return true;
}
+/// Returns true if the sequence [Begin, End) has N or less items. Can
+/// optionally take a predicate to lazily filter some items.
+template <typename IterTy,
+ typename Pred = bool (*)(const decltype(*std::declval<IterTy>()) &)>
+bool hasNItemsOrLess(
+ IterTy &&Begin, IterTy &&End, unsigned N,
+ Pred &&ShouldBeCounted = [](const decltype(*std::declval<IterTy>()) &) {
+ return true;
+ }) {
+ assert(N != std::numeric_limits<unsigned>::max());
+ return !hasNItemsOrMore(Begin, End, N + 1, ShouldBeCounted);
+}
+
+/// Returns true if the given container has exactly N items
+template <typename ContainerTy> bool hasNItems(ContainerTy &&C, unsigned N) {
+ return hasNItems(std::begin(C), std::end(C), N);
+}
+
+/// Returns true if the given container has N or more items
+template <typename ContainerTy>
+bool hasNItemsOrMore(ContainerTy &&C, unsigned N) {
+ return hasNItemsOrMore(std::begin(C), std::end(C), N);
+}
+
+/// Returns true if the given container has N or less items
+template <typename ContainerTy>
+bool hasNItemsOrLess(ContainerTy &&C, unsigned N) {
+ return hasNItemsOrLess(std::begin(C), std::end(C), N);
+}
+
/// Returns a raw pointer that represents the same address as the argument.
///
-/// The late bound return should be removed once we move to C++14 to better
-/// align with the C++20 declaration. Also, this implementation can be removed
-/// once we move to C++20 where it's defined as std::to_addres()
+/// This implementation can be removed once we move to C++20 where it's defined
+/// as std::to_address().
///
/// The std::pointer_traits<>::to_address(p) variations of these overloads has
/// not been implemented.
-template <class Ptr> auto to_address(const Ptr &P) -> decltype(P.operator->()) {
- return P.operator->();
-}
+template <class Ptr> auto to_address(const Ptr &P) { return P.operator->(); }
template <class T> constexpr T *to_address(T *P) { return P; }
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ScopedHashTable.h b/contrib/llvm-project/llvm/include/llvm/ADT/ScopedHashTable.h
index 40c49ebc0be1..a5e57c6a16c2 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ScopedHashTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ScopedHashTable.h
@@ -32,7 +32,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/Support/AllocatorBase.h"
#include <cassert>
#include <new>
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SetOperations.h b/contrib/llvm-project/llvm/include/llvm/ADT/SetOperations.h
index 037256a860b2..6087f479fe37 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SetOperations.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SetOperations.h
@@ -65,6 +65,27 @@ void set_subtract(S1Ty &S1, const S2Ty &S2) {
S1.erase(*SI);
}
+/// set_is_subset(A, B) - Return true iff A in B
+///
+template <class S1Ty, class S2Ty>
+bool set_is_subset(const S1Ty &S1, const S2Ty &S2) {
+ if (S1.size() > S2.size())
+ return false;
+ for (auto &It : S1)
+ if (!S2.count(It))
+ return false;
+ return true;
+}
+
+/// set_is_strict_subset(A, B) - Return true iff A in B and and A != B
+///
+template <class S1Ty, class S2Ty>
+bool set_is_strict_subset(const S1Ty &S1, const S2Ty &S2) {
+ if (S1.size() >= S2.size())
+ return false;
+ return set_is_subset(S1, S2);
+}
+
} // End llvm namespace
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SetVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/SetVector.h
index d0a0d28d1c81..91ad72143ed3 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SetVector.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SetVector.h
@@ -174,7 +174,7 @@ public:
set_.erase(V);
// FIXME: No need to use the non-const iterator when built with
- // std:vector.erase(const_iterator) as defined in C++11. This is for
+ // std::vector.erase(const_iterator) as defined in C++11. This is for
// compatibility with non-standard libstdc++ up to 4.8 (fixed in 4.9).
auto NI = vector_.begin();
std::advance(NI, std::distance<iterator>(NI, I));
@@ -263,6 +263,11 @@ public:
remove(*SI);
}
+ void swap(SetVector<T, Vector, Set> &RHS) {
+ set_.swap(RHS.set_);
+ vector_.swap(RHS.vector_);
+ }
+
private:
/// A wrapper predicate designed for use with std::remove_if.
///
@@ -308,4 +313,22 @@ public:
} // end namespace llvm
+namespace std {
+
+/// Implement std::swap in terms of SetVector swap.
+template<typename T, typename V, typename S>
+inline void
+swap(llvm::SetVector<T, V, S> &LHS, llvm::SetVector<T, V, S> &RHS) {
+ LHS.swap(RHS);
+}
+
+/// Implement std::swap in terms of SmallSetVector swap.
+template<typename T, unsigned N>
+inline void
+swap(llvm::SmallSetVector<T, N> &LHS, llvm::SmallSetVector<T, N> &RHS) {
+ LHS.swap(RHS);
+}
+
+} // end namespace std
+
#endif // LLVM_ADT_SETVECTOR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h
index 61375c008022..f570bac23ad5 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SmallBitVector.h
@@ -287,11 +287,11 @@ public:
/// Returns -1 if the next unset bit is not found.
int find_next_unset(unsigned Prev) const {
if (isSmall()) {
- ++Prev;
uintptr_t Bits = getSmallBits();
// Mask in previous bits.
- uintptr_t Mask = (uintptr_t(1) << Prev) - 1;
- Bits |= Mask;
+ Bits |= (uintptr_t(1) << (Prev + 1)) - 1;
+ // Mask in unused bits.
+ Bits |= ~uintptr_t(0) << getSmallSize();
if (Bits == ~uintptr_t(0) || Prev + 1 >= getSmallSize())
return -1;
@@ -662,6 +662,19 @@ public:
getPointer()->clearBitsNotInMask(Mask, MaskWords);
}
+ void invalid() {
+ assert(empty());
+ X = (uintptr_t)-1;
+ }
+ bool isInvalid() const { return X == (uintptr_t)-1; }
+
+ ArrayRef<uintptr_t> getData(uintptr_t &Store) const {
+ if (!isSmall())
+ return getPointer()->getData();
+ Store = getSmallBits();
+ return makeArrayRef(Store);
+ }
+
private:
template <bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
@@ -699,6 +712,24 @@ operator^(const SmallBitVector &LHS, const SmallBitVector &RHS) {
return Result;
}
+template <> struct DenseMapInfo<SmallBitVector> {
+ static inline SmallBitVector getEmptyKey() { return SmallBitVector(); }
+ static inline SmallBitVector getTombstoneKey() {
+ SmallBitVector V;
+ V.invalid();
+ return V;
+ }
+ static unsigned getHashValue(const SmallBitVector &V) {
+ uintptr_t Store;
+ return DenseMapInfo<std::pair<unsigned, ArrayRef<uintptr_t>>>::getHashValue(
+ std::make_pair(V.size(), V.getData(Store)));
+ }
+ static bool isEqual(const SmallBitVector &LHS, const SmallBitVector &RHS) {
+ if (LHS.isInvalid() || RHS.isInvalid())
+ return LHS.isInvalid() == RHS.isInvalid();
+ return LHS == RHS;
+ }
+};
} // end namespace llvm
namespace std {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h
index 1d8280063c80..0ab05cfe611a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -278,7 +278,7 @@ public:
const DebugEpochBase &Epoch)
: SmallPtrSetIteratorImpl(BP, E), DebugEpochBase::HandleBase(&Epoch) {}
- // Most methods provided by baseclass.
+ // Most methods are provided by the base class.
const PtrTy operator*() const {
assert(isHandleInSync() && "invalid iterator access!");
@@ -346,14 +346,8 @@ class SmallPtrSetImpl : public SmallPtrSetImplBase {
using ConstPtrTraits = PointerLikeTypeTraits<ConstPtrType>;
protected:
- // Constructors that forward to the base.
- SmallPtrSetImpl(const void **SmallStorage, const SmallPtrSetImpl &that)
- : SmallPtrSetImplBase(SmallStorage, that) {}
- SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize,
- SmallPtrSetImpl &&that)
- : SmallPtrSetImplBase(SmallStorage, SmallSize, std::move(that)) {}
- explicit SmallPtrSetImpl(const void **SmallStorage, unsigned SmallSize)
- : SmallPtrSetImplBase(SmallStorage, SmallSize) {}
+ // Forward constructors to the base.
+ using SmallPtrSetImplBase::SmallPtrSetImplBase;
public:
using iterator = SmallPtrSetIterator<PtrType>;
@@ -378,7 +372,9 @@ public:
return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
}
/// count - Return 1 if the specified pointer is in the set, 0 otherwise.
- size_type count(ConstPtrType Ptr) const { return find(Ptr) != end() ? 1 : 0; }
+ size_type count(ConstPtrType Ptr) const {
+ return find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)) != EndPointer();
+ }
iterator find(ConstPtrType Ptr) const {
return makeIterator(find_imp(ConstPtrTraits::getAsVoidPointer(Ptr)));
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SmallString.h b/contrib/llvm-project/llvm/include/llvm/ADT/SmallString.h
index 898be80d0324..cd6f2173d04f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SmallString.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SmallString.h
@@ -263,7 +263,7 @@ public:
// Extra methods.
/// Explicit conversion to StringRef.
- StringRef str() const { return StringRef(this->begin(), this->size()); }
+ StringRef str() const { return StringRef(this->data(), this->size()); }
// TODO: Make this const, if it's safe...
const char* c_str() {
@@ -275,6 +275,10 @@ public:
/// Implicit conversion to StringRef.
operator StringRef() const { return str(); }
+ explicit operator std::string() const {
+ return std::string(this->data(), this->size());
+ }
+
// Extra operators.
const SmallString &operator=(StringRef RHS) {
this->clear();
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h
index 8c46aa906905..3ccee3d21d48 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SmallVector.h
@@ -16,10 +16,10 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemAlloc.h"
#include "llvm/Support/type_traits.h"
-#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -27,6 +27,7 @@
#include <cstring>
#include <initializer_list>
#include <iterator>
+#include <limits>
#include <memory>
#include <new>
#include <type_traits>
@@ -34,11 +35,23 @@
namespace llvm {
-/// This is all the non-templated stuff common to all SmallVectors.
-class SmallVectorBase {
+/// This is all the stuff common to all SmallVectors.
+///
+/// The template parameter specifies the type which should be used to hold the
+/// Size and Capacity of the SmallVector, so it can be adjusted.
+/// Using 32 bit size is desirable to shrink the size of the SmallVector.
+/// Using 64 bit size is desirable for cases like SmallVector<char>, where a
+/// 32 bit size would limit the vector to ~4GB. SmallVectors are used for
+/// buffering bitcode output - which can exceed 4GB.
+template <class Size_T> class SmallVectorBase {
protected:
void *BeginX;
- unsigned Size = 0, Capacity;
+ Size_T Size = 0, Capacity;
+
+ /// The maximum value of the Size_T used.
+ static constexpr size_t SizeTypeMax() {
+ return std::numeric_limits<Size_T>::max();
+ }
SmallVectorBase() = delete;
SmallVectorBase(void *FirstEl, size_t TotalCapacity)
@@ -46,6 +59,7 @@ protected:
/// This is an implementation of the grow() method which only works
/// on POD-like data types and is out of line to reduce code duplication.
+ /// This function will report a fatal error if it cannot increase capacity.
void grow_pod(void *FirstEl, size_t MinCapacity, size_t TSize);
public:
@@ -69,9 +83,14 @@ public:
}
};
+template <class T>
+using SmallVectorSizeType =
+ typename std::conditional<sizeof(T) < 4 && sizeof(void *) >= 8, uint64_t,
+ uint32_t>::type;
+
/// Figure out the offset of the first element.
template <class T, typename = void> struct SmallVectorAlignmentAndSize {
- AlignedCharArrayUnion<SmallVectorBase> Base;
+ AlignedCharArrayUnion<SmallVectorBase<SmallVectorSizeType<T>>> Base;
AlignedCharArrayUnion<T> FirstEl;
};
@@ -79,7 +98,10 @@ template <class T, typename = void> struct SmallVectorAlignmentAndSize {
/// the type T is a POD. The extra dummy template argument is used by ArrayRef
/// to avoid unnecessarily requiring T to be complete.
template <typename T, typename = void>
-class SmallVectorTemplateCommon : public SmallVectorBase {
+class SmallVectorTemplateCommon
+ : public SmallVectorBase<SmallVectorSizeType<T>> {
+ using Base = SmallVectorBase<SmallVectorSizeType<T>>;
+
/// Find the address of the first element. For this pointer math to be valid
/// with small-size of 0 for T with lots of alignment, it's important that
/// SmallVectorStorage is properly-aligned even for small-size of 0.
@@ -91,21 +113,20 @@ class SmallVectorTemplateCommon : public SmallVectorBase {
// Space after 'FirstEl' is clobbered, do not add any instance vars after it.
protected:
- SmallVectorTemplateCommon(size_t Size)
- : SmallVectorBase(getFirstEl(), Size) {}
+ SmallVectorTemplateCommon(size_t Size) : Base(getFirstEl(), Size) {}
void grow_pod(size_t MinCapacity, size_t TSize) {
- SmallVectorBase::grow_pod(getFirstEl(), MinCapacity, TSize);
+ Base::grow_pod(getFirstEl(), MinCapacity, TSize);
}
/// Return true if this is a smallvector which has not had dynamic
/// memory allocated for it.
- bool isSmall() const { return BeginX == getFirstEl(); }
+ bool isSmall() const { return this->BeginX == getFirstEl(); }
/// Put this vector in a state of being small.
void resetToSmall() {
- BeginX = getFirstEl();
- Size = Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
+ this->BeginX = getFirstEl();
+ this->Size = this->Capacity = 0; // FIXME: Setting Capacity to 0 is suspect.
}
public:
@@ -123,6 +144,10 @@ public:
using pointer = T *;
using const_pointer = const T *;
+ using Base::capacity;
+ using Base::empty;
+ using Base::size;
+
// forward iterator creation methods.
iterator begin() { return (iterator)this->BeginX; }
const_iterator begin() const { return (const_iterator)this->BeginX; }
@@ -136,7 +161,9 @@ public:
const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
size_type size_in_bytes() const { return size() * sizeof(T); }
- size_type max_size() const { return size_type(-1) / sizeof(T); }
+ size_type max_size() const {
+ return std::min(this->SizeTypeMax(), size_type(-1) / sizeof(T));
+ }
size_t capacity_in_bytes() const { return capacity() * sizeof(T); }
@@ -173,9 +200,17 @@ public:
}
};
-/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put method
-/// implementations that are designed to work with non-POD-like T's.
-template <typename T, bool = is_trivially_copyable<T>::value>
+/// SmallVectorTemplateBase<TriviallyCopyable = false> - This is where we put
+/// method implementations that are designed to work with non-trivial T's.
+///
+/// We approximate is_trivially_copyable with trivial move/copy construction and
+/// trivial destruction. While the standard doesn't specify that you're allowed
+/// copy these types with memcpy, there is no way for the type to observe this.
+/// This catches the important case of std::pair<POD, POD>, which is not
+/// trivially assignable.
+template <typename T, bool = (is_trivially_copy_constructible<T>::value) &&
+ (is_trivially_move_constructible<T>::value) &&
+ std::is_trivially_destructible<T>::value>
class SmallVectorTemplateBase : public SmallVectorTemplateCommon<T> {
protected:
SmallVectorTemplateBase(size_t Size) : SmallVectorTemplateCommon<T>(Size) {}
@@ -231,12 +266,21 @@ public:
// Define this out-of-line to dissuade the C++ compiler from inlining it.
template <typename T, bool TriviallyCopyable>
void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
- if (MinSize > UINT32_MAX)
+ // Ensure we can fit the new capacity.
+ // This is only going to be applicable when the capacity is 32 bit.
+ if (MinSize > this->SizeTypeMax())
report_bad_alloc_error("SmallVector capacity overflow during allocation");
+ // Ensure we can meet the guarantee of space for at least one more element.
+ // The above check alone will not catch the case where grow is called with a
+ // default MinCapacity of 0, but the current capacity cannot be increased.
+ // This is only going to be applicable when the capacity is 32 bit.
+ if (this->capacity() == this->SizeTypeMax())
+ report_bad_alloc_error("SmallVector capacity unable to grow");
+
// Always grow, even from zero.
size_t NewCapacity = size_t(NextPowerOf2(this->capacity() + 2));
- NewCapacity = std::min(std::max(NewCapacity, MinSize), size_t(UINT32_MAX));
+ NewCapacity = std::min(std::max(NewCapacity, MinSize), this->SizeTypeMax());
T *NewElts = static_cast<T*>(llvm::safe_malloc(NewCapacity*sizeof(T)));
// Move the elements over.
@@ -254,7 +298,9 @@ void SmallVectorTemplateBase<T, TriviallyCopyable>::grow(size_t MinSize) {
}
/// SmallVectorTemplateBase<TriviallyCopyable = true> - This is where we put
-/// method implementations that are designed to work with POD-like T's.
+/// method implementations that are designed to work with trivially copyable
+/// T's. This allows using memcpy in place of copy/move construction and
+/// skipping destruction.
template <typename T>
class SmallVectorTemplateBase<T, true> : public SmallVectorTemplateCommon<T> {
protected:
@@ -284,8 +330,8 @@ protected:
template <typename T1, typename T2>
static void uninitialized_copy(
T1 *I, T1 *E, T2 *Dest,
- typename std::enable_if<std::is_same<typename std::remove_const<T1>::type,
- T2>::value>::type * = nullptr) {
+ std::enable_if_t<std::is_same<typename std::remove_const<T1>::type,
+ T2>::value> * = nullptr) {
// Use memcpy for PODs iterated by pointers (which includes SmallVector
// iterators): std::uninitialized_copy optimizes to memmove, but we can
// use memcpy here. Note that I and E are iterators and thus might be
@@ -381,9 +427,9 @@ public:
/// Add the specified range to the end of the SmallVector.
template <typename in_iter,
- typename = typename std::enable_if<std::is_convertible<
+ typename = std::enable_if_t<std::is_convertible<
typename std::iterator_traits<in_iter>::iterator_category,
- std::input_iterator_tag>::value>::type>
+ std::input_iterator_tag>::value>>
void append(in_iter in_start, in_iter in_end) {
size_type NumInputs = std::distance(in_start, in_end);
if (NumInputs > this->capacity() - this->size())
@@ -418,9 +464,9 @@ public:
}
template <typename in_iter,
- typename = typename std::enable_if<std::is_convertible<
+ typename = std::enable_if_t<std::is_convertible<
typename std::iterator_traits<in_iter>::iterator_category,
- std::input_iterator_tag>::value>::type>
+ std::input_iterator_tag>::value>>
void assign(in_iter in_start, in_iter in_end) {
clear();
append(in_start, in_end);
@@ -575,9 +621,9 @@ public:
}
template <typename ItTy,
- typename = typename std::enable_if<std::is_convertible<
+ typename = std::enable_if_t<std::is_convertible<
typename std::iterator_traits<ItTy>::iterator_category,
- std::input_iterator_tag>::value>::type>
+ std::input_iterator_tag>::value>>
iterator insert(iterator I, ItTy From, ItTy To) {
// Convert iterator to elt# to avoid invalidating iterator when we reserve()
size_t InsertElt = I - this->begin();
@@ -834,7 +880,8 @@ template <typename T> struct alignas(alignof(T)) SmallVectorStorage<T, 0> {};
/// Note that this does not attempt to be exception safe.
///
template <typename T, unsigned N>
-class SmallVector : public SmallVectorImpl<T>, SmallVectorStorage<T, N> {
+class LLVM_GSL_OWNER SmallVector : public SmallVectorImpl<T>,
+ SmallVectorStorage<T, N> {
public:
SmallVector() : SmallVectorImpl<T>(N) {}
@@ -849,9 +896,9 @@ public:
}
template <typename ItTy,
- typename = typename std::enable_if<std::is_convertible<
+ typename = std::enable_if_t<std::is_convertible<
typename std::iterator_traits<ItTy>::iterator_category,
- std::input_iterator_tag>::value>::type>
+ std::input_iterator_tag>::value>>
SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(N) {
this->append(S, E);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SparseMultiSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/SparseMultiSet.h
index d9d3ff459267..307d2c3f84e5 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SparseMultiSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SparseMultiSet.h
@@ -94,7 +94,7 @@ class SparseMultiSet {
/// tombstones, in which case they are actually nodes in a single-linked
/// freelist of recyclable slots.
struct SMSNode {
- static const unsigned INVALID = ~0U;
+ static constexpr unsigned INVALID = ~0U;
ValueT Data;
unsigned Prev;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/SparseSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/SparseSet.h
index a6eb9b942e80..74457d5fd679 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/SparseSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/SparseSet.h
@@ -21,7 +21,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/Support/AllocatorBase.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
@@ -79,7 +79,7 @@ struct SparseSetValFunctor<KeyT, KeyT, KeyFunctorT> {
}
};
-/// SparseSet - Fast set implmentation for objects that can be identified by
+/// SparseSet - Fast set implementation for objects that can be identified by
/// small unsigned keys.
///
/// SparseSet allocates memory proportional to the size of the key universe, so
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/StringExtras.h b/contrib/llvm-project/llvm/include/llvm/ADT/StringExtras.h
index ef1a11e0619b..990a3054a9d2 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/StringExtras.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/StringExtras.h
@@ -107,6 +107,14 @@ inline bool isPrint(char C) {
return (0x20 <= UC) && (UC <= 0x7E);
}
+/// Checks whether character \p C is whitespace in the "C" locale.
+///
+/// Locale-independent version of the C standard library isspace.
+inline bool isSpace(char C) {
+ return C == ' ' || C == '\f' || C == '\n' || C == '\r' || C == '\t' ||
+ C == '\v';
+}
+
/// Returns the corresponding lowercase character if \p x is uppercase.
inline char toLower(char x) {
if (x >= 'A' && x <= 'Z')
@@ -237,7 +245,7 @@ inline std::string utostr(uint64_t X, bool isNeg = false) {
inline std::string itostr(int64_t X) {
if (X < 0)
- return utostr(static_cast<uint64_t>(-X), true);
+ return utostr(-static_cast<uint64_t>(X), true);
else
return utostr(static_cast<uint64_t>(X));
}
@@ -292,6 +300,18 @@ void printHTMLEscaped(StringRef String, raw_ostream &Out);
/// printLowerCase - Print each character as lowercase if it is uppercase.
void printLowerCase(StringRef String, raw_ostream &Out);
+/// Converts a string from camel-case to snake-case by replacing all uppercase
+/// letters with '_' followed by the letter in lowercase, except if the
+/// uppercase letter is the first character of the string.
+std::string convertToSnakeFromCamelCase(StringRef input);
+
+/// Converts a string from snake-case to camel-case by replacing all occurrences
+/// of '_' followed by a lowercase letter with the letter in uppercase.
+/// Optionally allow capitalization of the first letter (if it is a lowercase
+/// letter)
+std::string convertToCamelFromSnakeCase(StringRef input,
+ bool capitalizeFirst = false);
+
namespace detail {
template <typename IteratorT>
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/StringMap.h b/contrib/llvm-project/llvm/include/llvm/ADT/StringMap.h
index 108185bd07b9..840f328db796 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/StringMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/StringMap.h
@@ -13,36 +13,17 @@
#ifndef LLVM_ADT_STRINGMAP_H
#define LLVM_ADT_STRINGMAP_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/StringMapEntry.h"
+#include "llvm/Support/AllocatorBase.h"
#include "llvm/Support/PointerLikeTypeTraits.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstdlib>
-#include <cstring>
#include <initializer_list>
#include <iterator>
-#include <utility>
namespace llvm {
-template<typename ValueTy> class StringMapConstIterator;
-template<typename ValueTy> class StringMapIterator;
-template<typename ValueTy> class StringMapKeyIterator;
-
-/// StringMapEntryBase - Shared base class of StringMapEntry instances.
-class StringMapEntryBase {
- size_t StrLen;
-
-public:
- explicit StringMapEntryBase(size_t Len) : StrLen(Len) {}
-
- size_t getKeyLength() const { return StrLen; }
-};
+template <typename ValueTy> class StringMapConstIterator;
+template <typename ValueTy> class StringMapIterator;
+template <typename ValueTy> class StringMapKeyIterator;
/// StringMapImpl - This is the base class of StringMap that is shared among
/// all of its instantiations.
@@ -58,8 +39,7 @@ protected:
unsigned ItemSize;
protected:
- explicit StringMapImpl(unsigned itemSize)
- : ItemSize(itemSize) {}
+ explicit StringMapImpl(unsigned itemSize) : ItemSize(itemSize) {}
StringMapImpl(StringMapImpl &&RHS)
: TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
@@ -118,127 +98,11 @@ public:
}
};
-/// StringMapEntryStorage - Holds the value in a StringMapEntry.
-///
-/// Factored out into a separate base class to make it easier to specialize.
-/// This is primarily intended to support StringSet, which doesn't need a value
-/// stored at all.
-template<typename ValueTy>
-class StringMapEntryStorage : public StringMapEntryBase {
-public:
- ValueTy second;
-
- explicit StringMapEntryStorage(size_t strLen)
- : StringMapEntryBase(strLen), second() {}
- template <typename... InitTy>
- StringMapEntryStorage(size_t strLen, InitTy &&... InitVals)
- : StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
- StringMapEntryStorage(StringMapEntryStorage &E) = delete;
-
- const ValueTy &getValue() const { return second; }
- ValueTy &getValue() { return second; }
-
- void setValue(const ValueTy &V) { second = V; }
-};
-
-template<>
-class StringMapEntryStorage<NoneType> : public StringMapEntryBase {
-public:
- explicit StringMapEntryStorage(size_t strLen, NoneType none = None)
- : StringMapEntryBase(strLen) {}
- StringMapEntryStorage(StringMapEntryStorage &E) = delete;
-
- NoneType getValue() const { return None; }
-};
-
-/// StringMapEntry - This is used to represent one value that is inserted into
-/// a StringMap. It contains the Value itself and the key: the string length
-/// and data.
-template<typename ValueTy>
-class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
-public:
- using StringMapEntryStorage<ValueTy>::StringMapEntryStorage;
-
- StringRef getKey() const {
- return StringRef(getKeyData(), this->getKeyLength());
- }
-
- /// getKeyData - Return the start of the string data that is the key for this
- /// value. The string data is always stored immediately after the
- /// StringMapEntry object.
- const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
-
- StringRef first() const {
- return StringRef(getKeyData(), this->getKeyLength());
- }
-
- /// Create a StringMapEntry for the specified key construct the value using
- /// \p InitiVals.
- template <typename AllocatorTy, typename... InitTy>
- static StringMapEntry *Create(StringRef Key, AllocatorTy &Allocator,
- InitTy &&... InitVals) {
- size_t KeyLength = Key.size();
-
- // Allocate a new item with space for the string at the end and a null
- // terminator.
- size_t AllocSize = sizeof(StringMapEntry) + KeyLength + 1;
- size_t Alignment = alignof(StringMapEntry);
-
- StringMapEntry *NewItem =
- static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize,Alignment));
- assert(NewItem && "Unhandled out-of-memory");
-
- // Construct the value.
- new (NewItem) StringMapEntry(KeyLength, std::forward<InitTy>(InitVals)...);
-
- // Copy the string information.
- char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
- if (KeyLength > 0)
- memcpy(StrBuffer, Key.data(), KeyLength);
- StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
- return NewItem;
- }
-
- /// Create - Create a StringMapEntry with normal malloc/free.
- template <typename... InitType>
- static StringMapEntry *Create(StringRef Key, InitType &&... InitVal) {
- MallocAllocator A;
- return Create(Key, A, std::forward<InitType>(InitVal)...);
- }
-
- static StringMapEntry *Create(StringRef Key) {
- return Create(Key, ValueTy());
- }
-
- /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
- /// into a StringMapEntry, return the StringMapEntry itself.
- static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
- char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
- return *reinterpret_cast<StringMapEntry*>(Ptr);
- }
-
- /// Destroy - Destroy this StringMapEntry, releasing memory back to the
- /// specified allocator.
- template<typename AllocatorTy>
- void Destroy(AllocatorTy &Allocator) {
- // Free memory referenced by the item.
- size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
- this->~StringMapEntry();
- Allocator.Deallocate(static_cast<void *>(this), AllocSize);
- }
-
- /// Destroy this object, releasing memory back to the malloc allocator.
- void Destroy() {
- MallocAllocator A;
- Destroy(A);
- }
-};
-
/// StringMap - This is an unconventional map that is specialized for handling
/// keys that are "strings", which are basically ranges of bytes. This does some
/// funky memory allocation and hashing things to make it extremely efficient,
/// storing the string data *after* the value in the map.
-template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+template <typename ValueTy, typename AllocatorTy = MallocAllocator>
class StringMap : public StringMapImpl {
AllocatorTy Allocator;
@@ -248,14 +112,15 @@ public:
StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(unsigned InitialSize)
- : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
+ : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
explicit StringMap(AllocatorTy A)
- : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {
+ }
StringMap(unsigned InitialSize, AllocatorTy A)
- : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
- Allocator(A) {}
+ : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
+ Allocator(A) {}
StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
: StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
@@ -267,9 +132,9 @@ public:
StringMap(StringMap &&RHS)
: StringMapImpl(std::move(RHS)), Allocator(std::move(RHS.Allocator)) {}
- StringMap(const StringMap &RHS) :
- StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
- Allocator(RHS.Allocator) {
+ StringMap(const StringMap &RHS)
+ : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
+ Allocator(RHS.Allocator) {
if (RHS.empty())
return;
@@ -316,7 +181,7 @@ public:
for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
StringMapEntryBase *Bucket = TheTable[I];
if (Bucket && Bucket != getTombstoneVal()) {
- static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ static_cast<MapEntryTy *>(Bucket)->Destroy(Allocator);
}
}
}
@@ -326,7 +191,7 @@ public:
AllocatorTy &getAllocator() { return Allocator; }
const AllocatorTy &getAllocator() const { return Allocator; }
- using key_type = const char*;
+ using key_type = const char *;
using mapped_type = ValueTy;
using value_type = StringMapEntry<ValueTy>;
using size_type = size_t;
@@ -334,17 +199,13 @@ public:
using const_iterator = StringMapConstIterator<ValueTy>;
using iterator = StringMapIterator<ValueTy>;
- iterator begin() {
- return iterator(TheTable, NumBuckets == 0);
- }
- iterator end() {
- return iterator(TheTable+NumBuckets, true);
- }
+ iterator begin() { return iterator(TheTable, NumBuckets == 0); }
+ iterator end() { return iterator(TheTable + NumBuckets, true); }
const_iterator begin() const {
return const_iterator(TheTable, NumBuckets == 0);
}
const_iterator end() const {
- return const_iterator(TheTable+NumBuckets, true);
+ return const_iterator(TheTable + NumBuckets, true);
}
iterator_range<StringMapKeyIterator<ValueTy>> keys() const {
@@ -354,14 +215,16 @@ public:
iterator find(StringRef Key) {
int Bucket = FindKey(Key);
- if (Bucket == -1) return end();
- return iterator(TheTable+Bucket, true);
+ if (Bucket == -1)
+ return end();
+ return iterator(TheTable + Bucket, true);
}
const_iterator find(StringRef Key) const {
int Bucket = FindKey(Key);
- if (Bucket == -1) return end();
- return const_iterator(TheTable+Bucket, true);
+ if (Bucket == -1)
+ return end();
+ return const_iterator(TheTable + Bucket, true);
}
/// lookup - Return the entry for the specified key, or a default
@@ -378,15 +241,33 @@ public:
ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
/// count - Return 1 if the element is in the map, 0 otherwise.
- size_type count(StringRef Key) const {
- return find(Key) == end() ? 0 : 1;
- }
+ size_type count(StringRef Key) const { return find(Key) == end() ? 0 : 1; }
template <typename InputTy>
size_type count(const StringMapEntry<InputTy> &MapEntry) const {
return count(MapEntry.getKey());
}
+ /// equal - check whether both of the containers are equal.
+ bool operator==(const StringMap &RHS) const {
+ if (size() != RHS.size())
+ return false;
+
+ for (const auto &KeyValue : *this) {
+ auto FindInRHS = RHS.find(KeyValue.getKey());
+
+ if (FindInRHS == RHS.end())
+ return false;
+
+ if (!(KeyValue.getValue() == FindInRHS->getValue()))
+ return false;
+ }
+
+ return true;
+ }
+
+ bool operator!=(const StringMap &RHS) const { return !(*this == RHS); }
+
/// insert - Insert the specified key/value pair into the map. If the key
/// already exists in the map, return false and ignore the request, otherwise
/// insert it and return true.
@@ -394,7 +275,7 @@ public:
unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
StringMapEntryBase *&Bucket = TheTable[BucketNo];
if (Bucket && Bucket != getTombstoneVal())
- return false; // Already exists in map.
+ return false; // Already exists in map.
if (Bucket == getTombstoneVal())
--NumTombstones;
@@ -448,14 +329,15 @@ public:
// clear - Empties out the StringMap
void clear() {
- if (empty()) return;
+ if (empty())
+ return;
// Zap all values, resetting the keys back to non-present (not tombstone),
// which is safe because we're removing all elements.
for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
StringMapEntryBase *&Bucket = TheTable[I];
if (Bucket && Bucket != getTombstoneVal()) {
- static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
+ static_cast<MapEntryTy *>(Bucket)->Destroy(Allocator);
}
Bucket = nullptr;
}
@@ -466,9 +348,7 @@ public:
/// remove - Remove the specified key/value pair from the map, but do not
/// erase it. This aborts if the key is not in the map.
- void remove(MapEntryTy *KeyValue) {
- RemoveKey(KeyValue);
- }
+ void remove(MapEntryTy *KeyValue) { RemoveKey(KeyValue); }
void erase(iterator I) {
MapEntryTy &V = *I;
@@ -478,7 +358,8 @@ public:
bool erase(StringRef Key) {
iterator I = find(Key);
- if (I == end()) return false;
+ if (I == end())
+ return false;
erase(I);
return true;
}
@@ -497,7 +378,8 @@ public:
explicit StringMapIterBase(StringMapEntryBase **Bucket,
bool NoAdvance = false)
: Ptr(Bucket) {
- if (!NoAdvance) AdvancePastEmptyBuckets();
+ if (!NoAdvance)
+ AdvancePastEmptyBuckets();
}
DerivedTy &operator=(const DerivedTy &Other) {
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/StringMapEntry.h b/contrib/llvm-project/llvm/include/llvm/ADT/StringMapEntry.h
new file mode 100644
index 000000000000..ea3aad6f1cb1
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/StringMapEntry.h
@@ -0,0 +1,135 @@
+//===- StringMapEntry.h - String Hash table map interface -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StringMapEntry class - it is intended to be a low
+// dependency implementation detail of StringMap that is more suitable for
+// inclusion in public headers than StringMap.h itself is.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAPENTRY_H
+#define LLVM_ADT_STRINGMAPENTRY_H
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+ size_t keyLength;
+
+public:
+ explicit StringMapEntryBase(size_t keyLength) : keyLength(keyLength) {}
+
+ size_t getKeyLength() const { return keyLength; }
+};
+
+/// StringMapEntryStorage - Holds the value in a StringMapEntry.
+///
+/// Factored out into a separate base class to make it easier to specialize.
+/// This is primarily intended to support StringSet, which doesn't need a value
+/// stored at all.
+template <typename ValueTy>
+class StringMapEntryStorage : public StringMapEntryBase {
+public:
+ ValueTy second;
+
+ explicit StringMapEntryStorage(size_t keyLength)
+ : StringMapEntryBase(keyLength), second() {}
+ template <typename... InitTy>
+ StringMapEntryStorage(size_t keyLength, InitTy &&... initVals)
+ : StringMapEntryBase(keyLength),
+ second(std::forward<InitTy>(initVals)...) {}
+ StringMapEntryStorage(StringMapEntryStorage &e) = delete;
+
+ const ValueTy &getValue() const { return second; }
+ ValueTy &getValue() { return second; }
+
+ void setValue(const ValueTy &V) { second = V; }
+};
+
+template <> class StringMapEntryStorage<NoneType> : public StringMapEntryBase {
+public:
+ explicit StringMapEntryStorage(size_t keyLength, NoneType none = None)
+ : StringMapEntryBase(keyLength) {}
+ StringMapEntryStorage(StringMapEntryStorage &entry) = delete;
+
+ NoneType getValue() const { return None; }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap. It contains the Value itself and the key: the string length
+/// and data.
+template <typename ValueTy>
+class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
+public:
+ using StringMapEntryStorage<ValueTy>::StringMapEntryStorage;
+
+ StringRef getKey() const {
+ return StringRef(getKeyData(), this->getKeyLength());
+ }
+
+ /// getKeyData - Return the start of the string data that is the key for this
+ /// value. The string data is always stored immediately after the
+ /// StringMapEntry object.
+ const char *getKeyData() const {
+ return reinterpret_cast<const char *>(this + 1);
+ }
+
+ StringRef first() const {
+ return StringRef(getKeyData(), this->getKeyLength());
+ }
+
+ /// Create a StringMapEntry for the specified key construct the value using
+ /// \p InitiVals.
+ template <typename AllocatorTy, typename... InitTy>
+ static StringMapEntry *Create(StringRef key, AllocatorTy &allocator,
+ InitTy &&... initVals) {
+ size_t keyLength = key.size();
+
+ // Allocate a new item with space for the string at the end and a null
+ // terminator.
+ size_t allocSize = sizeof(StringMapEntry) + keyLength + 1;
+ size_t alignment = alignof(StringMapEntry);
+
+ StringMapEntry *newItem =
+ static_cast<StringMapEntry *>(allocator.Allocate(allocSize, alignment));
+ assert(newItem && "Unhandled out-of-memory");
+
+ // Construct the value.
+ new (newItem) StringMapEntry(keyLength, std::forward<InitTy>(initVals)...);
+
+ // Copy the string information.
+ char *strBuffer = const_cast<char *>(newItem->getKeyData());
+ if (keyLength > 0)
+ memcpy(strBuffer, key.data(), keyLength);
+ strBuffer[keyLength] = 0; // Null terminate for convenience of clients.
+ return newItem;
+ }
+
+ /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded
+ /// into a StringMapEntry, return the StringMapEntry itself.
+ static StringMapEntry &GetStringMapEntryFromKeyData(const char *keyData) {
+ char *ptr = const_cast<char *>(keyData) - sizeof(StringMapEntry<ValueTy>);
+ return *reinterpret_cast<StringMapEntry *>(ptr);
+ }
+
+ /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+ /// specified allocator.
+ template <typename AllocatorTy> void Destroy(AllocatorTy &allocator) {
+ // Free memory referenced by the item.
+ size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
+ this->~StringMapEntry();
+ allocator.Deallocate(static_cast<void *>(this), AllocSize,
+ alignof(StringMapEntry));
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_STRINGMAPENTRY_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/StringRef.h b/contrib/llvm-project/llvm/include/llvm/ADT/StringRef.h
index f06d18720c3a..98c120fe2d2e 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/StringRef.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/StringRef.h
@@ -18,6 +18,9 @@
#include <cstring>
#include <limits>
#include <string>
+#if __cplusplus > 201402L
+#include <string_view>
+#endif
#include <type_traits>
#include <utility>
@@ -51,9 +54,9 @@ namespace llvm {
/// situations where the character data resides in some other buffer, whose
/// lifetime extends past that of the StringRef. For this reason, it is not in
/// general safe to store a StringRef.
- class StringRef {
+ class LLVM_GSL_POINTER StringRef {
public:
- static const size_t npos = ~size_t(0);
+ static constexpr size_t npos = ~size_t(0);
using iterator = const char *;
using const_iterator = const char *;
@@ -111,6 +114,12 @@ namespace llvm {
/*implicit*/ StringRef(const std::string &Str)
: Data(Str.data()), Length(Str.length()) {}
+#if __cplusplus > 201402L
+ /// Construct a string ref from an std::string_view.
+ /*implicit*/ constexpr StringRef(std::string_view Str)
+ : Data(Str.data()), Length(Str.size()) {}
+#endif
+
static StringRef withNullAsEmpty(const char *data) {
return StringRef(data ? data : "");
}
@@ -256,17 +265,20 @@ namespace llvm {
/// The declaration here is extra complicated so that `stringRef = {}`
/// and `stringRef = "abc"` continue to select the move assignment operator.
template <typename T>
- typename std::enable_if<std::is_same<T, std::string>::value,
- StringRef>::type &
+ std::enable_if_t<std::is_same<T, std::string>::value, StringRef> &
operator=(T &&Str) = delete;
/// @}
/// @name Type Conversions
/// @{
- operator std::string() const {
- return str();
+ explicit operator std::string() const { return str(); }
+
+#if __cplusplus > 201402L
+ operator std::string_view() const {
+ return std::string_view(data(), size());
}
+#endif
/// @}
/// @name String Predicates
@@ -495,7 +507,7 @@ namespace llvm {
/// this returns true to signify the error. The string is considered
/// erroneous if empty or if it overflows T.
template <typename T>
- typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
+ std::enable_if_t<std::numeric_limits<T>::is_signed, bool>
getAsInteger(unsigned Radix, T &Result) const {
long long LLVal;
if (getAsSignedInteger(*this, Radix, LLVal) ||
@@ -506,7 +518,7 @@ namespace llvm {
}
template <typename T>
- typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
+ std::enable_if_t<!std::numeric_limits<T>::is_signed, bool>
getAsInteger(unsigned Radix, T &Result) const {
unsigned long long ULLVal;
// The additional cast to unsigned long long is required to avoid the
@@ -529,7 +541,7 @@ namespace llvm {
/// The portion of the string representing the discovered numeric value
/// is removed from the beginning of the string.
template <typename T>
- typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type
+ std::enable_if_t<std::numeric_limits<T>::is_signed, bool>
consumeInteger(unsigned Radix, T &Result) {
long long LLVal;
if (consumeSignedInteger(*this, Radix, LLVal) ||
@@ -540,7 +552,7 @@ namespace llvm {
}
template <typename T>
- typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type
+ std::enable_if_t<!std::numeric_limits<T>::is_signed, bool>
consumeInteger(unsigned Radix, T &Result) {
unsigned long long ULLVal;
if (consumeUnsignedInteger(*this, Radix, ULLVal) ||
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/StringSet.h b/contrib/llvm-project/llvm/include/llvm/ADT/StringSet.h
index 60be09d3c326..63d929399a4e 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/StringSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/StringSet.h
@@ -1,4 +1,4 @@
-//===- StringSet.h - The LLVM Compiler Driver -------------------*- C++ -*-===//
+//===- StringSet.h - An efficient set built on StringMap --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -14,44 +14,38 @@
#define LLVM_ADT_STRINGSET_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Allocator.h"
-#include <cassert>
-#include <initializer_list>
-#include <utility>
namespace llvm {
- /// StringSet - A wrapper for StringMap that provides set-like functionality.
- template <class AllocatorTy = MallocAllocator>
- class StringSet : public StringMap<NoneType, AllocatorTy> {
- using base = StringMap<NoneType, AllocatorTy>;
-
- public:
- StringSet() = default;
- StringSet(std::initializer_list<StringRef> S) {
- for (StringRef X : S)
- insert(X);
- }
- explicit StringSet(AllocatorTy A) : base(A) {}
-
- std::pair<typename base::iterator, bool> insert(StringRef Key) {
- assert(!Key.empty());
- return base::insert(std::make_pair(Key, None));
- }
-
- template <typename InputIt>
- void insert(const InputIt &Begin, const InputIt &End) {
- for (auto It = Begin; It != End; ++It)
- base::insert(std::make_pair(*It, None));
- }
-
- template <typename ValueTy>
- std::pair<typename base::iterator, bool>
- insert(const StringMapEntry<ValueTy> &MapEntry) {
- return insert(MapEntry.getKey());
- }
- };
+/// StringSet - A wrapper for StringMap that provides set-like functionality.
+template <class AllocatorTy = MallocAllocator>
+class StringSet : public StringMap<NoneType, AllocatorTy> {
+ using Base = StringMap<NoneType, AllocatorTy>;
+
+public:
+ StringSet() = default;
+ StringSet(std::initializer_list<StringRef> initializer) {
+ for (StringRef str : initializer)
+ insert(str);
+ }
+ explicit StringSet(AllocatorTy a) : Base(a) {}
+
+ std::pair<typename Base::iterator, bool> insert(StringRef key) {
+ return Base::try_emplace(key);
+ }
+
+ template <typename InputIt>
+ void insert(const InputIt &begin, const InputIt &end) {
+ for (auto it = begin; it != end; ++it)
+ insert(*it);
+ }
+
+ template <typename ValueTy>
+ std::pair<typename Base::iterator, bool>
+ insert(const StringMapEntry<ValueTy> &mapEntry) {
+ return insert(mapEntry.getKey());
+ }
+};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/TinyPtrVector.h b/contrib/llvm-project/llvm/include/llvm/ADT/TinyPtrVector.h
index 6b76d35d4e92..ed20a762f307 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/TinyPtrVector.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/TinyPtrVector.h
@@ -152,10 +152,10 @@ public:
}
// Implicit conversion to ArrayRef<U> if EltTy* implicitly converts to U*.
- template<typename U,
- typename std::enable_if<
- std::is_convertible<ArrayRef<EltTy>, ArrayRef<U>>::value,
- bool>::type = false>
+ template <
+ typename U,
+ std::enable_if_t<std::is_convertible<ArrayRef<EltTy>, ArrayRef<U>>::value,
+ bool> = false>
operator ArrayRef<U>() const {
return operator ArrayRef<EltTy>();
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h b/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h
index 76a754d671fb..6bad18f19244 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Triple.h
@@ -19,6 +19,8 @@
namespace llvm {
+class VersionTuple;
+
/// Triple - Helper class for working with autoconf configuration names. For
/// historical reasons, we also call these 'triples' (they used to contain
/// exactly three fields).
@@ -101,6 +103,7 @@ public:
enum SubArchType {
NoSubArch,
+ ARMSubArch_v8_6a,
ARMSubArch_v8_5a,
ARMSubArch_v8_4a,
ARMSubArch_v8_3a,
@@ -437,17 +440,7 @@ public:
/// compatibility, which handles supporting skewed version numbering schemes
/// used by the "darwin" triples.
bool isMacOSXVersionLT(unsigned Major, unsigned Minor = 0,
- unsigned Micro = 0) const {
- assert(isMacOSX() && "Not an OS X triple!");
-
- // If this is OS X, expect a sane version number.
- if (getOS() == Triple::MacOSX)
- return isOSVersionLT(Major, Minor, Micro);
-
- // Otherwise, compare to the "Darwin" number.
- assert(Major == 10 && "Unexpected major version");
- return isOSVersionLT(Minor + 4, Micro, 0);
- }
+ unsigned Micro = 0) const;
/// isMacOSX - Is this a Mac OS X triple. For legacy reasons, we support both
/// "darwin" and "osx" as OS X triples.
@@ -691,6 +684,13 @@ public:
return getArch() == Triple::nvptx || getArch() == Triple::nvptx64;
}
+ /// Tests whether the target is AMDGCN
+ bool isAMDGCN() const { return getArch() == Triple::amdgcn; }
+
+ bool isAMDGPU() const {
+ return getArch() == Triple::r600 || getArch() == Triple::amdgcn;
+ }
+
/// Tests whether the target is Thumb (little and big endian).
bool isThumb() const {
return getArch() == Triple::thumb || getArch() == Triple::thumbeb;
@@ -731,6 +731,11 @@ public:
return getArch() == Triple::riscv32 || getArch() == Triple::riscv64;
}
+ /// Tests whether the target is SystemZ.
+ bool isSystemZ() const {
+ return getArch() == Triple::systemz;
+ }
+
/// Tests whether the target is x86 (32- or 64-bit).
bool isX86() const {
return getArch() == Triple::x86 || getArch() == Triple::x86_64;
@@ -741,9 +746,14 @@ public:
return getArch() == Triple::ve;
}
+ /// Tests whether the target is wasm (32- and 64-bit).
+ bool isWasm() const {
+ return getArch() == Triple::wasm32 || getArch() == Triple::wasm64;
+ }
+
/// Tests whether the target supports comdat
bool supportsCOMDAT() const {
- return !isOSBinFormatMachO();
+ return !(isOSBinFormatMachO() || isOSBinFormatXCOFF());
}
/// Tests whether the target uses emulated TLS as default.
@@ -850,6 +860,12 @@ public:
/// Merge target triples.
std::string merge(const Triple &Other) const;
+ /// Some platforms have different minimum supported OS versions that
+ /// varies by the architecture specified in the triple. This function
+ /// returns the minimum supported OS version for this triple if one an exists,
+ /// or an invalid version tuple if this triple doesn't have one.
+ VersionTuple getMinimumSupportedOSVersion() const;
+
/// @}
/// @name Static helpers for IDs.
/// @{
@@ -884,6 +900,10 @@ public:
static ArchType getArchTypeForLLVMName(StringRef Str);
/// @}
+
+ /// Returns a canonicalized OS version number for the specified OS.
+ static VersionTuple getCanonicalVersionForOS(OSType OSKind,
+ const VersionTuple &Version);
};
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Twine.h b/contrib/llvm-project/llvm/include/llvm/ADT/Twine.h
index 2dc7486c924f..4140c22aad3d 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/Twine.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Twine.h
@@ -153,11 +153,11 @@ namespace llvm {
/// LHS - The prefix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
- Child LHS = {0};
+ Child LHS;
/// RHS - The suffix in the concatenation, which may be uninitialized for
/// Null or Empty kinds.
- Child RHS = {0};
+ Child RHS;
/// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
NodeKind LHSKind = EmptyKind;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/TypeSwitch.h b/contrib/llvm-project/llvm/include/llvm/ADT/TypeSwitch.h
new file mode 100644
index 000000000000..bfcb2064301d
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/TypeSwitch.h
@@ -0,0 +1,176 @@
+//===- TypeSwitch.h - Switch functionality for RTTI casting -*- C++ -*-----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the TypeSwitch template, which mimics a switch()
+// statement whose cases are type names.
+//
+//===-----------------------------------------------------------------------===/
+
+#ifndef LLVM_ADT_TYPESWITCH_H
+#define LLVM_ADT_TYPESWITCH_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+namespace detail {
+
+template <typename DerivedT, typename T> class TypeSwitchBase {
+public:
+ TypeSwitchBase(const T &value) : value(value) {}
+ TypeSwitchBase(TypeSwitchBase &&other) : value(other.value) {}
+ ~TypeSwitchBase() = default;
+
+ /// TypeSwitchBase is not copyable.
+ TypeSwitchBase(const TypeSwitchBase &) = delete;
+ void operator=(const TypeSwitchBase &) = delete;
+ void operator=(TypeSwitchBase &&other) = delete;
+
+ /// Invoke a case on the derived class with multiple case types.
+ template <typename CaseT, typename CaseT2, typename... CaseTs,
+ typename CallableT>
+ DerivedT &Case(CallableT &&caseFn) {
+ DerivedT &derived = static_cast<DerivedT &>(*this);
+ return derived.template Case<CaseT>(caseFn)
+ .template Case<CaseT2, CaseTs...>(caseFn);
+ }
+
+ /// Invoke a case on the derived class, inferring the type of the Case from
+ /// the first input of the given callable.
+ /// Note: This inference rules for this overload are very simple: strip
+ /// pointers and references.
+ template <typename CallableT> DerivedT &Case(CallableT &&caseFn) {
+ using Traits = function_traits<std::decay_t<CallableT>>;
+ using CaseT = std::remove_cv_t<std::remove_pointer_t<
+ std::remove_reference_t<typename Traits::template arg_t<0>>>>;
+
+ DerivedT &derived = static_cast<DerivedT &>(*this);
+ return derived.template Case<CaseT>(std::forward<CallableT>(caseFn));
+ }
+
+protected:
+ /// Trait to check whether `ValueT` provides a 'dyn_cast' method with type
+ /// `CastT`.
+ template <typename ValueT, typename CastT>
+ using has_dyn_cast_t =
+ decltype(std::declval<ValueT &>().template dyn_cast<CastT>());
+
+ /// Attempt to dyn_cast the given `value` to `CastT`. This overload is
+ /// selected if `value` already has a suitable dyn_cast method.
+ template <typename CastT, typename ValueT>
+ static auto castValue(
+ ValueT value,
+ typename std::enable_if_t<
+ is_detected<has_dyn_cast_t, ValueT, CastT>::value> * = nullptr) {
+ return value.template dyn_cast<CastT>();
+ }
+
+ /// Attempt to dyn_cast the given `value` to `CastT`. This overload is
+ /// selected if llvm::dyn_cast should be used.
+ template <typename CastT, typename ValueT>
+ static auto castValue(
+ ValueT value,
+ typename std::enable_if_t<
+ !is_detected<has_dyn_cast_t, ValueT, CastT>::value> * = nullptr) {
+ return dyn_cast<CastT>(value);
+ }
+
+ /// The root value we are switching on.
+ const T value;
+};
+} // end namespace detail
+
+/// This class implements a switch-like dispatch statement for a value of 'T'
+/// using dyn_cast functionality. Each `Case<T>` takes a callable to be invoked
+/// if the root value isa<T>, the callable is invoked with the result of
+/// dyn_cast<T>() as a parameter.
+///
+/// Example:
+/// Operation *op = ...;
+/// LogicalResult result = TypeSwitch<Operation *, LogicalResult>(op)
+/// .Case<ConstantOp>([](ConstantOp op) { ... })
+/// .Default([](Operation *op) { ... });
+///
+template <typename T, typename ResultT = void>
+class TypeSwitch : public detail::TypeSwitchBase<TypeSwitch<T, ResultT>, T> {
+public:
+ using BaseT = detail::TypeSwitchBase<TypeSwitch<T, ResultT>, T>;
+ using BaseT::BaseT;
+ using BaseT::Case;
+ TypeSwitch(TypeSwitch &&other) = default;
+
+ /// Add a case on the given type.
+ template <typename CaseT, typename CallableT>
+ TypeSwitch<T, ResultT> &Case(CallableT &&caseFn) {
+ if (result)
+ return *this;
+
+ // Check to see if CaseT applies to 'value'.
+ if (auto caseValue = BaseT::template castValue<CaseT>(this->value))
+ result = caseFn(caseValue);
+ return *this;
+ }
+
+ /// As a default, invoke the given callable within the root value.
+ template <typename CallableT>
+ LLVM_NODISCARD ResultT Default(CallableT &&defaultFn) {
+ if (result)
+ return std::move(*result);
+ return defaultFn(this->value);
+ }
+
+ LLVM_NODISCARD
+ operator ResultT() {
+ assert(result && "Fell off the end of a type-switch");
+ return std::move(*result);
+ }
+
+private:
+ /// The pointer to the result of this switch statement, once known,
+ /// null before that.
+ Optional<ResultT> result;
+};
+
+/// Specialization of TypeSwitch for void returning callables.
+template <typename T>
+class TypeSwitch<T, void>
+ : public detail::TypeSwitchBase<TypeSwitch<T, void>, T> {
+public:
+ using BaseT = detail::TypeSwitchBase<TypeSwitch<T, void>, T>;
+ using BaseT::BaseT;
+ using BaseT::Case;
+ TypeSwitch(TypeSwitch &&other) = default;
+
+ /// Add a case on the given type.
+ template <typename CaseT, typename CallableT>
+ TypeSwitch<T, void> &Case(CallableT &&caseFn) {
+ if (foundMatch)
+ return *this;
+
+ // Check to see if any of the types apply to 'value'.
+ if (auto caseValue = BaseT::template castValue<CaseT>(this->value)) {
+ caseFn(caseValue);
+ foundMatch = true;
+ }
+ return *this;
+ }
+
+ /// As a default, invoke the given callable within the root value.
+ template <typename CallableT> void Default(CallableT &&defaultFn) {
+ if (!foundMatch)
+ defaultFn(this->value);
+ }
+
+private:
+ /// A flag detailing if we have already found a match.
+ bool foundMatch = false;
+};
+} // end namespace llvm
+
+#endif // LLVM_ADT_TYPESWITCH_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/Waymarking.h b/contrib/llvm-project/llvm/include/llvm/ADT/Waymarking.h
new file mode 100644
index 000000000000..f00bc106938f
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/Waymarking.h
@@ -0,0 +1,325 @@
+//===- Waymarking.h - Array waymarking algorithm ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility to backtrace an array's head, from a pointer into it. For the
+// backtrace to work, we use "Waymarks", which are special tags embedded into
+// the array's elements.
+//
+// A Tag of n-bits (in size) is composed as follows:
+//
+// bits: | n-1 | n-2 ... 0 |
+// .---------.------------------------------------.
+// |Stop Mask|(2^(n-1))-ary numeric system - digit|
+// '---------'------------------------------------'
+//
+// Backtracing is done as follows:
+// Walk back (starting from a given pointer to an element into the array), until
+// a tag with a "Stop Mask" is reached. Then start calculating the "Offset" from
+// the array's head, by picking up digits along the way, until another stop is
+// reached. The "Offset" is then subtracted from the current pointer, and the
+// result is the array's head.
+// A special case - if we first encounter a Tag with a Stop and a zero digit,
+// then this is already the head.
+//
+// For example:
+// In case of 2 bits:
+//
+// Tags:
+// x0 - binary digit 0
+// x1 - binary digit 1
+// 1x - stop and calculate (s)
+//
+// Array:
+// .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
+// head -> |s0 |s1 | 0 |s1 | 0 | 0 |s1 | 1 | 1 |s1 | 0 | 1 | 0 |s1 | 0 | 1 |
+// '---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
+// |-1 |-2 |-4 |-7 |-10 |-14
+// <_ | | | | | |
+// <_____ | | | | |
+// <_____________ | | | |
+// <_________________________ | | |
+// <_____________________________________ | |
+// <_____________________________________________________ |
+//
+//
+// In case of 3 bits:
+//
+// Tags:
+// x00 - quaternary digit 0
+// x01 - quaternary digit 1
+// x10 - quaternary digit 2
+// x11 - quaternary digit 3
+// 1xy - stop and calculate (s)
+//
+// Array:
+// .---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.
+// head -> |s0 |s1 |s2 |s3 | 0 |s1 | 2 |s1 | 0 |s2 | 2 |s2 | 0 |s3 | 2 |s3 |
+// '---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'
+// |-1 |-2 |-3 |-4 |-6 |-8 |-10 |-12 |-14 |-16
+// <_ | | | | | | | | | |
+// <_____ | | | | | | | | |
+// <_________ | | | | | | | |
+// <_____________ | | | | | | |
+// <_____________________ | | | | | |
+// <_____________________________ | | | | |
+// <_____________________________________ | | | |
+// <_____________________________________________ | | |
+// <_____________________________________________________ | |
+// <_____________________________________________________________ |
+//
+//
+// The API introduce 2 functions:
+// 1. fillWaymarks
+// 2. followWaymarks
+//
+// Example:
+// int N = 10;
+// int M = 5;
+// int **A = new int *[N + M]; // Define the array.
+// for (int I = 0; I < N + M; ++I)
+// A[I] = new int(I);
+//
+// fillWaymarks(A, A + N); // Set the waymarks for the first N elements
+// // of the array.
+// // Note that it must be done AFTER we fill
+// // the array's elements.
+//
+// ... // Elements which are not in the range
+// // [A, A+N) will not be marked, and we won't
+// // be able to call followWaymarks on them.
+//
+// ... // Elements which will be changed after the
+// // call to fillWaymarks, will have to be
+// // retagged.
+//
+// fillWaymarks(A + N, A + N + M, N); // Set the waymarks of the remaining M
+// // elements.
+// ...
+// int **It = A + N + 1;
+// int **B = followWaymarks(It); // Find the head of the array containing It.
+// assert(B == A);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_WAYMARKING_H
+#define LLVM_ADT_WAYMARKING_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+
+namespace llvm {
+
+namespace detail {
+
+template <unsigned NumBits> struct WaymarkingTraits {
+ enum : unsigned {
+ // The number of bits of a Waymarking Tag.
+ NUM_BITS = NumBits,
+
+ // A Tag is composed from a Mark and a Stop mask.
+ MARK_SIZE = NUM_BITS - 1,
+ STOP_MASK = (1 << MARK_SIZE),
+ MARK_MASK = (STOP_MASK - 1),
+ TAG_MASK = (MARK_MASK | STOP_MASK),
+
+ // The number of pre-computed tags (for fast fill).
+ NUM_STATIC_TAGS = 32
+ };
+
+private:
+ // Add a new tag, calculated from Count and Stop, to the Vals pack, while
+ // continuing recursively to decrease Len down to 0.
+ template <unsigned Len, bool Stop, unsigned Count, uint8_t... Vals>
+ struct AddTag;
+
+ // Delegate to the specialized AddTag according to the need of a Stop mask.
+ template <unsigned Len, unsigned Count, uint8_t... Vals> struct GenTag {
+ typedef
+ typename AddTag<Len, (Count <= MARK_MASK), Count, Vals...>::Xdata Xdata;
+ };
+
+ // Start adding tags while calculating the next Count, which is actually the
+ // number of already calculated tags (equivalent to the position in the
+ // array).
+ template <unsigned Len, uint8_t... Vals> struct GenOffset {
+ typedef typename GenTag<Len, sizeof...(Vals), Vals...>::Xdata Xdata;
+ };
+
+ // Add the tag and remove it from Count.
+ template <unsigned Len, unsigned Count, uint8_t... Vals>
+ struct AddTag<Len, false, Count, Vals...> {
+ typedef typename GenTag<Len - 1, (Count >> MARK_SIZE), Vals...,
+ Count & MARK_MASK>::Xdata Xdata;
+ };
+
+ // We have reached the end of this Count, so start with a new Count.
+ template <unsigned Len, unsigned Count, uint8_t... Vals>
+ struct AddTag<Len, true, Count, Vals...> {
+ typedef typename GenOffset<Len - 1, Vals...,
+ (Count & MARK_MASK) | STOP_MASK>::Xdata Xdata;
+ };
+
+ template <unsigned Count, uint8_t... Vals> struct TagsData {
+ // The remaining number for calculating the next tag, following the last one
+ // in Values.
+ static const unsigned Remain = Count;
+
+ // The array of ordered pre-computed Tags.
+ static const uint8_t Values[sizeof...(Vals)];
+ };
+
+ // Specialize the case when Len equals 0, as the recursion stop condition.
+ template <unsigned Count, uint8_t... Vals>
+ struct AddTag<0, false, Count, Vals...> {
+ typedef TagsData<Count, Vals...> Xdata;
+ };
+
+ template <unsigned Count, uint8_t... Vals>
+ struct AddTag<0, true, Count, Vals...> {
+ typedef TagsData<Count, Vals...> Xdata;
+ };
+
+public:
+ typedef typename GenOffset<NUM_STATIC_TAGS>::Xdata Tags;
+};
+
+template <unsigned NumBits>
+template <unsigned Count, uint8_t... Vals>
+const uint8_t WaymarkingTraits<NumBits>::TagsData<
+ Count, Vals...>::Values[sizeof...(Vals)] = {Vals...};
+
+} // end namespace detail
+
+/// This class is responsible for tagging (and retrieving the tag of) a given
+/// element of type T.
+template <class T, class WTraits = detail::WaymarkingTraits<
+ PointerLikeTypeTraits<T>::NumLowBitsAvailable>>
+struct Waymarker {
+ using Traits = WTraits;
+ static void setWaymark(T &N, unsigned Tag) { N.setWaymark(Tag); }
+ static unsigned getWaymark(const T &N) { return N.getWaymark(); }
+};
+
+template <class T, class WTraits> struct Waymarker<T *, WTraits> {
+ using Traits = WTraits;
+ static void setWaymark(T *&N, unsigned Tag) {
+ reinterpret_cast<uintptr_t &>(N) |= static_cast<uintptr_t>(Tag);
+ }
+ static unsigned getWaymark(const T *N) {
+ return static_cast<unsigned>(reinterpret_cast<uintptr_t>(N)) &
+ Traits::TAG_MASK;
+ }
+};
+
+/// Sets up the waymarking algorithm's tags for a given range [Begin, End).
+///
+/// \param Begin The beginning of the range to mark with tags (inclusive).
+/// \param End The ending of the range to mark with tags (exclusive).
+/// \param Offset The position in the supposed tags array from which to start
+/// marking the given range.
+template <class TIter, class Marker = Waymarker<
+ typename std::iterator_traits<TIter>::value_type>>
+void fillWaymarks(TIter Begin, TIter End, size_t Offset = 0) {
+ if (Begin == End)
+ return;
+
+ size_t Count = Marker::Traits::Tags::Remain;
+ if (Offset <= Marker::Traits::NUM_STATIC_TAGS) {
+ // Start by filling the pre-calculated tags, starting from the given offset.
+ while (Offset != Marker::Traits::NUM_STATIC_TAGS) {
+ Marker::setWaymark(*Begin, Marker::Traits::Tags::Values[Offset]);
+
+ ++Offset;
+ ++Begin;
+
+ if (Begin == End)
+ return;
+ }
+ } else {
+ // The given offset is larger than the number of pre-computed tags, so we
+ // must do it the hard way.
+ // Calculate the next remaining Count, as if we have filled the tags up to
+ // the given offset.
+ size_t Off = Marker::Traits::NUM_STATIC_TAGS;
+ do {
+ ++Off;
+
+ unsigned Tag = Count & Marker::Traits::MARK_MASK;
+
+ // If the count can fit into the tag, then the counting must stop.
+ if (Count <= Marker::Traits::MARK_MASK) {
+ Tag |= Marker::Traits::STOP_MASK;
+ Count = Off;
+ } else
+ Count >>= Marker::Traits::MARK_SIZE;
+ } while (Off != Offset);
+ }
+
+ // By now, we have the matching remaining Count for the current offset.
+ do {
+ ++Offset;
+
+ unsigned Tag = Count & Marker::Traits::MARK_MASK;
+
+ // If the count can fit into the tag, then the counting must stop.
+ if (Count <= Marker::Traits::MARK_MASK) {
+ Tag |= Marker::Traits::STOP_MASK;
+ Count = Offset;
+ } else
+ Count >>= Marker::Traits::MARK_SIZE;
+
+ Marker::setWaymark(*Begin, Tag);
+ ++Begin;
+ } while (Begin != End);
+}
+
+/// Sets up the waymarking algorithm's tags for a given range.
+///
+/// \param Range The range to mark with tags.
+/// \param Offset The position in the supposed tags array from which to start
+/// marking the given range.
+template <typename R, class Marker = Waymarker<typename std::remove_reference<
+ decltype(*std::begin(std::declval<R &>()))>::type>>
+void fillWaymarks(R &&Range, size_t Offset = 0) {
+ return fillWaymarks<decltype(std::begin(std::declval<R &>())), Marker>(
+ adl_begin(Range), adl_end(Range), Offset);
+}
+
+/// Retrieves the element marked with tag of only STOP_MASK, by following the
+/// waymarks. This is the first element in a range passed to a previous call to
+/// \c fillWaymarks with \c Offset 0.
+///
+/// For the trivial usage of calling \c fillWaymarks(Array), and \I is an
+/// iterator inside \c Array, this function retrieves the head of \c Array, by
+/// following the waymarks.
+///
+/// \param I The iterator into an array which was marked by the waymarking tags
+/// (by a previous call to \c fillWaymarks).
+template <class TIter, class Marker = Waymarker<
+ typename std::iterator_traits<TIter>::value_type>>
+TIter followWaymarks(TIter I) {
+ unsigned Tag;
+ do
+ Tag = Marker::getWaymark(*I--);
+ while (!(Tag & Marker::Traits::STOP_MASK));
+
+ // Special case for the first Use.
+ if (Tag != Marker::Traits::STOP_MASK) {
+ ptrdiff_t Offset = Tag & Marker::Traits::MARK_MASK;
+ while (!((Tag = Marker::getWaymark(*I)) & Marker::Traits::STOP_MASK)) {
+ Offset = (Offset << Marker::Traits::MARK_SIZE) + Tag;
+ --I;
+ }
+ I -= Offset;
+ }
+ return ++I;
+}
+
+} // end namespace llvm
+
+#endif // LLVM_ADT_WAYMARKING_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/bit.h b/contrib/llvm-project/llvm/include/llvm/ADT/bit.h
index a790d5ed2d21..d76bc6c6046c 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/bit.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/bit.h
@@ -22,23 +22,28 @@ namespace llvm {
// This implementation of bit_cast is different from the C++17 one in two ways:
// - It isn't constexpr because that requires compiler support.
// - It requires trivially-constructible To, to avoid UB in the implementation.
-template <typename To, typename From
- , typename = typename std::enable_if<sizeof(To) == sizeof(From)>::type
+template <
+ typename To, typename From,
+ typename = std::enable_if_t<sizeof(To) == sizeof(From)>
#if (__has_feature(is_trivially_constructible) && defined(_LIBCPP_VERSION)) || \
(defined(__GNUC__) && __GNUC__ >= 5)
- , typename = typename std::is_trivially_constructible<To>::type
+ ,
+ typename = std::enable_if_t<std::is_trivially_constructible<To>::value>
#elif __has_feature(is_trivially_constructible)
- , typename = typename std::enable_if<__is_trivially_constructible(To)>::type
+ ,
+ typename = std::enable_if_t<__is_trivially_constructible(To)>
#else
// See comment below.
#endif
#if (__has_feature(is_trivially_copyable) && defined(_LIBCPP_VERSION)) || \
(defined(__GNUC__) && __GNUC__ >= 5)
- , typename = typename std::enable_if<std::is_trivially_copyable<To>::value>::type
- , typename = typename std::enable_if<std::is_trivially_copyable<From>::value>::type
+ ,
+ typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
+ typename = std::enable_if_t<std::is_trivially_copyable<From>::value>
#elif __has_feature(is_trivially_copyable)
- , typename = typename std::enable_if<__is_trivially_copyable(To)>::type
- , typename = typename std::enable_if<__is_trivially_copyable(From)>::type
+ ,
+ typename = std::enable_if_t<__is_trivially_copyable(To)>,
+ typename = std::enable_if_t<__is_trivially_copyable(From)>
#else
// This case is GCC 4.x. clang with libc++ or libstdc++ never get here. Unlike
// llvm/Support/type_traits.h's is_trivially_copyable we don't want to
@@ -46,7 +51,7 @@ template <typename To, typename From
// compilation failures on the bots instead of locally. That's acceptable
// because it's very few developers, and only until we move past C++11.
#endif
->
+ >
inline To bit_cast(const From &from) noexcept {
To to;
std::memcpy(&to, &from, sizeof(To));
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/fallible_iterator.h b/contrib/llvm-project/llvm/include/llvm/ADT/fallible_iterator.h
index 6501ad2233cd..a196d8866b51 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/fallible_iterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/fallible_iterator.h
@@ -86,7 +86,7 @@ public:
return fallible_iterator(std::move(I), &Err);
}
- /// Construct a fallible iteratro that can be used as an end-of-range value.
+ /// Construct a fallible iterator that can be used as an end-of-range value.
///
/// A value created by this method can be dereferenced (if the underlying
/// value points at a valid value) and compared, but not incremented or
@@ -96,12 +96,10 @@ public:
}
/// Forward dereference to the underlying iterator.
- auto operator*() -> decltype(*std::declval<Underlying>()) { return *I; }
+ decltype(auto) operator*() { return *I; }
/// Forward const dereference to the underlying iterator.
- auto operator*() const -> decltype(*std::declval<const Underlying>()) {
- return *I;
- }
+ decltype(auto) operator*() const { return *I; }
/// Forward structure dereference to the underlying iterator (if the
/// underlying iterator supports it).
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ilist.h b/contrib/llvm-project/llvm/include/llvm/ADT/ilist.h
index 06c7abff965f..d5a1f286b177 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ilist.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ilist.h
@@ -198,10 +198,12 @@ public:
iplist_impl &operator=(const iplist_impl &) = delete;
iplist_impl(iplist_impl &&X)
- : TraitsT(std::move(X)), IntrusiveListT(std::move(X)) {}
+ : TraitsT(std::move(static_cast<TraitsT &>(X))),
+ IntrusiveListT(std::move(static_cast<IntrusiveListT &>(X))) {}
iplist_impl &operator=(iplist_impl &&X) {
- *static_cast<TraitsT *>(this) = std::move(X);
- *static_cast<IntrusiveListT *>(this) = std::move(X);
+ *static_cast<TraitsT *>(this) = std::move(static_cast<TraitsT &>(X));
+ *static_cast<IntrusiveListT *>(this) =
+ std::move(static_cast<IntrusiveListT &>(X));
return *this;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h b/contrib/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h
index cbe5cefa96d1..be876347907b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/ilist_iterator.h
@@ -88,15 +88,14 @@ public:
// This is templated so that we can allow constructing a const iterator from
// a nonconst iterator...
template <bool RHSIsConst>
- ilist_iterator(
- const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS,
- typename std::enable_if<IsConst || !RHSIsConst, void *>::type = nullptr)
+ ilist_iterator(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS,
+ std::enable_if_t<IsConst || !RHSIsConst, void *> = nullptr)
: NodePtr(RHS.NodePtr) {}
// This is templated so that we can allow assigning to a const iterator from
// a nonconst iterator...
template <bool RHSIsConst>
- typename std::enable_if<IsConst || !RHSIsConst, ilist_iterator &>::type
+ std::enable_if_t<IsConst || !RHSIsConst, ilist_iterator &>
operator=(const ilist_iterator<OptionsT, IsReverse, RHSIsConst> &RHS) {
NodePtr = RHS.NodePtr;
return *this;
diff --git a/contrib/llvm-project/llvm/include/llvm/ADT/iterator.h b/contrib/llvm-project/llvm/include/llvm/ADT/iterator.h
index 8fd5c11a2dcb..9a1f6e1511e7 100644
--- a/contrib/llvm-project/llvm/include/llvm/ADT/iterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/ADT/iterator.h
@@ -194,14 +194,14 @@ template <
typename T = typename std::iterator_traits<WrappedIteratorT>::value_type,
typename DifferenceTypeT =
typename std::iterator_traits<WrappedIteratorT>::difference_type,
- typename PointerT = typename std::conditional<
+ typename PointerT = std::conditional_t<
std::is_same<T, typename std::iterator_traits<
WrappedIteratorT>::value_type>::value,
- typename std::iterator_traits<WrappedIteratorT>::pointer, T *>::type,
- typename ReferenceT = typename std::conditional<
+ typename std::iterator_traits<WrappedIteratorT>::pointer, T *>,
+ typename ReferenceT = std::conditional_t<
std::is_same<T, typename std::iterator_traits<
WrappedIteratorT>::value_type>::value,
- typename std::iterator_traits<WrappedIteratorT>::reference, T &>::type>
+ typename std::iterator_traits<WrappedIteratorT>::reference, T &>>
class iterator_adaptor_base
: public iterator_facade_base<DerivedT, IteratorCategoryT, T,
DifferenceTypeT, PointerT, ReferenceT> {
@@ -281,8 +281,8 @@ public:
/// using iterator = pointee_iterator<SmallVectorImpl<T *>::iterator>;
/// \endcode
template <typename WrappedIteratorT,
- typename T = typename std::remove_reference<
- decltype(**std::declval<WrappedIteratorT>())>::type>
+ typename T = std::remove_reference_t<decltype(
+ **std::declval<WrappedIteratorT>())>>
struct pointee_iterator
: iterator_adaptor_base<
pointee_iterator<WrappedIteratorT, T>, WrappedIteratorT,
@@ -334,9 +334,11 @@ make_pointer_range(RangeT &&Range) {
}
template <typename WrappedIteratorT,
- typename T1 = typename std::remove_reference<decltype(**std::declval<WrappedIteratorT>())>::type,
- typename T2 = typename std::add_pointer<T1>::type>
-using raw_pointer_iterator = pointer_iterator<pointee_iterator<WrappedIteratorT, T1>, T2>;
+ typename T1 = std::remove_reference_t<decltype(
+ **std::declval<WrappedIteratorT>())>,
+ typename T2 = std::add_pointer_t<T1>>
+using raw_pointer_iterator =
+ pointer_iterator<pointee_iterator<WrappedIteratorT, T1>, T2>;
// Wrapper iterator over iterator ItType, adding DataRef to the type of ItType,
// to create NodeRef = std::pair<InnerTypeOfItType, DataRef>.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/AliasAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/AliasAnalysis.h
index 7c42a261ebb6..c35ee2f499de 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/AliasAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/AliasAnalysis.h
@@ -59,7 +59,6 @@ class AnalysisUsage;
class BasicAAResult;
class BasicBlock;
class DominatorTree;
-class OrderedBasicBlock;
class Value;
/// The possible results of an alias query.
@@ -226,11 +225,21 @@ enum FunctionModRefBehavior {
/// non-volatile loads from objects pointed to by its pointer-typed
/// arguments, with arbitrary offsets.
///
- /// This property corresponds to the IntrReadArgMem LLVM intrinsic flag.
+ /// This property corresponds to the combination of the IntrReadMem
+ /// and IntrArgMemOnly LLVM intrinsic flags.
FMRB_OnlyReadsArgumentPointees =
FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::Ref),
/// The only memory references in this function (if it has any) are
+ /// non-volatile stores from objects pointed to by its pointer-typed
+ /// arguments, with arbitrary offsets.
+ ///
+ /// This property corresponds to the combination of the IntrWriteMem
+ /// and IntrArgMemOnly LLVM intrinsic flags.
+ FMRB_OnlyWritesArgumentPointees =
+ FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::Mod),
+
+ /// The only memory references in this function (if it has any) are
/// non-volatile loads and stores from objects pointed to by its
/// pointer-typed arguments, with arbitrary offsets.
///
@@ -239,12 +248,48 @@ enum FunctionModRefBehavior {
FMRL_ArgumentPointees | static_cast<int>(ModRefInfo::ModRef),
/// The only memory references in this function (if it has any) are
+ /// reads of memory that is otherwise inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR inaccessiblememonly attribute.
+ FMRB_OnlyReadsInaccessibleMem =
+ FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::Ref),
+
+ /// The only memory references in this function (if it has any) are
+ /// writes to memory that is otherwise inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR inaccessiblememonly attribute.
+ FMRB_OnlyWritesInaccessibleMem =
+ FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::Mod),
+
+ /// The only memory references in this function (if it has any) are
/// references of memory that is otherwise inaccessible via LLVM IR.
///
/// This property corresponds to the LLVM IR inaccessiblememonly attribute.
FMRB_OnlyAccessesInaccessibleMem =
FMRL_InaccessibleMem | static_cast<int>(ModRefInfo::ModRef),
+ /// The function may perform non-volatile loads from objects pointed
+ /// to by its pointer-typed arguments, with arbitrary offsets, and
+ /// it may also perform loads of memory that is otherwise
+ /// inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR
+ /// inaccessiblemem_or_argmemonly attribute.
+ FMRB_OnlyReadsInaccessibleOrArgMem = FMRL_InaccessibleMem |
+ FMRL_ArgumentPointees |
+ static_cast<int>(ModRefInfo::Ref),
+
+ /// The function may perform non-volatile stores to objects pointed
+ /// to by its pointer-typed arguments, with arbitrary offsets, and
+ /// it may also perform stores of memory that is otherwise
+ /// inaccessible via LLVM IR.
+ ///
+ /// This property corresponds to the LLVM IR
+ /// inaccessiblemem_or_argmemonly attribute.
+ FMRB_OnlyWritesInaccessibleOrArgMem = FMRL_InaccessibleMem |
+ FMRL_ArgumentPointees |
+ static_cast<int>(ModRefInfo::Mod),
+
/// The function may perform non-volatile loads and stores of objects
/// pointed to by its pointer-typed arguments, with arbitrary offsets, and
/// it may also perform loads and stores of memory that is otherwise
@@ -269,7 +314,7 @@ enum FunctionModRefBehavior {
//
// This property corresponds to the LLVM IR 'writeonly' attribute.
// This property corresponds to the IntrWriteMem LLVM intrinsic flag.
- FMRB_DoesNotReadMemory = FMRL_Anywhere | static_cast<int>(ModRefInfo::Mod),
+ FMRB_OnlyWritesMemory = FMRL_Anywhere | static_cast<int>(ModRefInfo::Mod),
/// This indicates that the function could not be classified into one of the
/// behaviors above.
@@ -643,19 +688,16 @@ public:
/// Return information about whether a particular call site modifies
/// or reads the specified memory location \p MemLoc before instruction \p I
- /// in a BasicBlock. An ordered basic block \p OBB can be used to speed up
- /// instruction ordering queries inside the BasicBlock containing \p I.
+ /// in a BasicBlock.
/// Early exits in callCapturesBefore may lead to ModRefInfo::Must not being
/// set.
ModRefInfo callCapturesBefore(const Instruction *I,
- const MemoryLocation &MemLoc, DominatorTree *DT,
- OrderedBasicBlock *OBB = nullptr);
+ const MemoryLocation &MemLoc, DominatorTree *DT);
/// A convenience wrapper to synthesize a memory location.
ModRefInfo callCapturesBefore(const Instruction *I, const Value *P,
- LocationSize Size, DominatorTree *DT,
- OrderedBasicBlock *OBB = nullptr) {
- return callCapturesBefore(I, MemoryLocation(P, Size), DT, OBB);
+ LocationSize Size, DominatorTree *DT) {
+ return callCapturesBefore(I, MemoryLocation(P, Size), DT);
}
/// @}
@@ -1143,8 +1185,8 @@ private:
static void getModuleAAResultImpl(Function &F, FunctionAnalysisManager &AM,
AAResults &AAResults) {
auto &MAMProxy = AM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
- auto &MAM = MAMProxy.getManager();
- if (auto *R = MAM.template getCachedResult<AnalysisT>(*F.getParent())) {
+ if (auto *R =
+ MAMProxy.template getCachedResult<AnalysisT>(*F.getParent())) {
AAResults.addAAResult(*R);
MAMProxy
.template registerOuterAnalysisInvalidation<AnalysisT, AAManager>();
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/AliasSetTracker.h b/contrib/llvm-project/llvm/include/llvm/Analysis/AliasSetTracker.h
index e94a758b06ba..690a94d9cf2c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/AliasSetTracker.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/AliasSetTracker.h
@@ -87,12 +87,7 @@ class AliasSet : public ilist_node<AliasSet> {
AAInfo = NewAAInfo;
else {
AAMDNodes Intersection(AAInfo.intersect(NewAAInfo));
- if (!Intersection.TBAA || !Intersection.Scope ||
- !Intersection.NoAlias) {
- // NewAAInfo conflicts with AAInfo.
- AAInfo = DenseMapInfo<AAMDNodes>::getTombstoneKey();
- SizeChanged = true;
- }
+ SizeChanged |= Intersection != AAInfo;
AAInfo = Intersection;
}
return SizeChanged;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/AssumeBundleQueries.h b/contrib/llvm-project/llvm/include/llvm/Analysis/AssumeBundleQueries.h
new file mode 100644
index 000000000000..4d2884284d67
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/AssumeBundleQueries.h
@@ -0,0 +1,167 @@
+//===- AssumeBundleQueries.h - utilities to query assume bundles *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contain tools to query into assume bundles. assume bundles can be
+// built using utilities from Transform/Utils/AssumeBundleBuilder.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEQUERIES_H
+#define LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEQUERIES_H
+
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+class IntrinsicInst;
+class AssumptionCache;
+class DominatorTree;
+
+/// Index of elements in the operand bundle.
+/// If the element exist it is guaranteed to be what is specified in this enum
+/// but it may not exist.
+enum AssumeBundleArg {
+ ABA_WasOn = 0,
+ ABA_Argument = 1,
+};
+
+/// Query the operand bundle of an llvm.assume to find a single attribute of
+/// the specified kind applied on a specified Value.
+///
+/// This has a non-constant complexity. It should only be used when a single
+/// attribute is going to be queried.
+///
+/// Return true iff the queried attribute was found.
+/// If ArgVal is set. the argument will be stored to ArgVal.
+bool hasAttributeInAssume(CallInst &AssumeCI, Value *IsOn, StringRef AttrName,
+ uint64_t *ArgVal = nullptr);
+inline bool hasAttributeInAssume(CallInst &AssumeCI, Value *IsOn,
+ Attribute::AttrKind Kind,
+ uint64_t *ArgVal = nullptr) {
+ return hasAttributeInAssume(AssumeCI, IsOn,
+ Attribute::getNameFromAttrKind(Kind), ArgVal);
+}
+
+template<> struct DenseMapInfo<Attribute::AttrKind> {
+ static Attribute::AttrKind getEmptyKey() {
+ return Attribute::EmptyKey;
+ }
+ static Attribute::AttrKind getTombstoneKey() {
+ return Attribute::TombstoneKey;
+ }
+ static unsigned getHashValue(Attribute::AttrKind AK) {
+ return hash_combine(AK);
+ }
+ static bool isEqual(Attribute::AttrKind LHS, Attribute::AttrKind RHS) {
+ return LHS == RHS;
+ }
+};
+
+/// The map Key contains the Value on for which the attribute is valid and
+/// the Attribute that is valid for that value.
+/// If the Attribute is not on any value, the Value is nullptr.
+using RetainedKnowledgeKey = std::pair<Value *, Attribute::AttrKind>;
+
+struct MinMax {
+ unsigned Min;
+ unsigned Max;
+};
+
+/// A mapping from intrinsics (=`llvm.assume` calls) to a value range
+/// (=knowledge) that is encoded in them. How the value range is interpreted
+/// depends on the RetainedKnowledgeKey that was used to get this out of the
+/// RetainedKnowledgeMap.
+using Assume2KnowledgeMap = DenseMap<IntrinsicInst *, MinMax>;
+
+using RetainedKnowledgeMap =
+ DenseMap<RetainedKnowledgeKey, Assume2KnowledgeMap>;
+
+/// Insert into the map all the informations contained in the operand bundles of
+/// the llvm.assume. This should be used instead of hasAttributeInAssume when
+/// many queries are going to be made on the same llvm.assume.
+/// String attributes are not inserted in the map.
+/// If the IR changes the map will be outdated.
+void fillMapFromAssume(CallInst &AssumeCI, RetainedKnowledgeMap &Result);
+
+/// Represent one information held inside an operand bundle of an llvm.assume.
+/// AttrKind is the property that holds.
+/// WasOn if not null is that Value for which AttrKind holds.
+/// ArgValue is optionally an argument of the attribute.
+/// For example if we know that %P has an alignment of at least four:
+/// - AttrKind will be Attribute::Alignment.
+/// - WasOn will be %P.
+/// - ArgValue will be 4.
+struct RetainedKnowledge {
+ Attribute::AttrKind AttrKind = Attribute::None;
+ unsigned ArgValue = 0;
+ Value *WasOn = nullptr;
+ bool operator==(RetainedKnowledge Other) const {
+ return AttrKind == Other.AttrKind && WasOn == Other.WasOn &&
+ ArgValue == Other.ArgValue;
+ }
+ bool operator!=(RetainedKnowledge Other) const { return !(*this == Other); }
+ operator bool() const { return AttrKind != Attribute::None; }
+ static RetainedKnowledge none() { return RetainedKnowledge{}; }
+};
+
+/// Retreive the information help by Assume on the operand at index Idx.
+/// Assume should be an llvm.assume and Idx should be in the operand bundle.
+RetainedKnowledge getKnowledgeFromOperandInAssume(CallInst &Assume,
+ unsigned Idx);
+
+/// Retreive the information help by the Use U of an llvm.assume. the use should
+/// be in the operand bundle.
+inline RetainedKnowledge getKnowledgeFromUseInAssume(const Use *U) {
+ return getKnowledgeFromOperandInAssume(*cast<CallInst>(U->getUser()),
+ U->getOperandNo());
+}
+
+/// Tag in operand bundle indicating that this bundle should be ignored.
+constexpr StringRef IgnoreBundleTag = "ignore";
+
+/// Return true iff the operand bundles of the provided llvm.assume doesn't
+/// contain any valuable information. This is true when:
+/// - The operand bundle is empty
+/// - The operand bundle only contains information about dropped values or
+/// constant folded values.
+///
+/// the argument to the call of llvm.assume may still be useful even if the
+/// function returned true.
+bool isAssumeWithEmptyBundle(CallInst &Assume);
+
+/// Return a valid Knowledge associated to the Use U if its Attribute kind is
+/// in AttrKinds.
+RetainedKnowledge getKnowledgeFromUse(const Use *U,
+ ArrayRef<Attribute::AttrKind> AttrKinds);
+
+/// Return a valid Knowledge associated to the Value V if its Attribute kind is
+/// in AttrKinds and it matches the Filter.
+RetainedKnowledge getKnowledgeForValue(
+ const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
+ AssumptionCache *AC = nullptr,
+ function_ref<bool(RetainedKnowledge, Instruction *,
+ const CallBase::BundleOpInfo *)>
+ Filter = [](auto...) { return true; });
+
+/// Return a valid Knowledge associated to the Value V if its Attribute kind is
+/// in AttrKinds and the knowledge is suitable to be used in the context of
+/// CtxI.
+RetainedKnowledge getKnowledgeValidInContext(
+ const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
+ const Instruction *CtxI, const DominatorTree *DT = nullptr,
+ AssumptionCache *AC = nullptr);
+
+/// This extracts the Knowledge from an element of an operand bundle.
+/// This is mostly for use in the assume builder.
+RetainedKnowledge getKnowledgeFromBundle(CallInst &Assume,
+ const CallBase::BundleOpInfo &BOI);
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/AssumptionCache.h b/contrib/llvm-project/llvm/include/llvm/Analysis/AssumptionCache.h
index 0efbd59023d6..0ef63dc68e1c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/AssumptionCache.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/AssumptionCache.h
@@ -39,6 +39,21 @@ class Value;
/// register any new \@llvm.assume calls that they create. Deletions of
/// \@llvm.assume calls do not require special handling.
class AssumptionCache {
+public:
+ /// Value of ResultElem::Index indicating that the argument to the call of the
+ /// llvm.assume.
+ enum : unsigned { ExprResultIdx = std::numeric_limits<unsigned>::max() };
+
+ struct ResultElem {
+ WeakTrackingVH Assume;
+
+ /// contains either ExprResultIdx or the index of the operand bundle
+ /// containing the knowledge.
+ unsigned Index;
+ operator Value *() const { return Assume; }
+ };
+
+private:
/// The function for which this cache is handling assumptions.
///
/// We track this to lazily populate our assumptions.
@@ -46,7 +61,7 @@ class AssumptionCache {
/// Vector of weak value handles to calls of the \@llvm.assume
/// intrinsic.
- SmallVector<WeakTrackingVH, 4> AssumeHandles;
+ SmallVector<ResultElem, 4> AssumeHandles;
class AffectedValueCallbackVH final : public CallbackVH {
AssumptionCache *AC;
@@ -66,12 +81,12 @@ class AssumptionCache {
/// A map of values about which an assumption might be providing
/// information to the relevant set of assumptions.
using AffectedValuesMap =
- DenseMap<AffectedValueCallbackVH, SmallVector<WeakTrackingVH, 1>,
+ DenseMap<AffectedValueCallbackVH, SmallVector<ResultElem, 1>,
AffectedValueCallbackVH::DMI>;
AffectedValuesMap AffectedValues;
/// Get the vector of assumptions which affect a value from the cache.
- SmallVector<WeakTrackingVH, 1> &getOrInsertAffectedValues(Value *V);
+ SmallVector<ResultElem, 1> &getOrInsertAffectedValues(Value *V);
/// Move affected values in the cache for OV to be affected values for NV.
void transferAffectedValuesInCache(Value *OV, Value *NV);
@@ -128,20 +143,20 @@ public:
/// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
/// when we can write that to filter out the null values. Then caller code
/// will become simpler.
- MutableArrayRef<WeakTrackingVH> assumptions() {
+ MutableArrayRef<ResultElem> assumptions() {
if (!Scanned)
scanFunction();
return AssumeHandles;
}
/// Access the list of assumptions which affect this value.
- MutableArrayRef<WeakTrackingVH> assumptionsFor(const Value *V) {
+ MutableArrayRef<ResultElem> assumptionsFor(const Value *V) {
if (!Scanned)
scanFunction();
auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
if (AVI == AffectedValues.end())
- return MutableArrayRef<WeakTrackingVH>();
+ return MutableArrayRef<ResultElem>();
return AVI->second;
}
@@ -234,6 +249,21 @@ public:
static char ID; // Pass identification, replacement for typeid
};
+template<> struct simplify_type<AssumptionCache::ResultElem> {
+ using SimpleType = Value *;
+
+ static SimpleType getSimplifiedValue(AssumptionCache::ResultElem &Val) {
+ return Val;
+ }
+};
+template<> struct simplify_type<const AssumptionCache::ResultElem> {
+ using SimpleType = /*const*/ Value *;
+
+ static SimpleType getSimplifiedValue(const AssumptionCache::ResultElem &Val) {
+ return Val;
+ }
+};
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_ASSUMPTIONCACHE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
index 22e8c4b474cb..9214bfcd7a24 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/BasicAliasAnalysis.h
@@ -142,6 +142,8 @@ private:
APInt OtherOffset;
// Scaled variable (non-constant) indices.
SmallVector<VariableGEPIndex, 4> VarIndices;
+ // Is GEP index scale compile-time constant.
+ bool HasCompileTimeConstantScale;
};
/// Tracks phi nodes we have visited.
@@ -187,7 +189,7 @@ private:
bool
constantOffsetHeuristic(const SmallVectorImpl<VariableGEPIndex> &VarIndices,
LocationSize V1Size, LocationSize V2Size,
- APInt BaseOffset, AssumptionCache *AC,
+ const APInt &BaseOffset, AssumptionCache *AC,
DominatorTree *DT);
bool isValueEqualInPotentialCycles(const Value *V1, const Value *V2);
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
index 8bcfd7ff8f58..4c38cdd4a62b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfo.h
@@ -103,6 +103,9 @@ public:
uint64_t getEntryFreq() const;
void releaseMemory();
void print(raw_ostream &OS) const;
+
+ // Compare to the other BFI and verify they match.
+ void verifyMatch(BlockFrequencyInfo &Other) const;
};
/// Analysis pass which computes \c BlockFrequencyInfo.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h b/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
index bfe4fb14a2b8..868da7a64f68 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/BlockFrequencyInfoImpl.h
@@ -24,8 +24,10 @@
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DOTGraphTraits.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -46,6 +48,8 @@
#define DEBUG_TYPE "block-freq"
+extern llvm::cl::opt<bool> CheckBFIUnknownBlockQueries;
+
namespace llvm {
class BranchProbabilityInfo;
@@ -544,6 +548,7 @@ namespace bfi_detail {
template <class BlockT> struct TypeMap {};
template <> struct TypeMap<BasicBlock> {
using BlockT = BasicBlock;
+ using BlockKeyT = AssertingVH<const BasicBlock>;
using FunctionT = Function;
using BranchProbabilityInfoT = BranchProbabilityInfo;
using LoopT = Loop;
@@ -551,12 +556,16 @@ template <> struct TypeMap<BasicBlock> {
};
template <> struct TypeMap<MachineBasicBlock> {
using BlockT = MachineBasicBlock;
+ using BlockKeyT = const MachineBasicBlock *;
using FunctionT = MachineFunction;
using BranchProbabilityInfoT = MachineBranchProbabilityInfo;
using LoopT = MachineLoop;
using LoopInfoT = MachineLoopInfo;
};
+template <class BlockT, class BFIImplT>
+class BFICallbackVH;
+
/// Get the name of a MachineBasicBlock.
///
/// Get the name of a MachineBasicBlock. It's templated so that including from
@@ -842,6 +851,7 @@ template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
friend struct bfi_detail::BlockEdgesAdder<BT>;
using BlockT = typename bfi_detail::TypeMap<BT>::BlockT;
+ using BlockKeyT = typename bfi_detail::TypeMap<BT>::BlockKeyT;
using FunctionT = typename bfi_detail::TypeMap<BT>::FunctionT;
using BranchProbabilityInfoT =
typename bfi_detail::TypeMap<BT>::BranchProbabilityInfoT;
@@ -849,6 +859,8 @@ template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
using LoopInfoT = typename bfi_detail::TypeMap<BT>::LoopInfoT;
using Successor = GraphTraits<const BlockT *>;
using Predecessor = GraphTraits<Inverse<const BlockT *>>;
+ using BFICallbackVH =
+ bfi_detail::BFICallbackVH<BlockT, BlockFrequencyInfoImpl>;
const BranchProbabilityInfoT *BPI = nullptr;
const LoopInfoT *LI = nullptr;
@@ -856,7 +868,7 @@ template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
// All blocks in reverse postorder.
std::vector<const BlockT *> RPOT;
- DenseMap<const BlockT *, BlockNode> Nodes;
+ DenseMap<BlockKeyT, std::pair<BlockNode, BFICallbackVH>> Nodes;
using rpot_iterator = typename std::vector<const BlockT *>::const_iterator;
@@ -868,7 +880,8 @@ template <class BT> class BlockFrequencyInfoImpl : BlockFrequencyInfoImplBase {
BlockNode getNode(const rpot_iterator &I) const {
return BlockNode(getIndex(I));
}
- BlockNode getNode(const BlockT *BB) const { return Nodes.lookup(BB); }
+
+ BlockNode getNode(const BlockT *BB) const { return Nodes.lookup(BB).first; }
const BlockT *getBlock(const BlockNode &Node) const {
assert(Node.Index < RPOT.size());
@@ -989,6 +1002,13 @@ public:
void setBlockFreq(const BlockT *BB, uint64_t Freq);
+ void forgetBlock(const BlockT *BB) {
+ // We don't erase corresponding items from `Freqs`, `RPOT` and other to
+ // avoid invalidating indices. Doing so would have saved some memory, but
+ // it's not worth it.
+ Nodes.erase(BB);
+ }
+
Scaled64 getFloatingBlockFreq(const BlockT *BB) const {
return BlockFrequencyInfoImplBase::getFloatingBlockFreq(getNode(BB));
}
@@ -1014,8 +1034,40 @@ public:
raw_ostream &printBlockFreq(raw_ostream &OS, const BlockT *BB) const {
return BlockFrequencyInfoImplBase::printBlockFreq(OS, getNode(BB));
}
+
+ void verifyMatch(BlockFrequencyInfoImpl<BT> &Other) const;
+};
+
+namespace bfi_detail {
+
+template <class BFIImplT>
+class BFICallbackVH<BasicBlock, BFIImplT> : public CallbackVH {
+ BFIImplT *BFIImpl;
+
+public:
+ BFICallbackVH() = default;
+
+ BFICallbackVH(const BasicBlock *BB, BFIImplT *BFIImpl)
+ : CallbackVH(BB), BFIImpl(BFIImpl) {}
+
+ virtual ~BFICallbackVH() = default;
+
+ void deleted() override {
+ BFIImpl->forgetBlock(cast<BasicBlock>(getValPtr()));
+ }
};
+/// Dummy implementation since MachineBasicBlocks aren't Values, so ValueHandles
+/// don't apply to them.
+template <class BFIImplT>
+class BFICallbackVH<MachineBasicBlock, BFIImplT> {
+public:
+ BFICallbackVH() = default;
+ BFICallbackVH(const MachineBasicBlock *, BFIImplT *) {}
+};
+
+} // end namespace bfi_detail
+
template <class BT>
void BlockFrequencyInfoImpl<BT>::calculate(const FunctionT &F,
const BranchProbabilityInfoT &BPI,
@@ -1043,6 +1095,15 @@ void BlockFrequencyInfoImpl<BT>::calculate(const FunctionT &F,
computeMassInFunction();
unwrapLoops();
finalizeMetrics();
+
+ if (CheckBFIUnknownBlockQueries) {
+ // To detect BFI queries for unknown blocks, add entries for unreachable
+ // blocks, if any. This is to distinguish between known/existing unreachable
+ // blocks and unknown blocks.
+ for (const BlockT &BB : F)
+ if (!Nodes.count(&BB))
+ setBlockFreq(&BB, 0);
+ }
}
template <class BT>
@@ -1054,7 +1115,7 @@ void BlockFrequencyInfoImpl<BT>::setBlockFreq(const BlockT *BB, uint64_t Freq) {
// BlockNode for it assigned with a new index. The index can be determined
// by the size of Freqs.
BlockNode NewNode(Freqs.size());
- Nodes[BB] = NewNode;
+ Nodes[BB] = {NewNode, BFICallbackVH(BB, this)};
Freqs.emplace_back();
BlockFrequencyInfoImplBase::setBlockFreq(NewNode, Freq);
}
@@ -1074,7 +1135,7 @@ template <class BT> void BlockFrequencyInfoImpl<BT>::initializeRPOT() {
BlockNode Node = getNode(I);
LLVM_DEBUG(dbgs() << " - " << getIndex(I) << ": " << getBlockName(Node)
<< "\n");
- Nodes[*I] = Node;
+ Nodes[*I] = {Node, BFICallbackVH(*I, this)};
}
Working.reserve(RPOT.size());
@@ -1358,6 +1419,61 @@ raw_ostream &BlockFrequencyInfoImpl<BT>::print(raw_ostream &OS) const {
return OS;
}
+template <class BT>
+void BlockFrequencyInfoImpl<BT>::verifyMatch(
+ BlockFrequencyInfoImpl<BT> &Other) const {
+ bool Match = true;
+ DenseMap<const BlockT *, BlockNode> ValidNodes;
+ DenseMap<const BlockT *, BlockNode> OtherValidNodes;
+ for (auto &Entry : Nodes) {
+ const BlockT *BB = Entry.first;
+ if (BB) {
+ ValidNodes[BB] = Entry.second.first;
+ }
+ }
+ for (auto &Entry : Other.Nodes) {
+ const BlockT *BB = Entry.first;
+ if (BB) {
+ OtherValidNodes[BB] = Entry.second.first;
+ }
+ }
+ unsigned NumValidNodes = ValidNodes.size();
+ unsigned NumOtherValidNodes = OtherValidNodes.size();
+ if (NumValidNodes != NumOtherValidNodes) {
+ Match = false;
+ dbgs() << "Number of blocks mismatch: " << NumValidNodes << " vs "
+ << NumOtherValidNodes << "\n";
+ } else {
+ for (auto &Entry : ValidNodes) {
+ const BlockT *BB = Entry.first;
+ BlockNode Node = Entry.second;
+ if (OtherValidNodes.count(BB)) {
+ BlockNode OtherNode = OtherValidNodes[BB];
+ auto Freq = Freqs[Node.Index];
+ auto OtherFreq = Other.Freqs[OtherNode.Index];
+ if (Freq.Integer != OtherFreq.Integer) {
+ Match = false;
+ dbgs() << "Freq mismatch: " << bfi_detail::getBlockName(BB) << " "
+ << Freq.Integer << " vs " << OtherFreq.Integer << "\n";
+ }
+ } else {
+ Match = false;
+ dbgs() << "Block " << bfi_detail::getBlockName(BB) << " index "
+ << Node.Index << " does not exist in Other.\n";
+ }
+ }
+ // If there's a valid node in OtherValidNodes that's not in ValidNodes,
+ // either the above num check or the check on OtherValidNodes will fail.
+ }
+ if (!Match) {
+ dbgs() << "This\n";
+ print(dbgs());
+ dbgs() << "Other\n";
+ Other.print(dbgs());
+ }
+ assert(Match && "BFI mismatch");
+}
+
// Graph trait base class for block frequency information graph
// viewer.
@@ -1375,7 +1491,7 @@ struct BFIDOTGraphTraitsBase : public DefaultDOTGraphTraits {
explicit BFIDOTGraphTraitsBase(bool isSimple = false)
: DefaultDOTGraphTraits(isSimple) {}
- static std::string getGraphName(const BlockFrequencyInfoT *G) {
+ static StringRef getGraphName(const BlockFrequencyInfoT *G) {
return G->getFunction()->getName();
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/BranchProbabilityInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
index 41d6c23b8d0d..3e72afba36c3 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/BranchProbabilityInfo.h
@@ -55,8 +55,9 @@ public:
BranchProbabilityInfo() = default;
BranchProbabilityInfo(const Function &F, const LoopInfo &LI,
- const TargetLibraryInfo *TLI = nullptr) {
- calculate(F, LI, TLI);
+ const TargetLibraryInfo *TLI = nullptr,
+ PostDominatorTree *PDT = nullptr) {
+ calculate(F, LI, TLI, PDT);
}
BranchProbabilityInfo(BranchProbabilityInfo &&Arg)
@@ -75,6 +76,9 @@ public:
return *this;
}
+ bool invalidate(Function &, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
+
void releaseMemory();
void print(raw_ostream &OS) const;
@@ -95,7 +99,7 @@ public:
const BasicBlock *Dst) const;
BranchProbability getEdgeProbability(const BasicBlock *Src,
- succ_const_iterator Dst) const;
+ const_succ_iterator Dst) const;
/// Test if an edge is hot relative to other out-edges of the Src.
///
@@ -117,6 +121,7 @@ public:
raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src,
const BasicBlock *Dst) const;
+protected:
/// Set the raw edge probability for the given edge.
///
/// This allows a pass to explicitly set the edge probability for an edge. It
@@ -126,13 +131,22 @@ public:
void setEdgeProbability(const BasicBlock *Src, unsigned IndexInSuccessors,
BranchProbability Prob);
+public:
+ /// Set the raw probabilities for all edges from the given block.
+ ///
+ /// This allows a pass to explicitly set edge probabilities for a block. It
+ /// can be used when updating the CFG to update the branch probability
+ /// information.
+ void setEdgeProbability(const BasicBlock *Src,
+ const SmallVectorImpl<BranchProbability> &Probs);
+
static BranchProbability getBranchProbStackProtector(bool IsLikely) {
static const BranchProbability LikelyProb((1u << 20) - 1, 1u << 20);
return IsLikely ? LikelyProb : LikelyProb.getCompl();
}
void calculate(const Function &F, const LoopInfo &LI,
- const TargetLibraryInfo *TLI = nullptr);
+ const TargetLibraryInfo *TLI, PostDominatorTree *PDT);
/// Forget analysis results for the given basic block.
void eraseBlock(const BasicBlock *BB);
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CFG.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CFG.h
index 68f137ba622c..a36ceb484f14 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CFG.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CFG.h
@@ -14,8 +14,9 @@
#ifndef LLVM_ANALYSIS_CFG_H
#define LLVM_ANALYSIS_CFG_H
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CFG.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <utility>
namespace llvm {
@@ -24,6 +25,7 @@ class DominatorTree;
class Function;
class Instruction;
class LoopInfo;
+template <typename T> class SmallVectorImpl;
/// Analyze the specified function to find all of the loop backedges in the
/// function and return them. This is a relatively cheap (compared to
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CFGPrinter.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CFGPrinter.h
index aaefc11653dd..c4e49ce493ea 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CFGPrinter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CFGPrinter.h
@@ -18,49 +18,119 @@
#ifndef LLVM_ANALYSIS_CFGPRINTER_H
#define LLVM_ANALYSIS_CFGPRINTER_H
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/HeatUtils.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/GraphWriter.h"
namespace llvm {
-class CFGViewerPass
- : public PassInfoMixin<CFGViewerPass> {
+class CFGViewerPass : public PassInfoMixin<CFGViewerPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-class CFGOnlyViewerPass
- : public PassInfoMixin<CFGOnlyViewerPass> {
+class CFGOnlyViewerPass : public PassInfoMixin<CFGOnlyViewerPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-class CFGPrinterPass
- : public PassInfoMixin<CFGPrinterPass> {
+class CFGPrinterPass : public PassInfoMixin<CFGPrinterPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-class CFGOnlyPrinterPass
- : public PassInfoMixin<CFGOnlyPrinterPass> {
+class CFGOnlyPrinterPass : public PassInfoMixin<CFGOnlyPrinterPass> {
public:
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
-template<>
-struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
+class DOTFuncInfo {
+private:
+ const Function *F;
+ const BlockFrequencyInfo *BFI;
+ const BranchProbabilityInfo *BPI;
+ uint64_t MaxFreq;
+ bool ShowHeat;
+ bool EdgeWeights;
+ bool RawWeights;
- DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {}
+public:
+ DOTFuncInfo(const Function *F) : DOTFuncInfo(F, nullptr, nullptr, 0) {}
+
+ DOTFuncInfo(const Function *F, const BlockFrequencyInfo *BFI,
+ const BranchProbabilityInfo *BPI, uint64_t MaxFreq)
+ : F(F), BFI(BFI), BPI(BPI), MaxFreq(MaxFreq) {
+ ShowHeat = false;
+ EdgeWeights = !!BPI; // Print EdgeWeights when BPI is available.
+ RawWeights = !!BFI; // Print RawWeights when BFI is available.
+ }
+
+ const BlockFrequencyInfo *getBFI() { return BFI; }
+
+ const BranchProbabilityInfo *getBPI() { return BPI; }
+
+ const Function *getFunction() { return this->F; }
+
+ uint64_t getMaxFreq() { return MaxFreq; }
+
+ uint64_t getFreq(const BasicBlock *BB) {
+ return BFI->getBlockFreq(BB).getFrequency();
+ }
+
+ void setHeatColors(bool ShowHeat) { this->ShowHeat = ShowHeat; }
+
+ bool showHeatColors() { return ShowHeat; }
+
+ void setRawEdgeWeights(bool RawWeights) { this->RawWeights = RawWeights; }
- static std::string getGraphName(const Function *F) {
- return "CFG for '" + F->getName().str() + "' function";
+ bool useRawEdgeWeights() { return RawWeights; }
+
+ void setEdgeWeights(bool EdgeWeights) { this->EdgeWeights = EdgeWeights; }
+
+ bool showEdgeWeights() { return EdgeWeights; }
+};
+
+template <>
+struct GraphTraits<DOTFuncInfo *> : public GraphTraits<const BasicBlock *> {
+ static NodeRef getEntryNode(DOTFuncInfo *CFGInfo) {
+ return &(CFGInfo->getFunction()->getEntryBlock());
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ using nodes_iterator = pointer_iterator<Function::const_iterator>;
+
+ static nodes_iterator nodes_begin(DOTFuncInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->begin());
+ }
+
+ static nodes_iterator nodes_end(DOTFuncInfo *CFGInfo) {
+ return nodes_iterator(CFGInfo->getFunction()->end());
}
- static std::string getSimpleNodeLabel(const BasicBlock *Node,
- const Function *) {
+ static size_t size(DOTFuncInfo *CFGInfo) {
+ return CFGInfo->getFunction()->size();
+ }
+};
+
+template <>
+struct DOTGraphTraits<DOTFuncInfo *> : public DefaultDOTGraphTraits {
+
+ // Cache for is hidden property
+ llvm::DenseMap<const BasicBlock *, bool> isHiddenBasicBlock;
+
+ DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
+
+ static std::string getGraphName(DOTFuncInfo *CFGInfo) {
+ return "CFG for '" + CFGInfo->getFunction()->getName().str() + "' function";
+ }
+
+ static std::string getSimpleNodeLabel(const BasicBlock *Node, DOTFuncInfo *) {
if (!Node->getName().empty())
return Node->getName().str();
@@ -72,7 +142,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
static std::string getCompleteNodeLabel(const BasicBlock *Node,
- const Function *) {
+ DOTFuncInfo *) {
enum { MaxColumns = 80 };
std::string Str;
raw_string_ostream OS(Str);
@@ -84,22 +154,23 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
OS << *Node;
std::string OutStr = OS.str();
- if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+ if (OutStr[0] == '\n')
+ OutStr.erase(OutStr.begin());
// Process string output to make it nicer...
unsigned ColNum = 0;
unsigned LastSpace = 0;
for (unsigned i = 0; i != OutStr.length(); ++i) {
- if (OutStr[i] == '\n') { // Left justify
+ if (OutStr[i] == '\n') { // Left justify
OutStr[i] = '\\';
- OutStr.insert(OutStr.begin()+i+1, 'l');
+ OutStr.insert(OutStr.begin() + i + 1, 'l');
ColNum = 0;
LastSpace = 0;
- } else if (OutStr[i] == ';') { // Delete comments!
- unsigned Idx = OutStr.find('\n', i+1); // Find end of line
- OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
+ } else if (OutStr[i] == ';') { // Delete comments!
+ unsigned Idx = OutStr.find('\n', i + 1); // Find end of line
+ OutStr.erase(OutStr.begin() + i, OutStr.begin() + Idx);
--i;
- } else if (ColNum == MaxColumns) { // Wrap lines.
+ } else if (ColNum == MaxColumns) { // Wrap lines.
// Wrap very long names even though we can't find a space.
if (!LastSpace)
LastSpace = i;
@@ -107,8 +178,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
ColNum = i - LastSpace;
LastSpace = 0;
i += 3; // The loop will advance 'i' again.
- }
- else
+ } else
++ColNum;
if (OutStr[i] == ' ')
LastSpace = i;
@@ -116,16 +186,16 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
return OutStr;
}
- std::string getNodeLabel(const BasicBlock *Node,
- const Function *Graph) {
+ std::string getNodeLabel(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
+
if (isSimple())
- return getSimpleNodeLabel(Node, Graph);
+ return getSimpleNodeLabel(Node, CFGInfo);
else
- return getCompleteNodeLabel(Node, Graph);
+ return getCompleteNodeLabel(Node, CFGInfo);
}
static std::string getEdgeSourceLabel(const BasicBlock *Node,
- succ_const_iterator I) {
+ const_succ_iterator I) {
// Label source of conditional branches with "T" or "F"
if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
if (BI->isConditional())
@@ -135,7 +205,8 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
if (const SwitchInst *SI = dyn_cast<SwitchInst>(Node->getTerminator())) {
unsigned SuccNo = I.getSuccessorIndex();
- if (SuccNo == 0) return "def";
+ if (SuccNo == 0)
+ return "def";
std::string Str;
raw_string_ostream OS(Str);
@@ -147,12 +218,39 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
}
/// Display the raw branch weights from PGO.
- std::string getEdgeAttributes(const BasicBlock *Node, succ_const_iterator I,
- const Function *F) {
+ std::string getEdgeAttributes(const BasicBlock *Node, const_succ_iterator I,
+ DOTFuncInfo *CFGInfo) {
+ if (!CFGInfo->showEdgeWeights())
+ return "";
+
const Instruction *TI = Node->getTerminator();
if (TI->getNumSuccessors() == 1)
+ return "penwidth=2";
+
+ unsigned OpNo = I.getSuccessorIndex();
+
+ if (OpNo >= TI->getNumSuccessors())
return "";
+ BasicBlock *SuccBB = TI->getSuccessor(OpNo);
+ auto BranchProb = CFGInfo->getBPI()->getEdgeProbability(Node, SuccBB);
+ double WeightPercent = ((double)BranchProb.getNumerator()) /
+ ((double)BranchProb.getDenominator());
+ double Width = 1 + WeightPercent;
+
+ if (!CFGInfo->useRawEdgeWeights())
+ return formatv("label=\"{0:P}\" penwidth={1}", WeightPercent, Width)
+ .str();
+
+ // Prepend a 'W' to indicate that this is a weight rather than the actual
+ // profile count (due to scaling).
+
+ uint64_t Freq = CFGInfo->getFreq(Node);
+ std::string Attrs = formatv("label=\"W:{0}\" penwidth={1}",
+ (uint64_t)(Freq * WeightPercent), Width);
+ if (Attrs.size())
+ return Attrs;
+
MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
if (!WeightsNode)
return "";
@@ -161,25 +259,41 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
if (MDName->getString() != "branch_weights")
return "";
- unsigned OpNo = I.getSuccessorIndex() + 1;
+ OpNo = I.getSuccessorIndex() + 1;
if (OpNo >= WeightsNode->getNumOperands())
return "";
ConstantInt *Weight =
mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(OpNo));
if (!Weight)
return "";
+ return ("label=\"W:" + std::to_string(Weight->getZExtValue()) +
+ "\" penwidth=" + std::to_string(Width));
+ }
- // Prepend a 'W' to indicate that this is a weight rather than the actual
- // profile count (due to scaling).
- return ("label=\"W:" + Twine(Weight->getZExtValue()) + "\"").str();
+ std::string getNodeAttributes(const BasicBlock *Node, DOTFuncInfo *CFGInfo) {
+
+ if (!CFGInfo->showHeatColors())
+ return "";
+
+ uint64_t Freq = CFGInfo->getFreq(Node);
+ std::string Color = getHeatColor(Freq, CFGInfo->getMaxFreq());
+ std::string EdgeColor = (Freq <= (CFGInfo->getMaxFreq() / 2))
+ ? (getHeatColor(0))
+ : (getHeatColor(1));
+
+ std::string Attrs = "color=\"" + EdgeColor + "ff\", style=filled," +
+ " fillcolor=\"" + Color + "70\"";
+ return Attrs;
}
+ bool isNodeHidden(const BasicBlock *Node);
+ void computeHiddenNodes(const Function *F);
};
} // End llvm namespace
namespace llvm {
- class FunctionPass;
- FunctionPass *createCFGPrinterLegacyPassPass ();
- FunctionPass *createCFGOnlyPrinterLegacyPassPass ();
+class FunctionPass;
+FunctionPass *createCFGPrinterLegacyPassPass();
+FunctionPass *createCFGOnlyPrinterLegacyPassPass();
} // End llvm namespace
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CGSCCPassManager.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CGSCCPassManager.h
index 933f2210dafc..eb0d3ae8fedf 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CGSCCPassManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CGSCCPassManager.h
@@ -95,7 +95,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/PassManager.h"
@@ -381,10 +380,15 @@ class FunctionAnalysisManagerCGSCCProxy
public:
class Result {
public:
+ explicit Result() : FAM(nullptr) {}
explicit Result(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
+ void updateFAM(FunctionAnalysisManager &FAM) { this->FAM = &FAM; }
/// Accessor for the analysis manager.
- FunctionAnalysisManager &getManager() { return *FAM; }
+ FunctionAnalysisManager &getManager() {
+ assert(FAM);
+ return *FAM;
+ }
bool invalidate(LazyCallGraph::SCC &C, const PreservedAnalyses &PA,
CGSCCAnalysisManager::Invalidator &Inv);
@@ -416,7 +420,19 @@ using CGSCCAnalysisManagerFunctionProxy =
/// update result struct for the overall CGSCC walk.
LazyCallGraph::SCC &updateCGAndAnalysisManagerForFunctionPass(
LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
- CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR);
+ CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
+ FunctionAnalysisManager &FAM);
+
+/// Helper to update the call graph after running a CGSCC pass.
+///
+/// CGSCC passes can only mutate the call graph in specific ways. This
+/// routine provides a helper that updates the call graph in those ways
+/// including returning whether any changes were made and populating a CG
+/// update result struct for the overall CGSCC walk.
+LazyCallGraph::SCC &updateCGAndAnalysisManagerForCGSCCPass(
+ LazyCallGraph &G, LazyCallGraph::SCC &C, LazyCallGraph::Node &N,
+ CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR,
+ FunctionAnalysisManager &FAM);
/// Adaptor that maps from a SCC to its functions.
///
@@ -484,7 +500,11 @@ public:
if (!PI.runBeforePass<Function>(Pass, F))
continue;
- PreservedAnalyses PassPA = Pass.run(F, FAM);
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass.name());
+ PassPA = Pass.run(F, FAM);
+ }
PI.runAfterPass<Function>(Pass, F);
@@ -503,7 +523,7 @@ public:
auto PAC = PA.getChecker<LazyCallGraphAnalysis>();
if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) {
CurrentC = &updateCGAndAnalysisManagerForFunctionPass(CG, *CurrentC, *N,
- AM, UR);
+ AM, UR, FAM);
assert(
CG.lookupSCC(*N) == CurrentC &&
"Current SCC not updated to the SCC containing the current node!");
@@ -591,8 +611,8 @@ public:
CallCounts.insert(std::make_pair(&N.getFunction(), CountLocal))
.first->second;
for (Instruction &I : instructions(N.getFunction()))
- if (auto CS = CallSite(&I)) {
- if (CS.getCalledFunction()) {
+ if (auto *CB = dyn_cast<CallBase>(&I)) {
+ if (CB->getCalledFunction()) {
++Count.Direct;
} else {
++Count.Indirect;
@@ -634,17 +654,17 @@ public:
auto IsDevirtualizedHandle = [&](WeakTrackingVH &CallH) {
if (!CallH)
return false;
- auto CS = CallSite(CallH);
- if (!CS)
+ auto *CB = dyn_cast<CallBase>(CallH);
+ if (!CB)
return false;
// If the call is still indirect, leave it alone.
- Function *F = CS.getCalledFunction();
+ Function *F = CB->getCalledFunction();
if (!F)
return false;
LLVM_DEBUG(dbgs() << "Found devirtualized call from "
- << CS.getParent()->getParent()->getName() << " to "
+ << CB->getParent()->getParent()->getName() << " to "
<< F->getName() << "\n");
// We now have a direct call where previously we had an indirect call,
@@ -706,6 +726,7 @@ public:
// Update the analysis manager with each run and intersect the total set
// of preserved analyses so we're ready to iterate.
AM.invalidate(*C, PassPA);
+
PA.intersect(std::move(PassPA));
}
@@ -741,6 +762,10 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
// Get the call graph for this module.
LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);
+ // Get Function analysis manager from its proxy.
+ FunctionAnalysisManager &FAM =
+ AM.getCachedResult<FunctionAnalysisManagerModuleProxy>(M)->getManager();
+
// We keep worklists to allow us to push more work onto the pass manager as
// the passes are run.
SmallPriorityWorklist<LazyCallGraph::RefSCC *, 1> RCWorklist;
@@ -795,6 +820,12 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
LLVM_DEBUG(dbgs() << "Running an SCC pass across the RefSCC: " << *RC
<< "\n");
+ // The top of the worklist may *also* be the same SCC we just ran over
+ // (and invalidated for). Keep track of that last SCC we processed due
+ // to SCC update to avoid redundant processing when an SCC is both just
+ // updated itself and at the top of the worklist.
+ LazyCallGraph::SCC *LastUpdatedC = nullptr;
+
// Push the initial SCCs in reverse post-order as we'll pop off the
// back and so see this in post-order.
for (LazyCallGraph::SCC &C : llvm::reverse(*RC))
@@ -810,17 +841,22 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
LLVM_DEBUG(dbgs() << "Skipping an invalid SCC...\n");
continue;
}
+ if (LastUpdatedC == C) {
+ LLVM_DEBUG(dbgs() << "Skipping redundant run on SCC: " << *C << "\n");
+ continue;
+ }
if (&C->getOuterRefSCC() != RC) {
LLVM_DEBUG(dbgs() << "Skipping an SCC that is now part of some other "
"RefSCC...\n");
continue;
}
- // Ensure we can proxy analysis updates from from the CGSCC analysis
- // manager into the Function analysis manager by getting a proxy here.
- // FIXME: This seems like a bit of a hack. We should find a cleaner
- // or more costructive way to ensure this happens.
- (void)CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG);
+ // Ensure we can proxy analysis updates from the CGSCC analysis manager
+ // into the the Function analysis manager by getting a proxy here.
+ // This also needs to update the FunctionAnalysisManager, as this may be
+ // the first time we see this SCC.
+ CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
+ FAM);
// Each time we visit a new SCC pulled off the worklist,
// a transformation of a child SCC may have also modified this parent
@@ -837,11 +873,6 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
// invalidate the analyses for any SCCs other than themselves which
// are mutated. However, that seems to lose the robustness of the
// pass-manager driven invalidation scheme.
- //
- // FIXME: This is redundant in one case -- the top of the worklist may
- // *also* be the same SCC we just ran over (and invalidated for). In
- // that case, we'll end up doing a redundant invalidation here as
- // a consequence.
CGAM.invalidate(*C, UR.CrossSCCPA);
do {
@@ -851,6 +882,7 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
assert(&C->getOuterRefSCC() == RC &&
"Processing an SCC in a different RefSCC!");
+ LastUpdatedC = UR.UpdatedC;
UR.UpdatedRC = nullptr;
UR.UpdatedC = nullptr;
@@ -860,7 +892,11 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
if (!PI.runBeforePass<LazyCallGraph::SCC>(Pass, *C))
continue;
- PreservedAnalyses PassPA = Pass.run(*C, CGAM, CG, UR);
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass.name());
+ PassPA = Pass.run(*C, CGAM, CG, UR);
+ }
if (UR.InvalidatedSCCs.count(C))
PI.runAfterPassInvalidated<LazyCallGraph::SCC>(Pass);
@@ -871,6 +907,13 @@ ModuleToPostOrderCGSCCPassAdaptor<CGSCCPassT>::run(Module &M,
C = UR.UpdatedC ? UR.UpdatedC : C;
RC = UR.UpdatedRC ? UR.UpdatedRC : RC;
+ if (UR.UpdatedC) {
+ // If we're updating the SCC, also update the FAM inside the proxy's
+ // result.
+ CGAM.getResult<FunctionAnalysisManagerCGSCCProxy>(*C, CG).updateFAM(
+ FAM);
+ }
+
// If the CGSCC pass wasn't able to provide a valid updated SCC,
// the current SCC may simply need to be skipped if invalid.
if (UR.InvalidatedSCCs.count(C)) {
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraph.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraph.h
index 7a10183c4d91..98f9b0683fd4 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraph.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraph.h
@@ -94,10 +94,6 @@ class CallGraph {
/// callers from the old function to the new.
void spliceFunction(const Function *From, const Function *To);
- /// Add a function to the call graph, and link the node to all of the
- /// functions that it calls.
- void addToCallGraph(Function *F);
-
public:
explicit CallGraph(Module &M);
CallGraph(CallGraph &&Arg);
@@ -112,6 +108,9 @@ public:
/// Returns the module the call graph corresponds to.
Module &getModule() const { return M; }
+ bool invalidate(Module &, const PreservedAnalyses &PA,
+ ModuleAnalysisManager::Invalidator &);
+
inline iterator begin() { return FunctionMap.begin(); }
inline iterator end() { return FunctionMap.end(); }
inline const_iterator begin() const { return FunctionMap.begin(); }
@@ -139,6 +138,10 @@ public:
return CallsExternalNode.get();
}
+ /// Old node has been deleted, and New is to be used in its place, update the
+ /// ExternalCallingNode.
+ void ReplaceExternalCallEdge(CallGraphNode *Old, CallGraphNode *New);
+
//===---------------------------------------------------------------------
// Functions to keep a call graph up to date with a function that has been
// modified.
@@ -155,6 +158,13 @@ public:
/// Similar to operator[], but this will insert a new CallGraphNode for
/// \c F if one does not already exist.
CallGraphNode *getOrInsertFunction(const Function *F);
+
+ /// Populate \p CGN based on the calls inside the associated function.
+ void populateCallGraphNode(CallGraphNode *CGN);
+
+ /// Add a function to the call graph, and link the node to all of the
+ /// functions that it calls.
+ void addToCallGraph(Function *F);
};
/// A node in the call graph for a module.
@@ -165,13 +175,21 @@ class CallGraphNode {
public:
/// A pair of the calling instruction (a call or invoke)
/// and the call graph node being called.
- using CallRecord = std::pair<WeakTrackingVH, CallGraphNode *>;
+ /// Call graph node may have two types of call records which represent an edge
+ /// in the call graph - reference or a call edge. Reference edges are not
+ /// associated with any call instruction and are created with the first field
+ /// set to `None`, while real call edges have instruction address in this
+ /// field. Therefore, all real call edges are expected to have a value in the
+ /// first field and it is not supposed to be `nullptr`.
+ /// Reference edges, for example, are used for connecting broker function
+ /// caller to the callback function for callback call sites.
+ using CallRecord = std::pair<Optional<WeakTrackingVH>, CallGraphNode *>;
public:
using CalledFunctionsVector = std::vector<CallRecord>;
/// Creates a node for the specified function.
- inline CallGraphNode(Function *F) : F(F) {}
+ inline CallGraphNode(CallGraph *CG, Function *F) : CG(CG), F(F) {}
CallGraphNode(const CallGraphNode &) = delete;
CallGraphNode &operator=(const CallGraphNode &) = delete;
@@ -233,7 +251,8 @@ public:
assert(!Call || !Call->getCalledFunction() ||
!Call->getCalledFunction()->isIntrinsic() ||
!Intrinsic::isLeaf(Call->getCalledFunction()->getIntrinsicID()));
- CalledFunctions.emplace_back(Call, M);
+ CalledFunctions.emplace_back(
+ Call ? Optional<WeakTrackingVH>(Call) : Optional<WeakTrackingVH>(), M);
M->AddRef();
}
@@ -269,6 +288,7 @@ public:
private:
friend class CallGraph;
+ CallGraph *CG;
Function *F;
std::vector<CallRecord> CalledFunctions;
@@ -402,7 +422,7 @@ public:
// graphs by the generic graph algorithms.
//
-// Provide graph traits for tranversing call graphs using standard graph
+// Provide graph traits for traversing call graphs using standard graph
// traversals.
template <> struct GraphTraits<CallGraphNode *> {
using NodeRef = CallGraphNode *;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h
index 1b5b7e2f039e..d0d81605436e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CallGraphSCCPass.h
@@ -103,6 +103,10 @@ public:
/// Old node has been deleted, and New is to be used in its place.
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
+ /// DeleteNode - This informs the SCC and the pass manager that the specified
+ /// Old node has been deleted.
+ void DeleteNode(CallGraphNode *Old);
+
using iterator = std::vector<CallGraphNode *>::const_iterator;
iterator begin() const { return Nodes.begin(); }
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CaptureTracking.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CaptureTracking.h
index 29921a51d5be..e68675b278f1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CaptureTracking.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CaptureTracking.h
@@ -20,15 +20,11 @@ namespace llvm {
class DataLayout;
class Instruction;
class DominatorTree;
- class OrderedBasicBlock;
- /// The default value for MaxUsesToExplore argument. It's relatively small to
- /// keep the cost of analysis reasonable for clients like BasicAliasAnalysis,
- /// where the results can't be cached.
- /// TODO: we should probably introduce a caching CaptureTracking analysis and
- /// use it where possible. The caching version can use much higher limit or
- /// don't have this cap at all.
- unsigned constexpr DefaultMaxUsesToExplore = 20;
+ /// getDefaultMaxUsesToExploreForCaptureTracking - Return default value of
+ /// the maximal number of uses to explore before giving up. It is used by
+ /// PointerMayBeCaptured family analysis.
+ unsigned getDefaultMaxUsesToExploreForCaptureTracking();
/// PointerMayBeCaptured - Return true if this pointer value may be captured
/// by the enclosing function (which is required to exist). This routine can
@@ -37,12 +33,12 @@ namespace llvm {
/// counts as capturing it or not. The boolean StoreCaptures specified
/// whether storing the value (or part of it) into memory anywhere
/// automatically counts as capturing it or not.
- /// MaxUsesToExplore specifies how many uses should the analysis explore for
- /// one value before giving up due too "too many uses".
- bool PointerMayBeCaptured(const Value *V,
- bool ReturnCaptures,
+ /// MaxUsesToExplore specifies how many uses the analysis should explore for
+ /// one value before giving up due too "too many uses". If MaxUsesToExplore
+ /// is zero, a default value is assumed.
+ bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures,
bool StoreCaptures,
- unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
+ unsigned MaxUsesToExplore = 0);
/// PointerMayBeCapturedBefore - Return true if this pointer value may be
/// captured by the enclosing function (which is required to exist). If a
@@ -53,15 +49,14 @@ namespace llvm {
/// it or not. The boolean StoreCaptures specified whether storing the value
/// (or part of it) into memory anywhere automatically counts as capturing it
/// or not. Captures by the provided instruction are considered if the
- /// final parameter is true. An ordered basic block in \p OBB could be used
- /// to speed up capture-tracker queries.
- /// MaxUsesToExplore specifies how many uses should the analysis explore for
- /// one value before giving up due too "too many uses".
- bool PointerMayBeCapturedBefore(const Value *V, bool ReturnCaptures,
- bool StoreCaptures, const Instruction *I,
- const DominatorTree *DT, bool IncludeI = false,
- OrderedBasicBlock *OBB = nullptr,
- unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
+ /// final parameter is true.
+ /// MaxUsesToExplore specifies how many uses the analysis should explore for
+ /// one value before giving up due too "too many uses". If MaxUsesToExplore
+ /// is zero, a default value is assumed.
+ bool PointerMayBeCapturedBefore(
+ const Value *V, bool ReturnCaptures, bool StoreCaptures,
+ const Instruction *I, const DominatorTree *DT, bool IncludeI = false,
+ unsigned MaxUsesToExplore = 0);
/// This callback is used in conjunction with PointerMayBeCaptured. In
/// addition to the interface here, you'll need to provide your own getters
@@ -94,10 +89,11 @@ namespace llvm {
/// PointerMayBeCaptured - Visit the value and the values derived from it and
/// find values which appear to be capturing the pointer value. This feeds
/// results into and is controlled by the CaptureTracker object.
- /// MaxUsesToExplore specifies how many uses should the analysis explore for
- /// one value before giving up due too "too many uses".
+ /// MaxUsesToExplore specifies how many uses the analysis should explore for
+ /// one value before giving up due too "too many uses". If MaxUsesToExplore
+ /// is zero, a default value is assumed.
void PointerMayBeCaptured(const Value *V, CaptureTracker *Tracker,
- unsigned MaxUsesToExplore = DefaultMaxUsesToExplore);
+ unsigned MaxUsesToExplore = 0);
} // end namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/CodeMetrics.h b/contrib/llvm-project/llvm/include/llvm/Analysis/CodeMetrics.h
index 1482b66a3080..eab24c8ab179 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/CodeMetrics.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/CodeMetrics.h
@@ -15,15 +15,13 @@
#define LLVM_ANALYSIS_CODEMETRICS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
namespace llvm {
class AssumptionCache;
class BasicBlock;
class Loop;
class Function;
-class Instruction;
-class DataLayout;
+template <class T> class SmallPtrSetImpl;
class TargetTransformInfo;
class Value;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ConstantFolding.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ConstantFolding.h
index 2385b6f09c40..0ccc782ad6f5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ConstantFolding.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ConstantFolding.h
@@ -25,7 +25,6 @@ template <typename T> class ArrayRef;
class CallBase;
class Constant;
class ConstantExpr;
-class ConstantVector;
class DataLayout;
class Function;
class GlobalValue;
@@ -46,9 +45,9 @@ bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV, APInt &Offset,
Constant *ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr);
-/// ConstantFoldConstant - Attempt to fold the constant using the
-/// specified DataLayout.
-/// If successful, the constant result is returned, if not, null is returned.
+/// ConstantFoldConstant - Fold the constant using the specified DataLayout.
+/// This function always returns a non-null constant: Either the folding result,
+/// or the original constant if further folding is not possible.
Constant *ConstantFoldConstant(const Constant *C, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr);
@@ -119,10 +118,11 @@ Constant *ConstantFoldInsertElementInstruction(Constant *Val,
Constant *ConstantFoldExtractElementInstruction(Constant *Val, Constant *Idx);
/// Attempt to constant fold a shufflevector instruction with the
-/// specified operands and indices. The constant result is returned if
-/// successful; if not, null is returned.
+/// specified operands and mask. See class ShuffleVectorInst for a description
+/// of the mask representation. The constant result is returned if successful;
+/// if not, null is returned.
Constant *ConstantFoldShuffleVectorInstruction(Constant *V1, Constant *V2,
- Constant *Mask);
+ ArrayRef<int> Mask);
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DDG.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DDG.h
index 22df60efd84e..9e2b7907eaec 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DDG.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DDG.h
@@ -104,6 +104,8 @@ public:
/// Subclass of DDGNode representing single or multi-instruction nodes.
class SimpleDDGNode : public DDGNode {
+ friend class DDGBuilder;
+
public:
SimpleDDGNode() = delete;
SimpleDDGNode(Instruction &I);
@@ -282,6 +284,12 @@ public:
return *Root;
}
+ /// Collect all the data dependency infos coming from any pair of memory
+ /// accesses from \p Src to \p Dst, and store them into \p Deps. Return true
+ /// if a dependence exists, and false otherwise.
+ bool getDependencies(const NodeType &Src, const NodeType &Dst,
+ DependenceList &Deps) const;
+
protected:
// Name of the graph.
std::string Name;
@@ -388,6 +396,12 @@ public:
return PiNode->getNodes();
}
+ /// Return true if the two nodes \pSrc and \pTgt are both simple nodes and
+ /// the consecutive instructions after merging belong to the same basic block.
+ bool areNodesMergeable(const DDGNode &Src,
+ const DDGNode &Tgt) const final override;
+ void mergeNodes(DDGNode &Src, DDGNode &Tgt) final override;
+ bool shouldSimplify() const final override;
bool shouldCreatePiBlocks() const final override;
};
@@ -424,6 +438,32 @@ private:
};
//===--------------------------------------------------------------------===//
+// DependenceGraphInfo Implementation
+//===--------------------------------------------------------------------===//
+
+template <typename NodeType>
+bool DependenceGraphInfo<NodeType>::getDependencies(
+ const NodeType &Src, const NodeType &Dst, DependenceList &Deps) const {
+ assert(Deps.empty() && "Expected empty output list at the start.");
+
+ // List of memory access instructions from src and dst nodes.
+ SmallVector<Instruction *, 8> SrcIList, DstIList;
+ auto isMemoryAccess = [](const Instruction *I) {
+ return I->mayReadOrWriteMemory();
+ };
+ Src.collectInstructions(isMemoryAccess, SrcIList);
+ Dst.collectInstructions(isMemoryAccess, DstIList);
+
+ for (auto *SrcI : SrcIList)
+ for (auto *DstI : DstIList)
+ if (auto Dep =
+ const_cast<DependenceInfo *>(&DI)->depends(SrcI, DstI, true))
+ Deps.push_back(std::move(Dep));
+
+ return !Deps.empty();
+}
+
+//===--------------------------------------------------------------------===//
// GraphTraits specializations for the DDG
//===--------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
index c9e8df5db1c2..ecf54cd8a680 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -14,8 +14,6 @@
#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#include "llvm/Analysis/CFGPrinter.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/FileSystem.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceAnalysis.h
index 0c4002c3c3ba..305c9b1d88f2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceAnalysis.h
@@ -40,12 +40,13 @@
#define LLVM_ANALYSIS_DEPENDENCEANALYSIS_H
#include "llvm/ADT/SmallBitVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
-template <typename T> class ArrayRef;
+ class AAResults;
+ template <typename T> class ArrayRef;
class Loop;
class LoopInfo;
class ScalarEvolution;
@@ -270,7 +271,7 @@ template <typename T> class ArrayRef;
///
class DependenceInfo {
public:
- DependenceInfo(Function *F, AliasAnalysis *AA, ScalarEvolution *SE,
+ DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE,
LoopInfo *LI)
: AA(AA), SE(SE), LI(LI), F(F) {}
@@ -333,7 +334,7 @@ template <typename T> class ArrayRef;
Function *getFunction() const { return F; }
private:
- AliasAnalysis *AA;
+ AAResults *AA;
ScalarEvolution *SE;
LoopInfo *LI;
Function *F;
@@ -924,10 +925,28 @@ template <typename T> class ArrayRef;
void updateDirection(Dependence::DVEntry &Level,
const Constraint &CurConstraint) const;
+ /// Given a linear access function, tries to recover subscripts
+ /// for each dimension of the array element access.
bool tryDelinearize(Instruction *Src, Instruction *Dst,
SmallVectorImpl<Subscript> &Pair);
- private:
+ /// Tries to delinearize access function for a fixed size multi-dimensional
+ /// array, by deriving subscripts from GEP instructions. Returns true upon
+ /// success and false otherwise.
+ bool tryDelinearizeFixedSize(Instruction *Src, Instruction *Dst,
+ const SCEV *SrcAccessFn,
+ const SCEV *DstAccessFn,
+ SmallVectorImpl<const SCEV *> &SrcSubscripts,
+ SmallVectorImpl<const SCEV *> &DstSubscripts);
+
+ /// Tries to delinearize access function for a multi-dimensional array with
+ /// symbolic runtime sizes.
+ /// Returns true upon success and false otherwise.
+ bool tryDelinearizeParametricSize(
+ Instruction *Src, Instruction *Dst, const SCEV *SrcAccessFn,
+ const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
+ SmallVectorImpl<const SCEV *> &DstSubscripts);
+
/// checkSubscript - Helper function for checkSrcSubscript and
/// checkDstSubscript to avoid duplicate code
bool checkSubscript(const SCEV *Expr, const Loop *LoopNest,
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceGraphBuilder.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceGraphBuilder.h
index 08a13d967da2..6f4e1be94164 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceGraphBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DependenceGraphBuilder.h
@@ -14,13 +14,16 @@
#ifndef LLVM_ANALYSIS_DEPENDENCE_GRAPH_BUILDER_H
#define LLVM_ANALYSIS_DEPENDENCE_GRAPH_BUILDER_H
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/Analysis/DependenceAnalysis.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/ADT/SmallVector.h"
namespace llvm {
+class BasicBlock;
+class DependenceInfo;
+class Instruction;
+
/// This abstract builder class defines a set of high-level steps for creating
/// DDG-like graphs. The client code is expected to inherit from this class and
/// define concrete implementation for each of the pure virtual functions used
@@ -58,6 +61,7 @@ public:
createFineGrainedNodes();
createDefUseEdges();
createMemoryDependencyEdges();
+ simplify();
createAndConnectRootNode();
createPiBlocks();
sortNodesTopologically();
@@ -92,6 +96,15 @@ public:
/// the dependence graph into an acyclic graph.
void createPiBlocks();
+ /// Go through all the nodes in the graph and collapse any two nodes
+ /// 'a' and 'b' if all of the following are true:
+ /// - the only edge from 'a' is a def-use edge to 'b' and
+ /// - the only edge to 'b' is a def-use edge from 'a' and
+ /// - there is no cyclic edge from 'b' to 'a' and
+ /// - all instructions in 'a' and 'b' belong to the same basic block and
+ /// - both 'a' and 'b' are simple (single or multi instruction) nodes.
+ void simplify();
+
/// Topologically sort the graph nodes.
void sortNodesTopologically();
@@ -129,6 +142,18 @@ protected:
/// and false otherwise.
virtual bool shouldCreatePiBlocks() const { return true; }
+ /// Return true if graph simplification step is requested, and false
+ /// otherwise.
+ virtual bool shouldSimplify() const { return true; }
+
+ /// Return true if it's safe to merge the two nodes.
+ virtual bool areNodesMergeable(const NodeType &A,
+ const NodeType &B) const = 0;
+
+ /// Append the content of node \p B into node \p A and remove \p B and
+ /// the edge between \p A and \p B from the graph.
+ virtual void mergeNodes(NodeType &A, NodeType &B) = 0;
+
/// Given an instruction \p I return its associated ordinal number.
size_t getOrdinal(Instruction &I) {
assert(InstOrdinalMap.find(&I) != InstOrdinalMap.end() &&
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DivergenceAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DivergenceAnalysis.h
index 2fac9c8b4b34..a2da97bb9059 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DivergenceAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DivergenceAnalysis.h
@@ -147,7 +147,7 @@ private:
private:
const Function &F;
// If regionLoop != nullptr, analysis is only performed within \p RegionLoop.
- // Otw, analyze the whole function
+ // Otherwise, analyze the whole function
const Loop *RegionLoop;
const DominatorTree &DT;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DomTreeUpdater.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DomTreeUpdater.h
index 5ccce2e064cc..d09154d506ed 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DomTreeUpdater.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DomTreeUpdater.h
@@ -14,15 +14,17 @@
#ifndef LLVM_ANALYSIS_DOMTREEUPDATER_H
#define LLVM_ANALYSIS_DOMTREEUPDATER_H
-#include "llvm/Analysis/PostDominators.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/ValueHandle.h"
-#include "llvm/Support/GenericDomTree.h"
+#include "llvm/Support/Compiler.h"
+#include <cstddef>
#include <functional>
#include <vector>
namespace llvm {
+class PostDominatorTree;
+
class DomTreeUpdater {
public:
enum class UpdateStrategy : unsigned char { Eager = 0, Lazy = 1 };
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/DominanceFrontier.h b/contrib/llvm-project/llvm/include/llvm/Analysis/DominanceFrontier.h
index c0bf30e162dd..f67929c997f9 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/DominanceFrontier.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/DominanceFrontier.h
@@ -130,7 +130,7 @@ public:
using DomSetType = typename DominanceFrontierBase<BlockT, false>::DomSetType;
void analyze(DomTreeT &DT) {
- assert(DT.getRoots().size() == 1 &&
+ assert(DT.root_size() == 1 &&
"Only one entry block for forward domfronts!");
this->Roots = {DT.getRoot()};
calculate(DT, DT[this->Roots[0]]);
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/EHPersonalities.h b/contrib/llvm-project/llvm/include/llvm/Analysis/EHPersonalities.h
index d89aa11617b5..c17b0b4a90d3 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/EHPersonalities.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/EHPersonalities.h
@@ -11,12 +11,12 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
class BasicBlock;
class Function;
+class Triple;
class Value;
enum class EHPersonality {
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h b/contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h
index fa5b16cf95eb..7daaa7f484de 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/GlobalsModRef.h
@@ -14,7 +14,6 @@
#define LLVM_ANALYSIS_GLOBALSMODREF_H
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/CallGraph.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
@@ -23,6 +22,7 @@
#include <list>
namespace llvm {
+class CallGraph;
/// An alias analysis result set for globals.
///
@@ -83,6 +83,9 @@ public:
GlobalsAAResult(GlobalsAAResult &&Arg);
~GlobalsAAResult();
+ bool invalidate(Module &M, const PreservedAnalyses &PA,
+ ModuleAnalysisManager::Invalidator &);
+
static GlobalsAAResult
analyzeModule(Module &M,
std::function<const TargetLibraryInfo &(Function &F)> GetTLI,
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/HeatUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/HeatUtils.h
new file mode 100644
index 000000000000..b665e211c6ac
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/HeatUtils.h
@@ -0,0 +1,40 @@
+//===-- HeatUtils.h - Utility for printing heat colors ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility for printing heat colors based on profiling information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_HEATUTILS_H
+#define LLVM_ANALYSIS_HEATUTILS_H
+
+#include <cstdint>
+#include <string>
+
+namespace llvm {
+
+class BlockFrequencyInfo;
+class Function;
+
+// Returns number of calls of calledFunction by callerFunction.
+uint64_t
+getNumOfCalls(Function &callerFunction, Function &calledFunction);
+
+// Returns the maximum frequency of a BB in a function.
+uint64_t getMaxFreq(const Function &F, const BlockFrequencyInfo *BFI);
+
+// Calculates heat color based on current and maximum frequencies.
+std::string getHeatColor(uint64_t freq, uint64_t maxFreq);
+
+// Calculates heat color based on percent of "hotness".
+std::string getHeatColor(double percent);
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/IVDescriptors.h b/contrib/llvm-project/llvm/include/llvm/Analysis/IVDescriptors.h
index 7be1fd3f5788..1bae83d13c7a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/IVDescriptors.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/IVDescriptors.h
@@ -14,38 +14,25 @@
#define LLVM_ANALYSIS_IVDESCRIPTORS_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/DemandedBits.h"
-#include "llvm/Analysis/EHPersonalities.h"
-#include "llvm/Analysis/MustExecute.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
namespace llvm {
-class AliasSet;
-class AliasSetTracker;
-class BasicBlock;
-class DataLayout;
+class DemandedBits;
+class AssumptionCache;
class Loop;
-class LoopInfo;
-class OptimizationRemarkEmitter;
class PredicatedScalarEvolution;
-class PredIteratorCache;
class ScalarEvolution;
class SCEV;
-class TargetLibraryInfo;
-class TargetTransformInfo;
+class DominatorTree;
+class ICFLoopSafetyInfo;
/// The RecurrenceDescriptor is used to identify recurrences variables in a
/// loop. Reduction is a special case of recurrence that has uses of the
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/IndirectCallVisitor.h b/contrib/llvm-project/llvm/include/llvm/Analysis/IndirectCallVisitor.h
index 1d1f3f4cc5c0..eb72f2c5d14d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/IndirectCallVisitor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/IndirectCallVisitor.h
@@ -18,7 +18,7 @@
namespace llvm {
// Visitor class that finds all indirect call.
struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
- std::vector<Instruction *> IndirectCalls;
+ std::vector<CallBase *> IndirectCalls;
PGOIndirectCallVisitor() {}
void visitCallBase(CallBase &Call) {
@@ -28,7 +28,7 @@ struct PGOIndirectCallVisitor : public InstVisitor<PGOIndirectCallVisitor> {
};
// Helper function that finds all indirect call sites.
-inline std::vector<Instruction *> findIndirectCalls(Function &F) {
+inline std::vector<CallBase *> findIndirectCalls(Function &F) {
PGOIndirectCallVisitor ICV;
ICV.visit(F);
return ICV.IndirectCalls;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineAdvisor.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineAdvisor.h
new file mode 100644
index 000000000000..3480d93385a8
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineAdvisor.h
@@ -0,0 +1,238 @@
+//===- InlineAdvisor.h - Inlining decision making abstraction -*- C++ ---*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_INLINEADVISOR_H_
+#define LLVM_INLINEADVISOR_H_
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+#include "llvm/Analysis/InlineCost.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class BasicBlock;
+class CallBase;
+class Function;
+class Module;
+class OptimizationRemarkEmitter;
+
+/// There are 3 scenarios we can use the InlineAdvisor:
+/// - Default - use manual heuristics.
+///
+/// - Release mode, the expected mode for production, day to day deployments.
+/// In this mode, when building the compiler, we also compile a pre-trained ML
+/// model to native code, and link it as a static library. This mode has low
+/// overhead and no additional dependencies for the compiler runtime.
+///
+/// - Development mode, for training new models.
+/// In this mode, we trade off runtime performance for flexibility. This mode
+/// requires the full C Tensorflow API library, and evaluates models
+/// dynamically. This mode also permits generating training logs, for offline
+/// training.
+enum class InliningAdvisorMode : int { Default, Release, Development };
+
+class InlineAdvisor;
+/// Capture state between an inlining decision having had been made, and
+/// its impact being observable. When collecting model training data, this
+/// allows recording features/decisions/partial reward data sets.
+///
+/// Derivations of this type are expected to be tightly coupled with their
+/// InliningAdvisors. The base type implements the minimal contractual
+/// obligations.
+class InlineAdvice {
+public:
+ InlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
+ OptimizationRemarkEmitter &ORE, bool IsInliningRecommended);
+
+ InlineAdvice(InlineAdvice &&) = delete;
+ InlineAdvice(const InlineAdvice &) = delete;
+ virtual ~InlineAdvice() {
+ assert(Recorded && "InlineAdvice should have been informed of the "
+ "inliner's decision in all cases");
+ }
+
+ /// Exactly one of the record* APIs must be called. Implementers may extend
+ /// behavior by implementing the corresponding record*Impl.
+ ///
+ /// Call after inlining succeeded, and did not result in deleting the callee.
+ void recordInlining() {
+ markRecorded();
+ recordInliningImpl();
+ }
+
+ /// Call after inlining succeeded, and resulted in deleting the callee.
+ void recordInliningWithCalleeDeleted();
+
+ /// Call after the decision for a call site was to not inline.
+ void recordUnsuccessfulInlining(const InlineResult &Result) {
+ markRecorded();
+ recordUnsuccessfulInliningImpl(Result);
+ }
+
+ /// Call to indicate inlining was not attempted.
+ void recordUnattemptedInlining() {
+ markRecorded();
+ recordUnattemptedInliningImpl();
+ }
+
+ /// Get the inlining recommendation.
+ bool isInliningRecommended() const { return IsInliningRecommended; }
+ const DebugLoc &getOriginalCallSiteDebugLoc() const { return DLoc; }
+ const BasicBlock *getOriginalCallSiteBasicBlock() const { return Block; }
+
+protected:
+ virtual void recordInliningImpl() {}
+ virtual void recordInliningWithCalleeDeletedImpl() {}
+ virtual void recordUnsuccessfulInliningImpl(const InlineResult &Result) {}
+ virtual void recordUnattemptedInliningImpl() {}
+
+ InlineAdvisor *const Advisor;
+ /// Caller and Callee are pre-inlining.
+ Function *const Caller;
+ Function *const Callee;
+
+ // Capture the context of CB before inlining, as a successful inlining may
+ // change that context, and we want to report success or failure in the
+ // original context.
+ const DebugLoc DLoc;
+ const BasicBlock *const Block;
+ OptimizationRemarkEmitter &ORE;
+ const bool IsInliningRecommended;
+
+private:
+ void markRecorded() {
+ assert(!Recorded && "Recording should happen exactly once");
+ Recorded = true;
+ }
+
+ bool Recorded = false;
+};
+
+/// Interface for deciding whether to inline a call site or not.
+class InlineAdvisor {
+public:
+ InlineAdvisor(InlineAdvisor &&) = delete;
+ virtual ~InlineAdvisor() { freeDeletedFunctions(); }
+
+ /// Get an InlineAdvice containing a recommendation on whether to
+ /// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to
+ /// be up-to-date wrt previous inlining decisions.
+ /// Returns an InlineAdvice with the inlining recommendation.
+ virtual std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB) = 0;
+
+ /// This must be called when the Inliner pass is entered, to allow the
+ /// InlineAdvisor update internal state, as result of function passes run
+ /// between Inliner pass runs (for the same module).
+ virtual void onPassEntry() {}
+
+ /// This must be called when the Inliner pass is exited, as function passes
+ /// may be run subsequently. This allows an implementation of InlineAdvisor
+ /// to prepare for a partial update.
+ virtual void onPassExit() {}
+
+protected:
+ InlineAdvisor(FunctionAnalysisManager &FAM) : FAM(FAM) {}
+
+ FunctionAnalysisManager &FAM;
+
+ /// We may want to defer deleting functions to after the inlining for a whole
+ /// module has finished. This allows us to reliably use function pointers as
+ /// unique identifiers, as an efficient implementation detail of the
+ /// InlineAdvisor. Otherwise, it is possible the memory allocator
+ /// re-allocate Function objects at the same address of a deleted Function;
+ /// and Functions are potentially created during the function passes called
+ /// after each SCC inlining (e.g. argument promotion does that).
+ void freeDeletedFunctions();
+
+ bool isFunctionDeleted(const Function *F) const {
+ return DeletedFunctions.count(F);
+ }
+
+private:
+ friend class InlineAdvice;
+ void markFunctionAsDeleted(Function *F);
+ std::unordered_set<const Function *> DeletedFunctions;
+};
+
+/// The default (manual heuristics) implementation of the InlineAdvisor. This
+/// implementation does not need to keep state between inliner pass runs, and is
+/// reusable as-is for inliner pass test scenarios, as well as for regular use.
+class DefaultInlineAdvisor : public InlineAdvisor {
+public:
+ DefaultInlineAdvisor(FunctionAnalysisManager &FAM, InlineParams Params)
+ : InlineAdvisor(FAM), Params(Params) {}
+
+private:
+ std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB) override;
+
+ void onPassExit() override { freeDeletedFunctions(); }
+
+ InlineParams Params;
+};
+
+/// The InlineAdvisorAnalysis is a module pass because the InlineAdvisor
+/// needs to capture state right before inlining commences over a module.
+class InlineAdvisorAnalysis : public AnalysisInfoMixin<InlineAdvisorAnalysis> {
+public:
+ static AnalysisKey Key;
+ InlineAdvisorAnalysis() = default;
+ struct Result {
+ Result(Module &M, ModuleAnalysisManager &MAM) : M(M), MAM(MAM) {}
+ bool invalidate(Module &, const PreservedAnalyses &,
+ ModuleAnalysisManager::Invalidator &) {
+ // InlineAdvisor must be preserved across analysis invalidations.
+ return false;
+ }
+ bool tryCreate(InlineParams Params, InliningAdvisorMode Mode);
+ InlineAdvisor *getAdvisor() const { return Advisor.get(); }
+ void clear() { Advisor.reset(); }
+
+ private:
+ Module &M;
+ ModuleAnalysisManager &MAM;
+ std::unique_ptr<InlineAdvisor> Advisor;
+ };
+
+ Result run(Module &M, ModuleAnalysisManager &MAM) { return Result(M, MAM); }
+};
+
+#ifdef LLVM_HAVE_TF_AOT
+std::unique_ptr<InlineAdvisor>
+getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM);
+#endif
+
+// Default (manual policy) decision making helper APIs. Shared with the legacy
+// pass manager inliner.
+
+/// Return the cost only if the inliner should attempt to inline at the given
+/// CallSite. If we return the cost, we will emit an optimisation remark later
+/// using that cost, so we won't do so from this function. Return None if
+/// inlining should not be attempted.
+Optional<InlineCost>
+shouldInline(CallBase &CB, function_ref<InlineCost(CallBase &CB)> GetInlineCost,
+ OptimizationRemarkEmitter &ORE, bool EnableDeferral = true);
+
+/// Emit ORE message.
+void emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc,
+ const BasicBlock *Block, const Function &Callee,
+ const Function &Caller, const InlineCost &IC,
+ bool ForProfileContext = false,
+ const char *PassName = nullptr);
+
+/// Add location info to ORE message.
+void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc);
+
+/// Set the inline-remark attribute.
+void setInlineRemark(CallBase &CB, StringRef Message);
+
+/// Utility for extracting the inline cost message to a string.
+std::string inlineCostStr(const InlineCost &IC);
+} // namespace llvm
+#endif // LLVM_INLINEADVISOR_H_
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineCost.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineCost.h
index 611c9de24e47..7f04a8ce8f5f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineCost.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineCost.h
@@ -27,6 +27,7 @@ class DataLayout;
class Function;
class ProfileSummaryInfo;
class TargetTransformInfo;
+class TargetLibraryInfo;
namespace InlineConstants {
// Various thresholds used by inline cost analysis.
@@ -48,7 +49,10 @@ const int ColdccPenalty = 2000;
/// Do not inline functions which allocate this many bytes on the stack
/// when the caller is recursive.
const unsigned TotalAllocaSizeRecursiveCaller = 1024;
-}
+/// Do not inline dynamic allocas that have been constant propagated to be
+/// static allocas above this amount in bytes.
+const uint64_t MaxSimplifiedDynamicAllocaToInline = 65536;
+} // namespace InlineConstants
/// Represents the cost of inlining a function.
///
@@ -61,16 +65,13 @@ const unsigned TotalAllocaSizeRecursiveCaller = 1024;
/// directly tested to determine if inlining should occur given the cost and
/// threshold for this cost metric.
class InlineCost {
- enum SentinelValues {
- AlwaysInlineCost = INT_MIN,
- NeverInlineCost = INT_MAX
- };
+ enum SentinelValues { AlwaysInlineCost = INT_MIN, NeverInlineCost = INT_MAX };
/// The estimated cost of inlining this callsite.
- int Cost;
+ int Cost = 0;
/// The adjusted threshold against which this cost was computed.
- int Threshold;
+ int Threshold = 0;
/// Must be set for Always and Never instances.
const char *Reason = nullptr;
@@ -96,9 +97,7 @@ public:
}
/// Test whether the inline cost is low enough for inlining.
- explicit operator bool() const {
- return Cost < Threshold;
- }
+ explicit operator bool() const { return Cost < Threshold; }
bool isAlways() const { return Cost == AlwaysInlineCost; }
bool isNever() const { return Cost == NeverInlineCost; }
@@ -131,14 +130,22 @@ public:
};
/// InlineResult is basically true or false. For false results the message
-/// describes a reason why it is decided not to inline.
-struct InlineResult {
- const char *message = nullptr;
- InlineResult(bool result, const char *message = nullptr)
- : message(result ? nullptr : (message ? message : "cost > threshold")) {}
- InlineResult(const char *message = nullptr) : message(message) {}
- operator bool() const { return !message; }
- operator const char *() const { return message; }
+/// describes a reason.
+class InlineResult {
+ const char *Message = nullptr;
+ InlineResult(const char *Message = nullptr) : Message(Message) {}
+
+public:
+ static InlineResult success() { return {}; }
+ static InlineResult failure(const char *Reason) {
+ return InlineResult(Reason);
+ }
+ bool isSuccess() const { return Message == nullptr; }
+ const char *getFailureReason() const {
+ assert(!isSuccess() &&
+ "getFailureReason should only be called in failure cases");
+ return Message;
+ }
};
/// Thresholds to tune inline cost analysis. The inline cost analysis decides
@@ -152,7 +159,7 @@ struct InlineResult {
struct InlineParams {
/// The default threshold to start with for a callee.
- int DefaultThreshold;
+ int DefaultThreshold = -1;
/// Threshold to use for callees with inline hint.
Optional<int> HintThreshold;
@@ -178,6 +185,9 @@ struct InlineParams {
/// Compute inline cost even when the cost has exceeded the threshold.
Optional<bool> ComputeFullInlineCost;
+
+ /// Indicate whether we should allow inline deferral.
+ Optional<bool> EnableDeferral = true;
};
/// Generate the parameters to tune the inline cost analysis based only on the
@@ -212,11 +222,14 @@ int getCallsiteCost(CallBase &Call, const DataLayout &DL);
///
/// Also note that calling this function *dynamically* computes the cost of
/// inlining the callsite. It is an expensive, heavyweight call.
-InlineCost getInlineCost(
- CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI,
- std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE = nullptr);
+InlineCost
+getInlineCost(CallBase &Call, const InlineParams &Params,
+ TargetTransformInfo &CalleeTTI,
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
/// Get an InlineCost with the callee explicitly specified.
/// This allows you to calculate the cost of inlining a function via a
@@ -226,12 +239,51 @@ InlineCost getInlineCost(
InlineCost
getInlineCost(CallBase &Call, Function *Callee, const InlineParams &Params,
TargetTransformInfo &CalleeTTI,
- std::function<AssumptionCache &(Function &)> &GetAssumptionCache,
- Optional<function_ref<BlockFrequencyInfo &(Function &)>> GetBFI,
- ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE);
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
+
+/// Returns InlineResult::success() if the call site should be always inlined
+/// because of user directives, and the inlining is viable. Returns
+/// InlineResult::failure() if the inlining may never happen because of user
+/// directives or incompatibilities detectable without needing callee traversal.
+/// Otherwise returns None, meaning that inlining should be decided based on
+/// other criteria (e.g. cost modeling).
+Optional<InlineResult> getAttributeBasedInliningDecision(
+ CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI,
+ function_ref<const TargetLibraryInfo &(Function &)> GetTLI);
+
+/// Get the cost estimate ignoring thresholds. This is similar to getInlineCost
+/// when passed InlineParams::ComputeFullInlineCost, or a non-null ORE. It
+/// uses default InlineParams otherwise.
+/// Contrary to getInlineCost, which makes a threshold-based final evaluation of
+/// should/shouldn't inline, captured in InlineResult, getInliningCostEstimate
+/// returns:
+/// - None, if the inlining cannot happen (is illegal)
+/// - an integer, representing the cost.
+Optional<int> getInliningCostEstimate(
+ CallBase &Call, TargetTransformInfo &CalleeTTI,
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache,
+ function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr);
/// Minimal filter to detect invalid constructs for inlining.
InlineResult isInlineViable(Function &Callee);
-}
+
+// This pass is used to annotate instructions during the inline process for
+// debugging and analysis. The main purpose of the pass is to see and test
+// inliner's decisions when creating new optimizations to InlineCost.
+struct InlineCostAnnotationPrinterPass
+ : PassInfoMixin<InlineCostAnnotationPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit InlineCostAnnotationPrinterPass(raw_ostream &OS) : OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+};
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineFeaturesAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineFeaturesAnalysis.h
new file mode 100644
index 000000000000..cc3f96c424e9
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineFeaturesAnalysis.h
@@ -0,0 +1,45 @@
+//===- InlineFeaturesAnalysis.h - ML Policy Feature extraction -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INLINEFEATURESANALYSIS_H_
+#define LLVM_INLINEFEATURESANALYSIS_H_
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class Function;
+
+class InlineFeaturesAnalysis
+ : public AnalysisInfoMixin<InlineFeaturesAnalysis> {
+public:
+ static AnalysisKey Key;
+ struct Result {
+ /// Number of basic blocks
+ int64_t BasicBlockCount = 0;
+
+ /// Number of blocks reached from a conditional instruction, or that are
+ /// 'cases' of a SwitchInstr.
+ // FIXME: We may want to replace this with a more meaningful metric, like
+ // number of conditionally executed blocks:
+ // 'if (a) s();' would be counted here as 2 blocks, just like
+ // 'if (a) s(); else s2(); s3();' would.
+ int64_t BlocksReachedFromConditionalInstruction = 0;
+
+ /// Number of uses of this function, plus 1 if the function is callable
+ /// outside the module.
+ int64_t Uses = 0;
+
+ /// Number of direct calls made from this function to other functions
+ /// defined in this module.
+ int64_t DirectCallsToDefinedFunctions = 0;
+ };
+ Result run(const Function &F, FunctionAnalysisManager &FAM);
+};
+
+} // namespace llvm
+#endif // LLVM_INLINEFEATURESANALYSIS_H_ \ No newline at end of file
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
new file mode 100644
index 000000000000..8da442cc4a53
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineModelFeatureMaps.h
@@ -0,0 +1,70 @@
+//===- InlineModelFeatureMaps.h - common model runner defs ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H
+#define LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H
+
+#include <array>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+// List of features. Each feature is defined through a triple:
+// - the name of an enum member, which will be the feature index
+// - a textual name, used for Tensorflow model binding (so it needs to match the
+// names used by the Tensorflow model)
+// - a documentation description. Currently, that is not used anywhere
+// programmatically, and serves as workaround to inability of inserting comments
+// in macros.
+#define INLINE_FEATURE_ITERATOR(M) \
+ M(CalleeBasicBlockCount, "callee_basic_block_count", \
+ "number of basic blocks of the callee") \
+ M(CallSiteHeight, "callsite_height", \
+ "position of the call site in the original call graph - measured from " \
+ "the farthest SCC") \
+ M(NodeCount, "node_count", \
+ "total current number of defined functions in the module") \
+ M(NrCtantParams, "nr_ctant_params", \
+ "number of parameters in the call site that are constants") \
+ M(CostEstimate, "cost_estimate", "total cost estimate (threshold - free)") \
+ M(EdgeCount, "edge_count", \
+ "number of module-internal users of the caller, +1 if the caller is " \
+ "exposed externally") \
+ M(CallerUsers, "caller_users", \
+ "number of blocks reached from a conditional instruction, in the caller") \
+ M(CallerConditionallyExecutedBlocks, "caller_conditionally_executed_blocks", \
+ "number of blocks reached from a conditional instruction, in the caller") \
+ M(CallerBasicBlockCount, "caller_basic_block_count", \
+ "number of basic blocks in the caller") \
+ M(CalleeConditionallyExecutedBlocks, "callee_conditionally_executed_blocks", \
+ "number of blocks reached from a conditional instruction, in the callee") \
+ M(CalleeUsers, "callee_users", \
+ "number of blocks reached from a conditional instruction, in the callee")
+
+enum class FeatureIndex : size_t {
+#define POPULATE_INDICES(INDEX_NAME, NAME, COMMENT) INDEX_NAME,
+ INLINE_FEATURE_ITERATOR(POPULATE_INDICES)
+#undef POPULATE_INDICES
+ NumberOfFeatures
+};
+
+constexpr size_t NumberOfFeatures =
+ static_cast<size_t>(FeatureIndex::NumberOfFeatures);
+
+extern const std::array<std::string, NumberOfFeatures> FeatureNameMap;
+
+extern const char *const DecisionName;
+extern const char *const DefaultDecisionName;
+extern const char *const RewardName;
+
+using InlineFeatures = std::vector<int64_t>;
+
+} // namespace llvm
+#endif // LLVM_ANALYSIS_INLINEMODELFEATUREMAPS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h
new file mode 100644
index 000000000000..29a6f5914674
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InlineSizeEstimatorAnalysis.h
@@ -0,0 +1,35 @@
+//===- InlineSizeEstimatorAnalysis.h - ML size estimator --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_ANALYSIS_INLINESIZEESTIMATORANALYSIS_H
+#define LLVM_ANALYSIS_INLINESIZEESTIMATORANALYSIS_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class Function;
+
+class TFModelEvaluator;
+class InlineSizeEstimatorAnalysis
+ : public AnalysisInfoMixin<InlineSizeEstimatorAnalysis> {
+public:
+ InlineSizeEstimatorAnalysis();
+ InlineSizeEstimatorAnalysis(InlineSizeEstimatorAnalysis &&);
+ ~InlineSizeEstimatorAnalysis();
+
+ static AnalysisKey Key;
+ using Result = Optional<size_t>;
+ Result run(const Function &F, FunctionAnalysisManager &FAM);
+ static bool isEvaluatorRequested();
+
+private:
+ std::unique_ptr<TFModelEvaluator> Evaluator;
+};
+} // namespace llvm
+#endif // LLVM_ANALYSIS_INLINESIZEESTIMATORANALYSIS_H \ No newline at end of file
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionPrecedenceTracking.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionPrecedenceTracking.h
index 3c3981066a49..46bc974c4a7f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionPrecedenceTracking.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionPrecedenceTracking.h
@@ -20,18 +20,18 @@
#ifndef LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
#define LLVM_ANALYSIS_INSTRUCTIONPRECEDENCETRACKING_H
-#include "llvm/IR/Dominators.h"
-#include "llvm/Analysis/OrderedInstructions.h"
+#include "llvm/ADT/DenseMap.h"
namespace llvm {
+class BasicBlock;
+class Instruction;
+
class InstructionPrecedenceTracking {
// Maps a block to the topmost special instruction in it. If the value is
// nullptr, it means that it is known that this block does not contain any
// special instructions.
DenseMap<const BasicBlock *, const Instruction *> FirstSpecialInsts;
- // Allows to answer queries about precedence of instructions within one block.
- OrderedInstructions OI;
// Fills information about the given block's special instructions.
void fill(const BasicBlock *BB);
@@ -49,9 +49,6 @@ class InstructionPrecedenceTracking {
#endif
protected:
- InstructionPrecedenceTracking(DominatorTree *DT)
- : OI(OrderedInstructions(DT)) {}
-
/// Returns the topmost special instruction from the block \p BB. Returns
/// nullptr if there is no special instructions in the block.
const Instruction *getFirstSpecialInstruction(const BasicBlock *BB);
@@ -96,9 +93,6 @@ public:
/// perform PRE moving non-speculable instruction to other place.
class ImplicitControlFlowTracking : public InstructionPrecedenceTracking {
public:
- ImplicitControlFlowTracking(DominatorTree *DT)
- : InstructionPrecedenceTracking(DT) {}
-
/// Returns the topmost instruction with implicit control flow from the given
/// basic block. Returns nullptr if there is no such instructions in the block.
const Instruction *getFirstICFI(const BasicBlock *BB) {
@@ -116,13 +110,11 @@ public:
return isPreceededBySpecialInstruction(Insn);
}
- virtual bool isSpecialInstruction(const Instruction *Insn) const;
+ bool isSpecialInstruction(const Instruction *Insn) const override;
};
class MemoryWriteTracking : public InstructionPrecedenceTracking {
public:
- MemoryWriteTracking(DominatorTree *DT) : InstructionPrecedenceTracking(DT) {}
-
/// Returns the topmost instruction that may write memory from the given
/// basic block. Returns nullptr if there is no such instructions in the block.
const Instruction *getFirstMemoryWrite(const BasicBlock *BB) {
@@ -141,7 +133,7 @@ public:
return isPreceededBySpecialInstruction(Insn);
}
- virtual bool isSpecialInstruction(const Instruction *Insn) const;
+ bool isSpecialInstruction(const Instruction *Insn) const override;
};
} // llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionSimplify.h b/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionSimplify.h
index b661caee6848..2a39a4e09087 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionSimplify.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/InstructionSimplify.h
@@ -31,28 +31,27 @@
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
#define LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
-#include "llvm/ADT/SetVector.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Operator.h"
-#include "llvm/IR/User.h"
namespace llvm {
-class Function;
+
template <typename T, typename... TArgs> class AnalysisManager;
template <class T> class ArrayRef;
class AssumptionCache;
+class BinaryOperator;
class CallBase;
-class DominatorTree;
class DataLayout;
-class FastMathFlags;
+class DominatorTree;
+class Function;
struct LoopStandardAnalysisResults;
+class MDNode;
class OptimizationRemarkEmitter;
class Pass;
+template <class T, unsigned n> class SmallSetVector;
class TargetLibraryInfo;
class Type;
class Value;
-class MDNode;
-class BinaryOperator;
/// InstrInfoQuery provides an interface to query additional information for
/// instructions like metadata or keywords like nsw, which provides conservative
@@ -230,7 +229,8 @@ Value *SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty,
const SimplifyQuery &Q);
/// Given operands for a ShuffleVectorInst, fold the result or return null.
-Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, Constant *Mask,
+/// See class ShuffleVectorInst for a description of the mask representation.
+Value *SimplifyShuffleVectorInst(Value *Op0, Value *Op1, ArrayRef<int> Mask,
Type *RetTy, const SimplifyQuery &Q);
//=== Helper functions for higher up the class hierarchy.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h b/contrib/llvm-project/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
index 7c826780c318..fb6605285156 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/IteratedDominanceFrontier.h
@@ -9,7 +9,7 @@
#ifndef LLVM_ANALYSIS_IDF_H
#define LLVM_ANALYSIS_IDF_H
-#include "llvm/IR/CFGDiff.h"
+#include "llvm/Support/CFGDiff.h"
#include "llvm/Support/GenericIteratedDominanceFrontier.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
index cae0778cd16d..f4249f74104c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyBranchProbabilityInfo.h
@@ -63,7 +63,7 @@ class LazyBranchProbabilityInfoPass : public FunctionPass {
BranchProbabilityInfo &getCalculated() {
if (!Calculated) {
assert(F && LI && "call setAnalysis");
- BPI.calculate(*F, *LI, TLI);
+ BPI.calculate(*F, *LI, TLI, nullptr);
Calculated = true;
}
return BPI;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyCallGraph.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyCallGraph.h
index 20a35bef189b..ea63b837ba70 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyCallGraph.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyCallGraph.h
@@ -937,6 +937,9 @@ public:
LazyCallGraph(LazyCallGraph &&G);
LazyCallGraph &operator=(LazyCallGraph &&RHS);
+ bool invalidate(Module &, const PreservedAnalyses &PA,
+ ModuleAnalysisManager::Invalidator &);
+
EdgeSequence::iterator begin() { return EntryEdges.begin(); }
EdgeSequence::iterator end() { return EntryEdges.end(); }
@@ -1055,6 +1058,13 @@ public:
/// fully visited by the DFS prior to calling this routine.
void removeDeadFunction(Function &F);
+ /// Introduce a node for the function \p NewF in the SCC \p C.
+ void addNewFunctionIntoSCC(Function &NewF, SCC &C);
+
+ /// Introduce a node for the function \p NewF, as a single node in a
+ /// new SCC, in the RefSCC \p RC.
+ void addNewFunctionIntoRefSCC(Function &NewF, RefSCC &RC);
+
///@}
///@{
@@ -1161,6 +1171,13 @@ private:
/// Helper to update pointers back to the graph object during moves.
void updateGraphPtrs();
+ /// Helper to insert a new function, add it to the NodeMap, and populate its
+ /// node.
+ Node &createNode(Function &F);
+
+ /// Helper to add the given Node \p N to the SCCMap, mapped to the SCC \p C.
+ void addNodeToSCC(SCC &C, Node &N);
+
/// Allocates an SCC and constructs it using the graph allocator.
///
/// The arguments are forwarded to the constructor.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h
index 74e8f5072037..1bc88235273e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LazyValueInfo.h
@@ -33,18 +33,17 @@ class LazyValueInfo {
AssumptionCache *AC = nullptr;
const DataLayout *DL = nullptr;
class TargetLibraryInfo *TLI = nullptr;
- DominatorTree *DT = nullptr;
void *PImpl = nullptr;
LazyValueInfo(const LazyValueInfo&) = delete;
void operator=(const LazyValueInfo&) = delete;
public:
~LazyValueInfo();
LazyValueInfo() {}
- LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_, TargetLibraryInfo *TLI_,
- DominatorTree *DT_)
- : AC(AC_), DL(DL_), TLI(TLI_), DT(DT_) {}
+ LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
+ TargetLibraryInfo *TLI_)
+ : AC(AC_), DL(DL_), TLI(TLI_) {}
LazyValueInfo(LazyValueInfo &&Arg)
- : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
+ : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
Arg.PImpl = nullptr;
}
LazyValueInfo &operator=(LazyValueInfo &&Arg) {
@@ -52,7 +51,6 @@ public:
AC = Arg.AC;
DL = Arg.DL;
TLI = Arg.TLI;
- DT = Arg.DT;
PImpl = Arg.PImpl;
Arg.PImpl = nullptr;
return *this;
@@ -85,7 +83,9 @@ public:
/// Return the ConstantRange constraint that is known to hold for the
/// specified value at the end of the specified block. This may only be called
/// on integer-typed Values.
- ConstantRange getConstantRange(Value *V, BasicBlock *BB, Instruction *CxtI = nullptr);
+ ConstantRange getConstantRange(Value *V, BasicBlock *BB,
+ Instruction *CxtI = nullptr,
+ bool UndefAllowed = true);
/// Determine whether the specified value is known to be a
/// constant on the specified edge. Return null if not.
@@ -108,17 +108,9 @@ public:
/// Print the \LazyValueInfo Analysis.
/// We pass in the DTree that is required for identifying which basic blocks
- /// we can solve/print for, in the LVIPrinter. The DT is optional
- /// in LVI, so we need to pass it here as an argument.
+ /// we can solve/print for, in the LVIPrinter.
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
- /// Disables use of the DominatorTree within LVI.
- void disableDT();
-
- /// Enables use of the DominatorTree within LVI. Does nothing if the class
- /// instance was initialized without a DT pointer.
- void enableDT();
-
// For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
void releaseMemory();
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h
index 0770093bcd48..15400f5e07ff 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LegacyDivergenceAnalysis.h
@@ -16,13 +16,18 @@
#define LLVM_ANALYSIS_LEGACY_DIVERGENCE_ANALYSIS_H
#include "llvm/ADT/DenseSet.h"
-#include "llvm/Analysis/DivergenceAnalysis.h"
#include "llvm/Pass.h"
+#include <memory>
namespace llvm {
-class Value;
class Function;
class GPUDivergenceAnalysis;
+class Module;
+class raw_ostream;
+class TargetTransformInfo;
+class Use;
+class Value;
+
class LegacyDivergenceAnalysis : public FunctionPass {
public:
static char ID;
@@ -54,7 +59,8 @@ public:
private:
// Whether analysis should be performed by GPUDivergenceAnalysis.
- bool shouldUseGPUDivergenceAnalysis(const Function &F) const;
+ bool shouldUseGPUDivergenceAnalysis(const Function &F,
+ const TargetTransformInfo &TTI) const;
// (optional) handle to new DivergenceAnalysis
std::unique_ptr<GPUDivergenceAnalysis> gpuDA;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/Loads.h b/contrib/llvm-project/llvm/include/llvm/Analysis/Loads.h
index 9604b2521e89..5665a802942d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/Loads.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/Loads.h
@@ -13,13 +13,16 @@
#ifndef LLVM_ANALYSIS_LOADS_H
#define LLVM_ANALYSIS_LOADS_H
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/CommandLine.h"
namespace llvm {
+class AAResults;
class DataLayout;
+class DominatorTree;
+class Instruction;
+class LoadInst;
class Loop;
class MDNode;
class ScalarEvolution;
@@ -59,7 +62,7 @@ bool isDereferenceableAndAlignedPointer(const Value *V, Align Alignment,
/// If it is not obviously safe to load from the specified pointer, we do a
/// quick local scan of the basic block containing ScanFrom, to determine if
/// the address is already accessed.
-bool isSafeToLoadUnconditionally(Value *V, MaybeAlign Alignment, APInt &Size,
+bool isSafeToLoadUnconditionally(Value *V, Align Alignment, APInt &Size,
const DataLayout &DL,
Instruction *ScanFrom = nullptr,
const DominatorTree *DT = nullptr);
@@ -83,7 +86,7 @@ bool isDereferenceableAndAlignedInLoop(LoadInst *LI, Loop *L,
/// If it is not obviously safe to load from the specified pointer, we do a
/// quick local scan of the basic block containing ScanFrom, to determine if
/// the address is already accessed.
-bool isSafeToLoadUnconditionally(Value *V, Type *Ty, MaybeAlign Alignment,
+bool isSafeToLoadUnconditionally(Value *V, Type *Ty, Align Alignment,
const DataLayout &DL,
Instruction *ScanFrom = nullptr,
const DominatorTree *DT = nullptr);
@@ -120,7 +123,7 @@ Value *FindAvailableLoadedValue(LoadInst *Load,
BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
unsigned MaxInstsToScan = DefMaxInstsToScan,
- AliasAnalysis *AA = nullptr,
+ AAResults *AA = nullptr,
bool *IsLoadCSE = nullptr,
unsigned *NumScanedInst = nullptr);
@@ -143,15 +146,15 @@ Value *FindAvailableLoadedValue(LoadInst *Load,
/// is zero, the whole block will be scanned.
/// \param AA Optional pointer to alias analysis, to make the scan more
/// precise.
-/// \param [out] IsLoad Whether the returned value is a load from the same
+/// \param [out] IsLoadCSE Whether the returned value is a load from the same
/// location in memory, as opposed to the value operand of a store.
///
/// \returns The found value, or nullptr if no value is found.
Value *FindAvailablePtrLoadStore(Value *Ptr, Type *AccessTy, bool AtLeastAtomic,
BasicBlock *ScanBB,
BasicBlock::iterator &ScanFrom,
- unsigned MaxInstsToScan, AliasAnalysis *AA,
- bool *IsLoad, unsigned *NumScanedInst);
+ unsigned MaxInstsToScan, AAResults *AA,
+ bool *IsLoadCSE, unsigned *NumScanedInst);
}
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAccessAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
index 7f8639ac90d1..a5237e9ba59e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -15,27 +15,22 @@
#define LLVM_ANALYSIS_LOOPACCESSANALYSIS_H
#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AliasSetTracker.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
-class Value;
+class AAResults;
class DataLayout;
-class ScalarEvolution;
class Loop;
-class SCEV;
-class SCEVUnionPredicate;
class LoopAccessInfo;
class OptimizationRemarkEmitter;
+class raw_ostream;
+class SCEV;
+class SCEVUnionPredicate;
+class Value;
/// Collection of parameters shared beetween the Loop Vectorizer and the
/// Loop Access Analysis.
@@ -329,9 +324,45 @@ private:
void mergeInStatus(VectorizationSafetyStatus S);
};
+class RuntimePointerChecking;
+/// A grouping of pointers. A single memcheck is required between
+/// two groups.
+struct RuntimeCheckingPtrGroup {
+ /// Create a new pointer checking group containing a single
+ /// pointer, with index \p Index in RtCheck.
+ RuntimeCheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck);
+
+ /// Tries to add the pointer recorded in RtCheck at index
+ /// \p Index to this pointer checking group. We can only add a pointer
+ /// to a checking group if we will still be able to get
+ /// the upper and lower bounds of the check. Returns true in case
+ /// of success, false otherwise.
+ bool addPointer(unsigned Index);
+
+ /// Constitutes the context of this pointer checking group. For each
+ /// pointer that is a member of this group we will retain the index
+ /// at which it appears in RtCheck.
+ RuntimePointerChecking &RtCheck;
+ /// The SCEV expression which represents the upper bound of all the
+ /// pointers in this group.
+ const SCEV *High;
+ /// The SCEV expression which represents the lower bound of all the
+ /// pointers in this group.
+ const SCEV *Low;
+ /// Indices of all the pointers that constitute this grouping.
+ SmallVector<unsigned, 2> Members;
+};
+
+/// A memcheck which made up of a pair of grouped pointers.
+typedef std::pair<const RuntimeCheckingPtrGroup *,
+ const RuntimeCheckingPtrGroup *>
+ RuntimePointerCheck;
+
/// Holds information about the memory runtime legality checks to verify
/// that a group of pointers do not overlap.
class RuntimePointerChecking {
+ friend struct RuntimeCheckingPtrGroup;
+
public:
struct PointerInfo {
/// Holds the pointer value that we need to check.
@@ -381,59 +412,20 @@ public:
/// No run-time memory checking is necessary.
bool empty() const { return Pointers.empty(); }
- /// A grouping of pointers. A single memcheck is required between
- /// two groups.
- struct CheckingPtrGroup {
- /// Create a new pointer checking group containing a single
- /// pointer, with index \p Index in RtCheck.
- CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck)
- : RtCheck(RtCheck), High(RtCheck.Pointers[Index].End),
- Low(RtCheck.Pointers[Index].Start) {
- Members.push_back(Index);
- }
-
- /// Tries to add the pointer recorded in RtCheck at index
- /// \p Index to this pointer checking group. We can only add a pointer
- /// to a checking group if we will still be able to get
- /// the upper and lower bounds of the check. Returns true in case
- /// of success, false otherwise.
- bool addPointer(unsigned Index);
-
- /// Constitutes the context of this pointer checking group. For each
- /// pointer that is a member of this group we will retain the index
- /// at which it appears in RtCheck.
- RuntimePointerChecking &RtCheck;
- /// The SCEV expression which represents the upper bound of all the
- /// pointers in this group.
- const SCEV *High;
- /// The SCEV expression which represents the lower bound of all the
- /// pointers in this group.
- const SCEV *Low;
- /// Indices of all the pointers that constitute this grouping.
- SmallVector<unsigned, 2> Members;
- };
-
- /// A memcheck which made up of a pair of grouped pointers.
- ///
- /// These *have* to be const for now, since checks are generated from
- /// CheckingPtrGroups in LAI::addRuntimeChecks which is a const member
- /// function. FIXME: once check-generation is moved inside this class (after
- /// the PtrPartition hack is removed), we could drop const.
- typedef std::pair<const CheckingPtrGroup *, const CheckingPtrGroup *>
- PointerCheck;
-
/// Generate the checks and store it. This also performs the grouping
/// of pointers to reduce the number of memchecks necessary.
void generateChecks(MemoryDepChecker::DepCandidates &DepCands,
bool UseDependencies);
/// Returns the checks that generateChecks created.
- const SmallVector<PointerCheck, 4> &getChecks() const { return Checks; }
+ const SmallVector<RuntimePointerCheck, 4> &getChecks() const {
+ return Checks;
+ }
/// Decide if we need to add a check between two groups of pointers,
/// according to needsChecking.
- bool needsChecking(const CheckingPtrGroup &M,
- const CheckingPtrGroup &N) const;
+ bool needsChecking(const RuntimeCheckingPtrGroup &M,
+ const RuntimeCheckingPtrGroup &N) const;
/// Returns the number of run-time checks required according to
/// needsChecking.
@@ -443,7 +435,8 @@ public:
void print(raw_ostream &OS, unsigned Depth = 0) const;
/// Print \p Checks.
- void printChecks(raw_ostream &OS, const SmallVectorImpl<PointerCheck> &Checks,
+ void printChecks(raw_ostream &OS,
+ const SmallVectorImpl<RuntimePointerCheck> &Checks,
unsigned Depth = 0) const;
/// This flag indicates if we need to add the runtime check.
@@ -453,7 +446,7 @@ public:
SmallVector<PointerInfo, 2> Pointers;
/// Holds a partitioning of pointers into "check groups".
- SmallVector<CheckingPtrGroup, 2> CheckingGroups;
+ SmallVector<RuntimeCheckingPtrGroup, 2> CheckingGroups;
/// Check if pointers are in the same partition
///
@@ -472,6 +465,8 @@ public:
return Pointers[PtrIdx];
}
+ ScalarEvolution *getSE() const { return SE; }
+
private:
/// Groups pointers such that a single memcheck is required
/// between two different groups. This will clear the CheckingGroups vector
@@ -481,15 +476,14 @@ private:
bool UseDependencies);
/// Generate the checks and return them.
- SmallVector<PointerCheck, 4>
- generateChecks() const;
+ SmallVector<RuntimePointerCheck, 4> generateChecks() const;
/// Holds a pointer to the ScalarEvolution analysis.
ScalarEvolution *SE;
/// Set of run-time checks required to establish independence of
/// otherwise may-aliasing pointers in the loop.
- SmallVector<PointerCheck, 4> Checks;
+ SmallVector<RuntimePointerCheck, 4> Checks;
};
/// Drive the analysis of memory accesses in the loop
@@ -516,7 +510,7 @@ private:
class LoopAccessInfo {
public:
LoopAccessInfo(Loop *L, ScalarEvolution *SE, const TargetLibraryInfo *TLI,
- AliasAnalysis *AA, DominatorTree *DT, LoopInfo *LI);
+ AAResults *AA, DominatorTree *DT, LoopInfo *LI);
/// Return true we can analyze the memory accesses in the loop and there are
/// no memory dependence cycles.
@@ -549,24 +543,6 @@ public:
unsigned getNumStores() const { return NumStores; }
unsigned getNumLoads() const { return NumLoads;}
- /// Add code that checks at runtime if the accessed arrays overlap.
- ///
- /// Returns a pair of instructions where the first element is the first
- /// instruction generated in possibly a sequence of instructions and the
- /// second value is the final comparator value or NULL if no check is needed.
- std::pair<Instruction *, Instruction *>
- addRuntimeChecks(Instruction *Loc) const;
-
- /// Generete the instructions for the checks in \p PointerChecks.
- ///
- /// Returns a pair of instructions where the first element is the first
- /// instruction generated in possibly a sequence of instructions and the
- /// second value is the final comparator value or NULL if no check is needed.
- std::pair<Instruction *, Instruction *>
- addRuntimeChecks(Instruction *Loc,
- const SmallVectorImpl<RuntimePointerChecking::PointerCheck>
- &PointerChecks) const;
-
/// The diagnostics report generated for the analysis. E.g. why we
/// couldn't analyze the loop.
const OptimizationRemarkAnalysis *getReport() const { return Report.get(); }
@@ -607,7 +583,7 @@ public:
private:
/// Analyze the loop.
- void analyzeLoop(AliasAnalysis *AA, LoopInfo *LI,
+ void analyzeLoop(AAResults *AA, LoopInfo *LI,
const TargetLibraryInfo *TLI, DominatorTree *DT);
/// Check if the structure of the loop allows it to be analyzed by this
@@ -750,7 +726,7 @@ private:
// The used analysis passes.
ScalarEvolution *SE = nullptr;
const TargetLibraryInfo *TLI = nullptr;
- AliasAnalysis *AA = nullptr;
+ AAResults *AA = nullptr;
DominatorTree *DT = nullptr;
LoopInfo *LI = nullptr;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAnalysisManager.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAnalysisManager.h
index a2e65a7310af..0e162e03bde1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAnalysisManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopAnalysisManager.h
@@ -30,22 +30,21 @@
#define LLVM_ANALYSIS_LOOPANALYSISMANAGER_H
#include "llvm/ADT/PostOrderIterator.h"
-#include "llvm/ADT/PriorityWorklist.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/GlobalsModRef.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class AAResults;
+class AssumptionCache;
+class DominatorTree;
+class Function;
+class Loop;
+class LoopInfo;
+class MemorySSA;
+class ScalarEvolution;
+class TargetLibraryInfo;
+class TargetTransformInfo;
+
/// The adaptor from a function pass to a loop pass computes these analyses and
/// makes them available to the loop passes "for free". Each loop pass is
/// expected expected to update these analyses if necessary to ensure they're
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfo.h
index a01045124c7b..35fe2a03a2a2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfo.h
@@ -60,7 +60,6 @@ class Loop;
class InductionDescriptor;
class MDNode;
class MemorySSAUpdater;
-class PHINode;
class ScalarEvolution;
class raw_ostream;
template <class N, bool IsPostDom> class DominatorTreeBase;
@@ -103,6 +102,14 @@ public:
return D;
}
BlockT *getHeader() const { return getBlocks().front(); }
+ /// Return the parent loop if it exists or nullptr for top
+ /// level loops.
+
+ /// A loop is either top-level in a function (that is, it is not
+ /// contained in any other loop) or it is entirely enclosed in
+ /// some other loop.
+ /// If a loop is top-level, it has no parent, otherwise its
+ /// parent is the innermost loop in which it is enclosed.
LoopT *getParentLoop() const { return ParentLoop; }
/// This is a raw interface for bypassing addChildLoop.
@@ -772,10 +779,11 @@ public:
bool isCanonical(ScalarEvolution &SE) const;
/// Return true if the Loop is in LCSSA form.
- bool isLCSSAForm(DominatorTree &DT) const;
+ bool isLCSSAForm(const DominatorTree &DT) const;
/// Return true if this Loop and all inner subloops are in LCSSA form.
- bool isRecursivelyLCSSAForm(DominatorTree &DT, const LoopInfo &LI) const;
+ bool isRecursivelyLCSSAForm(const DominatorTree &DT,
+ const LoopInfo &LI) const;
/// Return true if the Loop is in the form that the LoopSimplify form
/// transforms loops to, which is sometimes called normal form.
@@ -954,6 +962,12 @@ public:
return L && L->getHeader() == BB;
}
+ /// Return the top-level loops.
+ const std::vector<LoopT *> &getTopLevelLoops() const { return TopLevelLoops; }
+
+ /// Return the top-level loops.
+ std::vector<LoopT *> &getTopLevelLoopsVector() { return TopLevelLoops; }
+
/// This removes the specified top-level loop from this loop info object.
/// The loop is not deleted, as it will presumably be inserted into
/// another loop.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfoImpl.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfoImpl.h
index 99f192a59215..58a4abafcc85 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfoImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopInfoImpl.h
@@ -17,7 +17,6 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Dominators.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopNestAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopNestAnalysis.h
new file mode 100644
index 000000000000..792958a312ce
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopNestAnalysis.h
@@ -0,0 +1,162 @@
+//===- llvm/Analysis/LoopNestAnalysis.h -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file defines the interface for the loop nest analysis.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOPNESTANALYSIS_H
+#define LLVM_ANALYSIS_LOOPNESTANALYSIS_H
+
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/Analysis/LoopInfo.h"
+
+namespace llvm {
+
+using LoopVectorTy = SmallVector<Loop *, 8>;
+class LPMUpdater;
+
+/// This class represents a loop nest and can be used to query its properties.
+class LoopNest {
+public:
+ /// Construct a loop nest rooted by loop \p Root.
+ LoopNest(Loop &Root, ScalarEvolution &SE);
+
+ LoopNest() = delete;
+ LoopNest &operator=(const LoopNest &) = delete;
+
+ /// Construct a LoopNest object.
+ static std::unique_ptr<LoopNest> getLoopNest(Loop &Root, ScalarEvolution &SE);
+
+ /// Return true if the given loops \p OuterLoop and \p InnerLoop are
+ /// perfectly nested with respect to each other, and false otherwise.
+ /// Example:
+ /// \code
+ /// for(i)
+ /// for(j)
+ /// for(k)
+ /// \endcode
+ /// arePerfectlyNested(loop_i, loop_j, SE) would return true.
+ /// arePerfectlyNested(loop_j, loop_k, SE) would return true.
+ /// arePerfectlyNested(loop_i, loop_k, SE) would return false.
+ static bool arePerfectlyNested(const Loop &OuterLoop, const Loop &InnerLoop,
+ ScalarEvolution &SE);
+
+ /// Return the maximum nesting depth of the loop nest rooted by loop \p Root.
+ /// For example given the loop nest:
+ /// \code
+ /// for(i) // loop at level 1 and Root of the nest
+ /// for(j) // loop at level 2
+ /// <code>
+ /// for(k) // loop at level 3
+ /// \endcode
+ /// getMaxPerfectDepth(Loop_i) would return 2.
+ static unsigned getMaxPerfectDepth(const Loop &Root, ScalarEvolution &SE);
+
+ /// Return the outermost loop in the loop nest.
+ Loop &getOutermostLoop() const { return *Loops.front(); }
+
+ /// Return the innermost loop in the loop nest if the nest has only one
+ /// innermost loop, and a nullptr otherwise.
+ /// Note: the innermost loop returned is not necessarily perfectly nested.
+ Loop *getInnermostLoop() const {
+ if (Loops.size() == 1)
+ return Loops.back();
+
+ // The loops in the 'Loops' vector have been collected in breadth first
+ // order, therefore if the last 2 loops in it have the same nesting depth
+ // there isn't a unique innermost loop in the nest.
+ Loop *LastLoop = Loops.back();
+ auto SecondLastLoopIter = ++Loops.rbegin();
+ return (LastLoop->getLoopDepth() == (*SecondLastLoopIter)->getLoopDepth())
+ ? nullptr
+ : LastLoop;
+ }
+
+ /// Return the loop at the given \p Index.
+ Loop *getLoop(unsigned Index) const {
+ assert(Index < Loops.size() && "Index is out of bounds");
+ return Loops[Index];
+ }
+
+ /// Return the number of loops in the nest.
+ size_t getNumLoops() const { return Loops.size(); }
+
+ /// Get the loops in the nest.
+ ArrayRef<Loop *> getLoops() const { return Loops; }
+
+ /// Retrieve a vector of perfect loop nests contained in the current loop
+ /// nest. For example, given the following nest containing 4 loops, this
+ /// member function would return {{L1,L2},{L3,L4}}.
+ /// \code
+ /// for(i) // L1
+ /// for(j) // L2
+ /// <code>
+ /// for(k) // L3
+ /// for(l) // L4
+ /// \endcode
+ SmallVector<LoopVectorTy, 4> getPerfectLoops(ScalarEvolution &SE) const;
+
+ /// Return the loop nest depth (i.e. the loop depth of the 'deepest' loop)
+ /// For example given the loop nest:
+ /// \code
+ /// for(i) // loop at level 1 and Root of the nest
+ /// for(j1) // loop at level 2
+ /// for(k) // loop at level 3
+ /// for(j2) // loop at level 2
+ /// \endcode
+ /// getNestDepth() would return 3.
+ unsigned getNestDepth() const {
+ int NestDepth =
+ Loops.back()->getLoopDepth() - Loops.front()->getLoopDepth() + 1;
+ assert(NestDepth > 0 && "Expecting NestDepth to be at least 1");
+ return NestDepth;
+ }
+
+ /// Return the maximum perfect nesting depth.
+ unsigned getMaxPerfectDepth() const { return MaxPerfectDepth; }
+
+ /// Return true if all loops in the loop nest are in simplify form.
+ bool areAllLoopsSimplifyForm() const {
+ return llvm::all_of(Loops,
+ [](const Loop *L) { return L->isLoopSimplifyForm(); });
+ }
+
+protected:
+ const unsigned MaxPerfectDepth; // maximum perfect nesting depth level.
+ LoopVectorTy Loops; // the loops in the nest (in breadth first order).
+};
+
+raw_ostream &operator<<(raw_ostream &, const LoopNest &);
+
+/// This analysis provides information for a loop nest. The analysis runs on
+/// demand and can be initiated via AM.getResult<LoopNestAnalysis>.
+class LoopNestAnalysis : public AnalysisInfoMixin<LoopNestAnalysis> {
+ friend AnalysisInfoMixin<LoopNestAnalysis>;
+ static AnalysisKey Key;
+
+public:
+ using Result = LoopNest;
+ Result run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR);
+};
+
+/// Printer pass for the \c LoopNest results.
+class LoopNestPrinterPass : public PassInfoMixin<LoopNestPrinterPass> {
+ raw_ostream &OS;
+
+public:
+ explicit LoopNestPrinterPass(raw_ostream &OS) : OS(OS) {}
+
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_LOOPNESTANALYSIS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopPass.h b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopPass.h
index 04fed15f15f9..0fd2a39eefc0 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/LoopPass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/LoopPass.h
@@ -23,7 +23,6 @@ namespace llvm {
class LPPassManager;
class Function;
-class PMStack;
class LoopPass : public Pass {
public:
@@ -66,26 +65,6 @@ public:
return PMT_LoopPassManager;
}
- //===--------------------------------------------------------------------===//
- /// SimpleAnalysis - Provides simple interface to update analysis info
- /// maintained by various passes. Note, if required this interface can
- /// be extracted into a separate abstract class but it would require
- /// additional use of multiple inheritance in Pass class hierarchy, something
- /// we are trying to avoid.
-
- /// Each loop pass can override these simple analysis hooks to update
- /// desired analysis information.
- /// cloneBasicBlockAnalysis - Clone analysis info associated with basic block.
- virtual void cloneBasicBlockAnalysis(BasicBlock *F, BasicBlock *T, Loop *L) {}
-
- /// deleteAnalysisValue - Delete analysis info associated with value V.
- virtual void deleteAnalysisValue(Value *V, Loop *L) {}
-
- /// Delete analysis info associated with Loop L.
- /// Called to notify a Pass that a loop has been deleted and any
- /// associated analysis values can be deleted.
- virtual void deleteAnalysisLoop(Loop *L) {}
-
protected:
/// Optional passes call this function to check whether the pass should be
/// skipped. This is the case when Attribute::OptimizeNone is set or when
@@ -131,25 +110,6 @@ public:
// Mark \p L as deleted.
void markLoopAsDeleted(Loop &L);
- //===--------------------------------------------------------------------===//
- /// SimpleAnalysis - Provides simple interface to update analysis info
- /// maintained by various passes. Note, if required this interface can
- /// be extracted into a separate abstract class but it would require
- /// additional use of multiple inheritance in Pass class hierarchy, something
- /// we are trying to avoid.
-
- /// cloneBasicBlockSimpleAnalysis - Invoke cloneBasicBlockAnalysis hook for
- /// all passes that implement simple analysis interface.
- void cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L);
-
- /// deleteSimpleAnalysisValue - Invoke deleteAnalysisValue hook for all passes
- /// that implement simple analysis interface.
- void deleteSimpleAnalysisValue(Value *V, Loop *L);
-
- /// Invoke deleteAnalysisLoop hook for all passes that implement simple
- /// analysis interface.
- void deleteSimpleAnalysisLoop(Loop *L);
-
private:
std::deque<Loop *> LQ;
LoopInfo *LI;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MLInlineAdvisor.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MLInlineAdvisor.h
new file mode 100644
index 000000000000..cbe3b1f1f4e6
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MLInlineAdvisor.h
@@ -0,0 +1,107 @@
+//===- MLInlineAdvisor.h - ML - based InlineAdvisor factories ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MLINLINEADVISOR_H
+#define LLVM_ANALYSIS_MLINLINEADVISOR_H
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/InlineAdvisor.h"
+#include "llvm/Analysis/MLModelRunner.h"
+#include "llvm/IR/PassManager.h"
+
+#include <memory>
+#include <unordered_map>
+
+namespace llvm {
+class Module;
+class MLInlineAdvice;
+
+class MLInlineAdvisor : public InlineAdvisor {
+public:
+ MLInlineAdvisor(Module &M, ModuleAnalysisManager &MAM,
+ std::unique_ptr<MLModelRunner> ModelRunner);
+
+ CallGraph *callGraph() const { return CG.get(); }
+ virtual ~MLInlineAdvisor() = default;
+
+ void onPassEntry() override;
+
+ std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB) override;
+
+ int64_t getIRSize(const Function &F) const { return F.getInstructionCount(); }
+ void onSuccessfulInlining(const MLInlineAdvice &Advice,
+ bool CalleeWasDeleted);
+
+ bool isForcedToStop() const { return ForceStop; }
+ int64_t getLocalCalls(Function &F);
+ const MLModelRunner &getModelRunner() const { return *ModelRunner.get(); }
+
+protected:
+ virtual std::unique_ptr<MLInlineAdvice>
+ getMandatoryAdvice(CallBase &CB, OptimizationRemarkEmitter &ORE);
+
+ virtual std::unique_ptr<MLInlineAdvice>
+ getAdviceFromModel(CallBase &CB, OptimizationRemarkEmitter &ORE);
+
+ Module &M;
+ std::unique_ptr<MLModelRunner> ModelRunner;
+
+private:
+ int64_t getModuleIRSize() const;
+
+ std::unique_ptr<CallGraph> CG;
+
+ int64_t NodeCount = 0;
+ int64_t EdgeCount = 0;
+ std::map<const Function *, unsigned> FunctionLevels;
+ const int32_t InitialIRSize = 0;
+ int32_t CurrentIRSize = 0;
+
+ bool ForceStop = false;
+};
+
+/// InlineAdvice that tracks changes post inlining. For that reason, it only
+/// overrides the "successful inlining" extension points.
+class MLInlineAdvice : public InlineAdvice {
+public:
+ MLInlineAdvice(MLInlineAdvisor *Advisor, CallBase &CB,
+ OptimizationRemarkEmitter &ORE, bool Recommendation)
+ : InlineAdvice(Advisor, CB, ORE, Recommendation),
+ CallerIRSize(Advisor->isForcedToStop() ? 0
+ : Advisor->getIRSize(*Caller)),
+ CalleeIRSize(Advisor->isForcedToStop() ? 0
+ : Advisor->getIRSize(*Callee)),
+ CallerAndCalleeEdges(Advisor->isForcedToStop()
+ ? 0
+ : (Advisor->getLocalCalls(*Caller) +
+ Advisor->getLocalCalls(*Callee))) {}
+ virtual ~MLInlineAdvice() = default;
+
+ void recordInliningImpl() override;
+ void recordInliningWithCalleeDeletedImpl() override;
+ void recordUnsuccessfulInliningImpl(const InlineResult &Result) override;
+ void recordUnattemptedInliningImpl() override;
+
+ Function *getCaller() const { return Caller; }
+ Function *getCallee() const { return Callee; }
+
+ const int64_t CallerIRSize;
+ const int64_t CalleeIRSize;
+ const int64_t CallerAndCalleeEdges;
+
+private:
+ void reportContextForRemark(DiagnosticInfoOptimizationBase &OR);
+
+ MLInlineAdvisor *getAdvisor() const {
+ return static_cast<MLInlineAdvisor *>(Advisor);
+ };
+};
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_MLINLINEADVISOR_H \ No newline at end of file
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MLModelRunner.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MLModelRunner.h
new file mode 100644
index 000000000000..7cfa6efedf10
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MLModelRunner.h
@@ -0,0 +1,39 @@
+//===- MLModelRunner.h ---- ML model runner interface -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+
+#ifndef LLVM_ANALYSIS_MLMODELRUNNER_H
+#define LLVM_ANALYSIS_MLMODELRUNNER_H
+
+#include "llvm/Analysis/InlineModelFeatureMaps.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// MLModelRunner interface: abstraction of a mechanism for evaluating a
+/// tensorflow "saved model".
+class MLModelRunner {
+public:
+ // Disallows copy and assign.
+ MLModelRunner(const MLModelRunner &) = delete;
+ MLModelRunner &operator=(const MLModelRunner &) = delete;
+ virtual ~MLModelRunner() = default;
+
+ virtual bool run() = 0;
+ virtual void setFeature(FeatureIndex Index, int64_t Value) = 0;
+ virtual int64_t getFeature(int Index) const = 0;
+
+protected:
+ MLModelRunner(LLVMContext &Ctx) : Ctx(Ctx) {}
+
+ LLVMContext &Ctx;
+};
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_MLMODELRUNNER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h
index a89d76b9e5bd..c5428726995e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryBuiltins.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/TargetFolder.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/ValueHandle.h"
@@ -48,7 +47,6 @@ class LoadInst;
class PHINode;
class PointerType;
class SelectInst;
-class TargetLibraryInfo;
class Type;
class UndefValue;
class Value;
@@ -76,6 +74,14 @@ bool isMallocLikeFn(const Value *V,
bool LookThroughBitCast = false);
/// Tests if a value is a call or invoke to a library function that
+/// allocates uninitialized memory with alignment (such as aligned_alloc).
+bool isAlignedAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
+ bool LookThroughBitCast = false);
+bool isAlignedAllocLikeFn(
+ const Value *V, function_ref<const TargetLibraryInfo &(Function &)> GetTLI,
+ bool LookThroughBitCast = false);
+
+/// Tests if a value is a call or invoke to a library function that
/// allocates zero-filled memory (such as calloc).
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI,
bool LookThroughBitCast = false);
@@ -259,7 +265,7 @@ public:
// compute() should be used by external users.
SizeOffsetType visitAllocaInst(AllocaInst &I);
SizeOffsetType visitArgument(Argument &A);
- SizeOffsetType visitCallSite(CallSite CS);
+ SizeOffsetType visitCallBase(CallBase &CB);
SizeOffsetType visitConstantPointerNull(ConstantPointerNull&);
SizeOffsetType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetType visitExtractValueInst(ExtractValueInst &I);
@@ -329,7 +335,7 @@ public:
// The individual instruction visitors should be treated as private.
SizeOffsetEvalType visitAllocaInst(AllocaInst &I);
- SizeOffsetEvalType visitCallSite(CallSite CS);
+ SizeOffsetEvalType visitCallBase(CallBase &CB);
SizeOffsetEvalType visitExtractElementInst(ExtractElementInst &I);
SizeOffsetEvalType visitExtractValueInst(ExtractValueInst &I);
SizeOffsetEvalType visitGEPOperator(GEPOperator &GEP);
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
index e89e5690fad0..0777dc7d7862 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerSumType.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Metadata.h"
@@ -35,6 +34,7 @@
namespace llvm {
+class AAResults;
class AssumptionCache;
class DominatorTree;
class Function;
@@ -355,7 +355,7 @@ private:
ReverseDepMapType ReverseNonLocalDeps;
/// Current AA implementation, just a cache.
- AliasAnalysis &AA;
+ AAResults &AA;
AssumptionCache &AC;
const TargetLibraryInfo &TLI;
DominatorTree &DT;
@@ -365,7 +365,7 @@ private:
unsigned DefaultBlockScanLimit;
public:
- MemoryDependenceResults(AliasAnalysis &AA, AssumptionCache &AC,
+ MemoryDependenceResults(AAResults &AA, AssumptionCache &AC,
const TargetLibraryInfo &TLI, DominatorTree &DT,
PhiValues &PV, unsigned DefaultBlockScanLimit)
: AA(AA), AC(AC), TLI(TLI), DT(DT), PV(PV),
@@ -384,8 +384,7 @@ public:
///
/// See the class comment for more details. It is illegal to call this on
/// non-memory instructions.
- MemDepResult getDependency(Instruction *QueryInst,
- OrderedBasicBlock *OBB = nullptr);
+ MemDepResult getDependency(Instruction *QueryInst);
/// Perform a full dependency query for the specified call, returning the set
/// of blocks that the value is potentially live across.
@@ -451,14 +450,12 @@ public:
BasicBlock::iterator ScanIt,
BasicBlock *BB,
Instruction *QueryInst = nullptr,
- unsigned *Limit = nullptr,
- OrderedBasicBlock *OBB = nullptr);
+ unsigned *Limit = nullptr);
MemDepResult
getSimplePointerDependencyFrom(const MemoryLocation &MemLoc, bool isLoad,
BasicBlock::iterator ScanIt, BasicBlock *BB,
- Instruction *QueryInst, unsigned *Limit,
- OrderedBasicBlock *OBB);
+ Instruction *QueryInst, unsigned *Limit);
/// This analysis looks for other loads and stores with invariant.group
/// metadata and the same pointer operand. Returns Unknown if it does not
@@ -468,18 +465,6 @@ public:
/// with the same queried instruction.
MemDepResult getInvariantGroupPointerDependency(LoadInst *LI, BasicBlock *BB);
- /// Looks at a memory location for a load (specified by MemLocBase, Offs, and
- /// Size) and compares it against a load.
- ///
- /// If the specified load could be safely widened to a larger integer load
- /// that is 1) still efficient, 2) safe for the target, and 3) would provide
- /// the specified memory location value, then this function returns the size
- /// in bytes of the load width to use. If not, this returns zero.
- static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
- int64_t MemLocOffs,
- unsigned MemLocSize,
- const LoadInst *LI);
-
/// Release memory in caches.
void releaseMemory();
@@ -493,7 +478,8 @@ private:
BasicBlock *BB,
SmallVectorImpl<NonLocalDepResult> &Result,
DenseMap<BasicBlock *, Value *> &Visited,
- bool SkipFirstBlock = false);
+ bool SkipFirstBlock = false,
+ bool IsIncomplete = false);
MemDepResult GetNonLocalInfoForBlock(Instruction *QueryInst,
const MemoryLocation &Loc, bool isLoad,
BasicBlock *BB, NonLocalDepInfo *Cache,
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryLocation.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryLocation.h
index 7c26353e618b..d01ac7da85cd 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryLocation.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MemoryLocation.h
@@ -17,20 +17,25 @@
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/Support/TypeSize.h"
namespace llvm {
+class CallBase;
+class Instruction;
class LoadInst;
class StoreInst;
class MemTransferInst;
class MemIntrinsic;
+class AtomicCmpXchgInst;
class AtomicMemTransferInst;
class AtomicMemIntrinsic;
+class AtomicRMWInst;
class AnyMemTransferInst;
class AnyMemIntrinsic;
class TargetLibraryInfo;
+class VAArgInst;
// Represents the size of a MemoryLocation. Logically, it's an
// Optional<uint63_t> that also carries a bit to represent whether the integer
@@ -88,6 +93,11 @@ public:
: Value(Raw > MaxValue ? Unknown : Raw) {}
static LocationSize precise(uint64_t Value) { return LocationSize(Value); }
+ static LocationSize precise(TypeSize Value) {
+ if (Value.isScalable())
+ return unknown();
+ return precise(Value.getFixedSize());
+ }
static LocationSize upperBound(uint64_t Value) {
// You can't go lower than 0, so give a precise result.
@@ -97,6 +107,11 @@ public:
return unknown();
return LocationSize(Value | ImpreciseBit, Direct);
}
+ static LocationSize upperBound(TypeSize Value) {
+ if (Value.isScalable())
+ return unknown();
+ return upperBound(Value.getFixedSize());
+ }
constexpr static LocationSize unknown() {
return LocationSize(Unknown, Direct);
@@ -194,6 +209,8 @@ public:
/// member is null if that kind of information is unavailable).
AAMDNodes AATags;
+ void print(raw_ostream &OS) const { OS << *Ptr << " " << Size << "\n"; }
+
/// Return a location with information about the memory reference by the given
/// instruction.
static MemoryLocation get(const LoadInst *LI);
@@ -204,22 +221,7 @@ public:
static MemoryLocation get(const Instruction *Inst) {
return *MemoryLocation::getOrNone(Inst);
}
- static Optional<MemoryLocation> getOrNone(const Instruction *Inst) {
- switch (Inst->getOpcode()) {
- case Instruction::Load:
- return get(cast<LoadInst>(Inst));
- case Instruction::Store:
- return get(cast<StoreInst>(Inst));
- case Instruction::VAArg:
- return get(cast<VAArgInst>(Inst));
- case Instruction::AtomicCmpXchg:
- return get(cast<AtomicCmpXchgInst>(Inst));
- case Instruction::AtomicRMW:
- return get(cast<AtomicRMWInst>(Inst));
- default:
- return None;
- }
- }
+ static Optional<MemoryLocation> getOrNone(const Instruction *Inst);
/// Return a location representing the source of a memory transfer.
static MemoryLocation getForSource(const MemTransferInst *MTI);
@@ -240,6 +242,12 @@ public:
return getForArgument(Call, ArgIdx, &TLI);
}
+ // Return the exact size if the exact size is known at compiletime,
+ // otherwise return MemoryLocation::UnknownSize.
+ static uint64_t getSizeOrUnknown(const TypeSize &T) {
+ return T.isScalable() ? UnknownSize : T.getFixedSize();
+ }
+
explicit MemoryLocation(const Value *Ptr = nullptr,
LocationSize Size = LocationSize::unknown(),
const AAMDNodes &AATags = AAMDNodes())
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSA.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSA.h
index 9b393c9cdaa3..5ce2b3fd047f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSA.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSA.h
@@ -499,14 +499,11 @@ public:
using const_block_iterator = BasicBlock *const *;
block_iterator block_begin() {
- auto *Ref = reinterpret_cast<Use::UserRef *>(op_begin() + ReservedSpace);
- return reinterpret_cast<block_iterator>(Ref + 1);
+ return reinterpret_cast<block_iterator>(op_begin() + ReservedSpace);
}
const_block_iterator block_begin() const {
- const auto *Ref =
- reinterpret_cast<const Use::UserRef *>(op_begin() + ReservedSpace);
- return reinterpret_cast<const_block_iterator>(Ref + 1);
+ return reinterpret_cast<const_block_iterator>(op_begin() + ReservedSpace);
}
block_iterator block_end() { return block_begin() + getNumOperands(); }
@@ -726,6 +723,8 @@ public:
return cast_or_null<MemoryPhi>(ValueToMemoryAccess.lookup(cast<Value>(BB)));
}
+ DominatorTree &getDomTree() const { return *DT; }
+
void dump() const;
void print(raw_ostream &) const;
@@ -1182,9 +1181,9 @@ class upward_defs_iterator
using BaseT = upward_defs_iterator::iterator_facade_base;
public:
- upward_defs_iterator(const MemoryAccessPair &Info)
+ upward_defs_iterator(const MemoryAccessPair &Info, DominatorTree *DT)
: DefIterator(Info.first), Location(Info.second),
- OriginalAccess(Info.first) {
+ OriginalAccess(Info.first), DT(DT) {
CurrentPair.first = nullptr;
WalkingPhi = Info.first && isa<MemoryPhi>(Info.first);
@@ -1223,12 +1222,16 @@ private:
const_cast<Value *>(Location.Ptr),
OriginalAccess->getBlock()->getModule()->getDataLayout(), nullptr);
if (!Translator.PHITranslateValue(OriginalAccess->getBlock(),
- DefIterator.getPhiArgBlock(), nullptr,
- false))
+ DefIterator.getPhiArgBlock(), DT,
+ false)) {
if (Translator.getAddr() != Location.Ptr) {
CurrentPair.second = Location.getWithNewPtr(Translator.getAddr());
return;
}
+ } else {
+ CurrentPair.second = Location.getWithNewSize(LocationSize::unknown());
+ return;
+ }
}
CurrentPair.second = Location;
}
@@ -1238,17 +1241,19 @@ private:
MemoryLocation Location;
MemoryAccess *OriginalAccess = nullptr;
bool WalkingPhi = false;
+ DominatorTree *DT = nullptr;
};
-inline upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair) {
- return upward_defs_iterator(Pair);
+inline upward_defs_iterator upward_defs_begin(const MemoryAccessPair &Pair,
+ DominatorTree &DT) {
+ return upward_defs_iterator(Pair, &DT);
}
inline upward_defs_iterator upward_defs_end() { return upward_defs_iterator(); }
inline iterator_range<upward_defs_iterator>
-upward_defs(const MemoryAccessPair &Pair) {
- return make_range(upward_defs_begin(Pair), upward_defs_end());
+upward_defs(const MemoryAccessPair &Pair, DominatorTree &DT) {
+ return make_range(upward_defs_begin(Pair, DT), upward_defs_end());
}
/// Walks the defining accesses of MemoryDefs. Stops after we hit something that
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSAUpdater.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSAUpdater.h
index 1d34663721e3..20588ef083c5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSAUpdater.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MemorySSAUpdater.h
@@ -35,31 +35,19 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/MemorySSA.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CFGDiff.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/OperandTraits.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Use.h"
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/IR/ValueMap.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/CFGDiff.h"
+#include <utility>
namespace llvm {
-class Function;
+class BasicBlock;
+class BranchInst;
+class DominatorTree;
class Instruction;
-class MemoryAccess;
-class LLVMContext;
-class raw_ostream;
+class LoopBlocksRPO;
using ValueToValueMapTy = ValueMap<const Value *, WeakTrackingVH>;
using PhiToDefMap = SmallDenseMap<MemoryPhi *, MemoryAccess *>;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
index 1572a49e3384..eb48ec3af526 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
@@ -25,6 +25,7 @@ class BlockFrequencyInfo;
class Function;
class Module;
class ProfileSummaryInfo;
+class StackSafetyInfo;
/// Direct function to compute a \c ModuleSummaryIndex from a given module.
///
@@ -35,7 +36,9 @@ class ProfileSummaryInfo;
ModuleSummaryIndex buildModuleSummaryIndex(
const Module &M,
std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
- ProfileSummaryInfo *PSI);
+ ProfileSummaryInfo *PSI,
+ std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback =
+ [](const Function &F) -> const StackSafetyInfo * { return nullptr; });
/// Analysis pass to provide the ModuleSummaryIndex object.
class ModuleSummaryIndexAnalysis
@@ -75,6 +78,27 @@ public:
//
ModulePass *createModuleSummaryIndexWrapperPass();
+/// Legacy wrapper pass to provide the ModuleSummaryIndex object.
+class ImmutableModuleSummaryIndexWrapperPass : public ImmutablePass {
+ const ModuleSummaryIndex *Index;
+
+public:
+ static char ID;
+
+ ImmutableModuleSummaryIndexWrapperPass(
+ const ModuleSummaryIndex *Index = nullptr);
+ const ModuleSummaryIndex *getIndex() const { return Index; }
+ void getAnalysisUsage(AnalysisUsage &AU) const override;
+};
+
+//===--------------------------------------------------------------------===//
+//
+// ImmutableModuleSummaryIndexWrapperPass - This pass wrap provided
+// ModuleSummaryIndex object for the module, to be used by other passes.
+//
+ImmutablePass *
+createImmutableModuleSummaryIndexWrapperPass(const ModuleSummaryIndex *Index);
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/MustExecute.h b/contrib/llvm-project/llvm/include/llvm/Analysis/MustExecute.h
index d88cdf40ed87..a3b7bee97808 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/MustExecute.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/MustExecute.h
@@ -24,12 +24,9 @@
#define LLVM_ANALYSIS_MUSTEXECUTE_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/InstructionPrecedenceTracking.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Instruction.h"
namespace llvm {
@@ -37,15 +34,17 @@ namespace {
template <typename T> using GetterTy = std::function<T *(const Function &F)>;
}
-class Instruction;
+class BasicBlock;
class DominatorTree;
-class PostDominatorTree;
+class Instruction;
class Loop;
+class LoopInfo;
+class PostDominatorTree;
/// Captures loop safety information.
/// It keep information for loop blocks may throw exception or otherwise
-/// exit abnormaly on any iteration of the loop which might actually execute
-/// at runtime. The primary way to consume this infromation is via
+/// exit abnormally on any iteration of the loop which might actually execute
+/// at runtime. The primary way to consume this information is via
/// isGuaranteedToExecute below, but some callers bailout or fallback to
/// alternate reasoning if a loop contains any implicit control flow.
/// NOTE: LoopSafetyInfo contains cached information regarding loops and their
@@ -112,19 +111,15 @@ class SimpleLoopSafetyInfo: public LoopSafetyInfo {
bool HeaderMayThrow = false; // Same as previous, but specific to loop header
public:
- virtual bool blockMayThrow(const BasicBlock *BB) const;
+ bool blockMayThrow(const BasicBlock *BB) const override;
- virtual bool anyBlockMayThrow() const;
-
- virtual void computeLoopSafetyInfo(const Loop *CurLoop);
-
- virtual bool isGuaranteedToExecute(const Instruction &Inst,
- const DominatorTree *DT,
- const Loop *CurLoop) const;
+ bool anyBlockMayThrow() const override;
- SimpleLoopSafetyInfo() : LoopSafetyInfo() {};
+ void computeLoopSafetyInfo(const Loop *CurLoop) override;
- virtual ~SimpleLoopSafetyInfo() {};
+ bool isGuaranteedToExecute(const Instruction &Inst,
+ const DominatorTree *DT,
+ const Loop *CurLoop) const override;
};
/// This implementation of LoopSafetyInfo use ImplicitControlFlowTracking to
@@ -141,15 +136,15 @@ class ICFLoopSafetyInfo: public LoopSafetyInfo {
mutable MemoryWriteTracking MW;
public:
- virtual bool blockMayThrow(const BasicBlock *BB) const;
+ bool blockMayThrow(const BasicBlock *BB) const override;
- virtual bool anyBlockMayThrow() const;
+ bool anyBlockMayThrow() const override;
- virtual void computeLoopSafetyInfo(const Loop *CurLoop);
+ void computeLoopSafetyInfo(const Loop *CurLoop) override;
- virtual bool isGuaranteedToExecute(const Instruction &Inst,
- const DominatorTree *DT,
- const Loop *CurLoop) const;
+ bool isGuaranteedToExecute(const Instruction &Inst,
+ const DominatorTree *DT,
+ const Loop *CurLoop) const override;
/// Returns true if we could not execute a memory-modifying instruction before
/// we enter \p BB under assumption that \p CurLoop is entered.
@@ -170,14 +165,18 @@ public:
/// from its block. It will make all cache updates to keep it correct after
/// this removal.
void removeInstruction(const Instruction *Inst);
-
- ICFLoopSafetyInfo(DominatorTree *DT) : LoopSafetyInfo(), ICF(DT), MW(DT) {};
-
- virtual ~ICFLoopSafetyInfo() {};
};
+bool mayContainIrreducibleControl(const Function &F, const LoopInfo *LI);
+
struct MustBeExecutedContextExplorer;
+/// Enum that allows us to spell out the direction.
+enum class ExplorationDirection {
+ BACKWARD = 0,
+ FORWARD = 1,
+};
+
/// Must be executed iterators visit stretches of instructions that are
/// guaranteed to be executed together, potentially with other instruction
/// executed in-between.
@@ -282,16 +281,18 @@ struct MustBeExecutedIterator {
MustBeExecutedIterator(const MustBeExecutedIterator &Other)
: Visited(Other.Visited), Explorer(Other.Explorer),
- CurInst(Other.CurInst) {}
+ CurInst(Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
MustBeExecutedIterator(MustBeExecutedIterator &&Other)
: Visited(std::move(Other.Visited)), Explorer(Other.Explorer),
- CurInst(Other.CurInst) {}
+ CurInst(Other.CurInst), Head(Other.Head), Tail(Other.Tail) {}
MustBeExecutedIterator &operator=(MustBeExecutedIterator &&Other) {
if (this != &Other) {
std::swap(Visited, Other.Visited);
std::swap(CurInst, Other.CurInst);
+ std::swap(Head, Other.Head);
+ std::swap(Tail, Other.Tail);
}
return *this;
}
@@ -315,7 +316,7 @@ struct MustBeExecutedIterator {
/// Equality and inequality operators. Note that we ignore the history here.
///{
bool operator==(const MustBeExecutedIterator &Other) const {
- return CurInst == Other.CurInst;
+ return CurInst == Other.CurInst && Head == Other.Head && Tail == Other.Tail;
}
bool operator!=(const MustBeExecutedIterator &Other) const {
@@ -328,10 +329,14 @@ struct MustBeExecutedIterator {
const Instruction *getCurrentInst() const { return CurInst; }
/// Return true if \p I was encountered by this iterator already.
- bool count(const Instruction *I) const { return Visited.count(I); }
+ bool count(const Instruction *I) const {
+ return Visited.count({I, ExplorationDirection::FORWARD}) ||
+ Visited.count({I, ExplorationDirection::BACKWARD});
+ }
private:
- using VisitedSetTy = DenseSet<const Instruction *>;
+ using VisitedSetTy =
+ DenseSet<PointerIntPair<const Instruction *, 1, ExplorationDirection>>;
/// Private constructors.
MustBeExecutedIterator(ExplorerTy &Explorer, const Instruction *I);
@@ -339,6 +344,9 @@ private:
/// Reset the iterator to its initial state pointing at \p I.
void reset(const Instruction *I);
+ /// Reset the iterator to point at \p I, keep cached state.
+ void resetInstruction(const Instruction *I);
+
/// Try to advance one of the underlying positions (Head or Tail).
///
/// \return The next instruction in the must be executed context, or nullptr
@@ -357,6 +365,11 @@ private:
/// initially the program point itself.
const Instruction *CurInst;
+ /// Two positions that mark the program points where this iterator will look
+ /// for the next instruction. Note that the current instruction is either the
+ /// one pointed to by Head, Tail, or both.
+ const Instruction *Head, *Tail;
+
friend struct MustBeExecutedContextExplorer;
};
@@ -379,19 +392,24 @@ struct MustBeExecutedContextExplorer {
/// \param ExploreInterBlock Flag to indicate if instructions in blocks
/// other than the parent of PP should be
/// explored.
+ /// \param ExploreCFGForward Flag to indicate if instructions located after
+ /// PP in the CFG, e.g., post-dominating PP,
+ /// should be explored.
+ /// \param ExploreCFGBackward Flag to indicate if instructions located
+ /// before PP in the CFG, e.g., dominating PP,
+ /// should be explored.
MustBeExecutedContextExplorer(
- bool ExploreInterBlock,
+ bool ExploreInterBlock, bool ExploreCFGForward, bool ExploreCFGBackward,
GetterTy<const LoopInfo> LIGetter =
[](const Function &) { return nullptr; },
+ GetterTy<const DominatorTree> DTGetter =
+ [](const Function &) { return nullptr; },
GetterTy<const PostDominatorTree> PDTGetter =
[](const Function &) { return nullptr; })
- : ExploreInterBlock(ExploreInterBlock), LIGetter(LIGetter),
- PDTGetter(PDTGetter), EndIterator(*this, nullptr) {}
-
- /// Clean up the dynamically allocated iterators.
- ~MustBeExecutedContextExplorer() {
- DeleteContainerSeconds(InstructionIteratorMap);
- }
+ : ExploreInterBlock(ExploreInterBlock),
+ ExploreCFGForward(ExploreCFGForward),
+ ExploreCFGBackward(ExploreCFGBackward), LIGetter(LIGetter),
+ DTGetter(DTGetter), PDTGetter(PDTGetter), EndIterator(*this, nullptr) {}
/// Iterator-based interface. \see MustBeExecutedIterator.
///{
@@ -400,15 +418,15 @@ struct MustBeExecutedContextExplorer {
/// Return an iterator to explore the context around \p PP.
iterator &begin(const Instruction *PP) {
- auto *&It = InstructionIteratorMap[PP];
+ auto &It = InstructionIteratorMap[PP];
if (!It)
- It = new iterator(*this, PP);
+ It.reset(new iterator(*this, PP));
return *It;
}
/// Return an iterator to explore the cached context around \p PP.
const_iterator &begin(const Instruction *PP) const {
- return *InstructionIteratorMap.lookup(PP);
+ return *InstructionIteratorMap.find(PP)->second;
}
/// Return an universal end iterator.
@@ -431,6 +449,18 @@ struct MustBeExecutedContextExplorer {
}
///}
+ /// Check \p Pred on all instructions in the context.
+ ///
+ /// This method will evaluate \p Pred and return
+ /// true if \p Pred holds in every instruction.
+ bool checkForAllContext(const Instruction *PP,
+ function_ref<bool(const Instruction *)> Pred) {
+ for (auto EIt = begin(PP), EEnd = end(PP); EIt != EEnd; ++EIt)
+ if (!Pred(*EIt))
+ return false;
+ return true;
+ }
+
/// Helper to look for \p I in the context of \p PP.
///
/// The context is expanded until \p I was found or no more expansion is
@@ -464,14 +494,28 @@ struct MustBeExecutedContextExplorer {
const Instruction *
getMustBeExecutedNextInstruction(MustBeExecutedIterator &It,
const Instruction *PP);
+ /// Return the previous instr. that is guaranteed to be executed before \p PP.
+ ///
+ /// \param It The iterator that is used to traverse the must be
+ /// executed context.
+ /// \param PP The program point for which the previous instr.
+ /// that is guaranteed to execute is determined.
+ const Instruction *
+ getMustBeExecutedPrevInstruction(MustBeExecutedIterator &It,
+ const Instruction *PP);
/// Find the next join point from \p InitBB in forward direction.
const BasicBlock *findForwardJoinPoint(const BasicBlock *InitBB);
+ /// Find the next join point from \p InitBB in backward direction.
+ const BasicBlock *findBackwardJoinPoint(const BasicBlock *InitBB);
+
/// Parameter that limit the performed exploration. See the constructor for
/// their meaning.
///{
const bool ExploreInterBlock;
+ const bool ExploreCFGForward;
+ const bool ExploreCFGBackward;
///}
private:
@@ -479,6 +523,7 @@ private:
/// PostDominatorTree.
///{
GetterTy<const LoopInfo> LIGetter;
+ GetterTy<const DominatorTree> DTGetter;
GetterTy<const PostDominatorTree> PDTGetter;
///}
@@ -489,7 +534,7 @@ private:
DenseMap<const Function*, Optional<bool>> IrreducibleControlMap;
/// Map from instructions to associated must be executed iterators.
- DenseMap<const Instruction *, MustBeExecutedIterator *>
+ DenseMap<const Instruction *, std::unique_ptr<MustBeExecutedIterator>>
InstructionIteratorMap;
/// A unique end iterator.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
index 522abd756c9f..cad1c52f7f87 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCAnalysisUtils.h
@@ -23,22 +23,12 @@
#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/ObjCARCInstKind.h"
-#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueHandle.h"
-#include "llvm/Pass.h"
-
-namespace llvm {
-class raw_ostream;
-}
namespace llvm {
namespace objcarc {
@@ -156,9 +146,7 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op) {
return false;
// Special arguments can not be a valid retainable object pointer.
if (const Argument *Arg = dyn_cast<Argument>(Op))
- if (Arg->hasByValAttr() ||
- Arg->hasInAllocaAttr() ||
- Arg->hasNestAttr() ||
+ if (Arg->hasPassPointeeByValueAttr() || Arg->hasNestAttr() ||
Arg->hasStructRetAttr())
return false;
// Only consider values with pointer types.
@@ -195,13 +183,12 @@ inline bool IsPotentialRetainableObjPtr(const Value *Op,
/// Helper for GetARCInstKind. Determines what kind of construct CS
/// is.
-inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
- for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
- I != E; ++I)
+inline ARCInstKind GetCallSiteClass(const CallBase &CB) {
+ for (auto I = CB.arg_begin(), E = CB.arg_end(); I != E; ++I)
if (IsPotentialRetainableObjPtr(*I))
- return CS.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser;
+ return CB.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser;
- return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call;
+ return CB.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call;
}
/// Return true if this value refers to a distinct and identifiable
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h
index dc6093a7b86c..84565b9315c7 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h
@@ -9,8 +9,6 @@
#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
#define LLVM_ANALYSIS_OBJCARCINSTKIND_H
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Instructions.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h b/contrib/llvm-project/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
index 7b8404404ce7..ab97d5b8504e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/OptimizationRemarkEmitter.h
@@ -17,15 +17,11 @@
#include "llvm/ADT/Optional.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
-class DebugLoc;
-class Loop;
-class Pass;
-class Twine;
+class Function;
class Value;
/// The optimization diagnostic interface.
@@ -77,7 +73,7 @@ public:
// remarks enabled. We can't currently check whether remarks are requested
// for the calling pass since that requires actually building the remark.
- if (F->getContext().getRemarkStreamer() ||
+ if (F->getContext().getLLVMRemarkStreamer() ||
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled()) {
auto R = RemarkBuilder();
emit((DiagnosticInfoOptimizationBase &)R);
@@ -92,7 +88,7 @@ public:
/// provide more context so that non-trivial false positives can be quickly
/// detected by the user.
bool allowExtraAnalysis(StringRef PassName) const {
- return (F->getContext().getRemarkStreamer() ||
+ return (F->getContext().getLLVMRemarkStreamer() ||
F->getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(PassName));
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedBasicBlock.h b/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedBasicBlock.h
deleted file mode 100644
index ae64c0189f5e..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedBasicBlock.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===- llvm/Analysis/OrderedBasicBlock.h --------------------- -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the OrderedBasicBlock class. OrderedBasicBlock maintains
-// an interface where clients can query if one instruction comes before another
-// in a BasicBlock. Since BasicBlock currently lacks a reliable way to query
-// relative position between instructions one can use OrderedBasicBlock to do
-// such queries. OrderedBasicBlock is lazily built on a source BasicBlock and
-// maintains an internal Instruction -> Position map. A OrderedBasicBlock
-// instance should be discarded whenever the source BasicBlock changes.
-//
-// It's currently used by the CaptureTracker in order to find relative
-// positions of a pair of instructions inside a BasicBlock.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_ORDEREDBASICBLOCK_H
-#define LLVM_ANALYSIS_ORDEREDBASICBLOCK_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/BasicBlock.h"
-
-namespace llvm {
-
-class Instruction;
-class BasicBlock;
-
-class OrderedBasicBlock {
-private:
- /// Map a instruction to its position in a BasicBlock.
- SmallDenseMap<const Instruction *, unsigned, 32> NumberedInsts;
-
- /// Keep track of last instruction inserted into \p NumberedInsts.
- /// It speeds up queries for uncached instructions by providing a start point
- /// for new queries in OrderedBasicBlock::comesBefore.
- BasicBlock::const_iterator LastInstFound;
-
- /// The position/number to tag the next instruction to be found.
- unsigned NextInstPos;
-
- /// The source BasicBlock to map.
- const BasicBlock *BB;
-
- /// Given no cached results, find if \p A comes before \p B in \p BB.
- /// Cache and number out instruction while walking \p BB.
- bool comesBefore(const Instruction *A, const Instruction *B);
-
-public:
- OrderedBasicBlock(const BasicBlock *BasicB);
-
- /// Find out whether \p A dominates \p B, meaning whether \p A
- /// comes before \p B in \p BB. This is a simplification that considers
- /// cached instruction positions and ignores other basic blocks, being
- /// only relevant to compare relative instructions positions inside \p BB.
- /// Returns false for A == B.
- bool dominates(const Instruction *A, const Instruction *B);
-
- /// Remove \p from the ordering, if it is present.
- void eraseInstruction(const Instruction *I);
-
- /// Replace \p Old with \p New in the ordering. \p New is assigned the
- /// numbering of \p Old, so it must be inserted at the same position in the
- /// IR.
- void replaceInstruction(const Instruction *Old, const Instruction *New);
-};
-
-} // End llvm namespace
-
-#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedInstructions.h b/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedInstructions.h
deleted file mode 100644
index 967b146b52de..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/OrderedInstructions.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//===- llvm/Transforms/Utils/OrderedInstructions.h -------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines an efficient way to check for dominance relation between 2
-// instructions.
-//
-// This interface dispatches to appropriate dominance check given 2
-// instructions, i.e. in case the instructions are in the same basic block,
-// OrderedBasicBlock (with instruction numbering and caching) are used.
-// Otherwise, dominator tree is used.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
-#define LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Analysis/OrderedBasicBlock.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Operator.h"
-
-namespace llvm {
-
-class OrderedInstructions {
- /// Used to check dominance for instructions in same basic block.
- mutable DenseMap<const BasicBlock *, std::unique_ptr<OrderedBasicBlock>>
- OBBMap;
-
- /// The dominator tree of the parent function.
- DominatorTree *DT;
-
- /// Return true if the first instruction comes before the second in the
- /// same basic block. It will create an ordered basic block, if it does
- /// not yet exist in OBBMap.
- bool localDominates(const Instruction *, const Instruction *) const;
-
-public:
- /// Constructor.
- OrderedInstructions(DominatorTree *DT) : DT(DT) {}
-
- /// Return true if first instruction dominates the second.
- bool dominates(const Instruction *, const Instruction *) const;
-
- /// Return true if the first instruction comes before the second in the
- /// dominator tree DFS traversal if they are in different basic blocks,
- /// or if the first instruction comes before the second in the same basic
- /// block.
- bool dfsBefore(const Instruction *, const Instruction *) const;
-
- /// Invalidate the OrderedBasicBlock cache when its basic block changes.
- /// i.e. If an instruction is deleted or added to the basic block, the user
- /// should call this function to invalidate the OrderedBasicBlock cache for
- /// this basic block.
- void invalidateBlock(const BasicBlock *BB) { OBBMap.erase(BB); }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_ANALYSIS_ORDEREDINSTRUCTIONS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/Passes.h b/contrib/llvm-project/llvm/include/llvm/Analysis/Passes.h
index 8562519fa7b1..afca4d057800 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/Passes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/Passes.h
@@ -17,10 +17,7 @@
namespace llvm {
class FunctionPass;
class ImmutablePass;
- class LoopPass;
class ModulePass;
- class Pass;
- class PassInfo;
//===--------------------------------------------------------------------===//
//
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/PhiValues.h b/contrib/llvm-project/llvm/include/llvm/Analysis/PhiValues.h
index ee6eec85f198..ea879d727282 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/PhiValues.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/PhiValues.h
@@ -29,7 +29,6 @@
namespace llvm {
-class Use;
class Value;
class PHINode;
class Function;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/PostDominators.h b/contrib/llvm-project/llvm/include/llvm/Analysis/PostDominators.h
index 801eb3d59673..296110d8d03b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/PostDominators.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/PostDominators.h
@@ -88,9 +88,7 @@ struct PostDominatorTreeWrapperPass : public FunctionPass {
AU.setPreservesAll();
}
- void releaseMemory() override {
- DT.releaseMemory();
- }
+ void releaseMemory() override { DT.reset(); }
void print(raw_ostream &OS, const Module*) const override;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ProfileSummaryInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
index 6693e40ccf22..a1fea9fefc9a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ProfileSummaryInfo.h
@@ -14,22 +14,19 @@
#ifndef LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
#define LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instructions.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfileSummary.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
#include <memory>
namespace llvm {
class BasicBlock;
class BlockFrequencyInfo;
-class CallSite;
+class CallBase;
+class Function;
class ProfileSummary;
+
/// Analysis providing profile information.
///
/// This is an immutable analysis pass that provides ability to query global
@@ -44,7 +41,6 @@ class ProfileSummaryInfo {
private:
Module &M;
std::unique_ptr<ProfileSummary> Summary;
- bool computeSummary();
void computeThresholds();
// Count thresholds to answer isHotCount and isColdCount queries.
Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
@@ -57,33 +53,35 @@ private:
// percentile is above a large threshold.
Optional<bool> HasLargeWorkingSetSize;
// Compute the threshold for a given cutoff.
- Optional<uint64_t> computeThreshold(int PercentileCutoff);
+ Optional<uint64_t> computeThreshold(int PercentileCutoff) const;
// The map that caches the threshold values. The keys are the percentile
// cutoff values and the values are the corresponding threshold values.
- DenseMap<int, uint64_t> ThresholdCache;
+ mutable DenseMap<int, uint64_t> ThresholdCache;
public:
- ProfileSummaryInfo(Module &M) : M(M) {}
- ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
- : M(Arg.M), Summary(std::move(Arg.Summary)) {}
+ ProfileSummaryInfo(Module &M) : M(M) { refresh(); }
+ ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;
+
+ /// If no summary is present, attempt to refresh.
+ void refresh();
/// Returns true if profile summary is available.
- bool hasProfileSummary() { return computeSummary(); }
+ bool hasProfileSummary() const { return Summary != nullptr; }
/// Returns true if module \c M has sample profile.
- bool hasSampleProfile() {
+ bool hasSampleProfile() const {
return hasProfileSummary() &&
Summary->getKind() == ProfileSummary::PSK_Sample;
}
/// Returns true if module \c M has instrumentation profile.
- bool hasInstrumentationProfile() {
+ bool hasInstrumentationProfile() const {
return hasProfileSummary() &&
Summary->getKind() == ProfileSummary::PSK_Instr;
}
/// Returns true if module \c M has context sensitive instrumentation profile.
- bool hasCSInstrumentationProfile() {
+ bool hasCSInstrumentationProfile() const {
return hasProfileSummary() &&
Summary->getKind() == ProfileSummary::PSK_CSInstr;
}
@@ -100,59 +98,88 @@ public:
}
/// Returns the profile count for \p CallInst.
- Optional<uint64_t> getProfileCount(const Instruction *CallInst,
+ Optional<uint64_t> getProfileCount(const CallBase &CallInst,
BlockFrequencyInfo *BFI,
- bool AllowSynthetic = false);
+ bool AllowSynthetic = false) const;
+ /// Returns true if module \c M has partial-profile sample profile.
+ bool hasPartialSampleProfile() const;
/// Returns true if the working set size of the code is considered huge.
- bool hasHugeWorkingSetSize();
+ bool hasHugeWorkingSetSize() const;
/// Returns true if the working set size of the code is considered large.
- bool hasLargeWorkingSetSize();
+ bool hasLargeWorkingSetSize() const;
/// Returns true if \p F has hot function entry.
- bool isFunctionEntryHot(const Function *F);
+ bool isFunctionEntryHot(const Function *F) const;
/// Returns true if \p F contains hot code.
- bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
+ bool isFunctionHotInCallGraph(const Function *F,
+ BlockFrequencyInfo &BFI) const;
/// Returns true if \p F has cold function entry.
- bool isFunctionEntryCold(const Function *F);
+ bool isFunctionEntryCold(const Function *F) const;
/// Returns true if \p F contains only cold code.
- bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
+ bool isFunctionColdInCallGraph(const Function *F,
+ BlockFrequencyInfo &BFI) const;
+ /// Returns true if the hotness of \p F is unknown.
+ bool isFunctionHotnessUnknown(const Function &F) const;
/// Returns true if \p F contains hot code with regard to a given hot
/// percentile cutoff value.
bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,
const Function *F,
- BlockFrequencyInfo &BFI);
+ BlockFrequencyInfo &BFI) const;
+ /// Returns true if \p F contains cold code with regard to a given cold
+ /// percentile cutoff value.
+ bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,
+ const Function *F,
+ BlockFrequencyInfo &BFI) const;
/// Returns true if count \p C is considered hot.
- bool isHotCount(uint64_t C);
+ bool isHotCount(uint64_t C) const;
/// Returns true if count \p C is considered cold.
- bool isColdCount(uint64_t C);
+ bool isColdCount(uint64_t C) const;
/// Returns true if count \p C is considered hot with regard to a given
/// hot percentile cutoff value.
- bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C);
+ bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const;
+ /// Returns true if count \p C is considered cold with regard to a given
+ /// cold percentile cutoff value.
+ bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
/// Returns true if BasicBlock \p BB is considered hot.
- bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
+ bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
/// Returns true if BasicBlock \p BB is considered cold.
- bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI);
+ bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
/// Returns true if BasicBlock \p BB is considered hot with regard to a given
/// hot percentile cutoff value.
- bool isHotBlockNthPercentile(int PercentileCutoff,
- const BasicBlock *BB, BlockFrequencyInfo *BFI);
- /// Returns true if CallSite \p CS is considered hot.
- bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
- /// Returns true if Callsite \p CS is considered cold.
- bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
+ bool isHotBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
+ BlockFrequencyInfo *BFI) const;
+ /// Returns true if BasicBlock \p BB is considered cold with regard to a given
+ /// cold percentile cutoff value.
+ bool isColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
+ BlockFrequencyInfo *BFI) const;
+ /// Returns true if the call site \p CB is considered hot.
+ bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
+ /// Returns true if call site \p CB is considered cold.
+ bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
/// Returns HotCountThreshold if set. Recompute HotCountThreshold
/// if not set.
- uint64_t getOrCompHotCountThreshold();
+ uint64_t getOrCompHotCountThreshold() const;
/// Returns ColdCountThreshold if set. Recompute HotCountThreshold
/// if not set.
- uint64_t getOrCompColdCountThreshold();
+ uint64_t getOrCompColdCountThreshold() const;
/// Returns HotCountThreshold if set.
- uint64_t getHotCountThreshold() {
+ uint64_t getHotCountThreshold() const {
return HotCountThreshold ? HotCountThreshold.getValue() : 0;
}
/// Returns ColdCountThreshold if set.
- uint64_t getColdCountThreshold() {
+ uint64_t getColdCountThreshold() const {
return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
}
+
+ private:
+ template <bool isHot>
+ bool isFunctionHotOrColdInCallGraphNthPercentile(
+ int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const;
+ template <bool isHot>
+ bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
+ template <bool isHot>
+ bool isHotOrColdBlockNthPercentile(int PercentileCutoff,
+ const BasicBlock *BB,
+ BlockFrequencyInfo *BFI) const;
};
/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/PtrUseVisitor.h b/contrib/llvm-project/llvm/include/llvm/Analysis/PtrUseVisitor.h
index 05bca2226742..78e9251da627 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/PtrUseVisitor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/PtrUseVisitor.h
@@ -26,7 +26,6 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/InstVisitor.h"
@@ -295,9 +294,9 @@ protected:
// Generically, arguments to calls and invokes escape the pointer to some
// other function. Mark that.
- void visitCallSite(CallSite CS) {
- PI.setEscaped(CS.getInstruction());
- Base::visitCallSite(CS);
+ void visitCallBase(CallBase &CB) {
+ PI.setEscaped(&CB);
+ Base::visitCallBase(CB);
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfo.h
index 8bcc3e851200..b0336c559774 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfo.h
@@ -574,10 +574,9 @@ public:
template <bool IsConst>
class block_iterator_wrapper
: public df_iterator<
- typename std::conditional<IsConst, const BlockT, BlockT>::type *> {
+ std::conditional_t<IsConst, const BlockT, BlockT> *> {
using super =
- df_iterator<
- typename std::conditional<IsConst, const BlockT, BlockT>::type *>;
+ df_iterator<std::conditional_t<IsConst, const BlockT, BlockT> *>;
public:
using Self = block_iterator_wrapper<IsConst>;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfoImpl.h b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfoImpl.h
index 6b5936680c37..8d9ec646f519 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfoImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionInfoImpl.h
@@ -236,7 +236,7 @@ std::string RegionBase<Tr>::getNameStr() const {
getEntry()->printAsOperand(OS, false);
} else
- entryName = getEntry()->getName();
+ entryName = std::string(getEntry()->getName());
if (getExit()) {
if (getExit()->getName().empty()) {
@@ -244,7 +244,7 @@ std::string RegionBase<Tr>::getNameStr() const {
getExit()->printAsOperand(OS, false);
} else
- exitName = getExit()->getName();
+ exitName = std::string(getExit()->getName());
} else
exitName = "<Function Return>";
@@ -724,7 +724,7 @@ void RegionInfoBase<Tr>::findRegionsWithEntry(BlockT *entry,
template <class Tr>
void RegionInfoBase<Tr>::scanForRegions(FuncT &F, BBtoBBMap *ShortCut) {
- using FuncPtrT = typename std::add_pointer<FuncT>::type;
+ using FuncPtrT = std::add_pointer_t<FuncT>;
BlockT *entry = GraphTraits<FuncPtrT>::getEntryNode(&F);
DomTreeNodeT *N = DT->getNode(entry);
@@ -912,7 +912,7 @@ RegionInfoBase<Tr>::getCommonRegion(SmallVectorImpl<BlockT *> &BBs) const {
template <class Tr>
void RegionInfoBase<Tr>::calculate(FuncT &F) {
- using FuncPtrT = typename std::add_pointer<FuncT>::type;
+ using FuncPtrT = std::add_pointer_t<FuncT>;
// ShortCut a function where for every BB the exit of the largest region
// starting with BB is stored. These regions can be threated as single BBS.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionPass.h b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionPass.h
index 5b1864a37629..995c5dca3de3 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/RegionPass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/RegionPass.h
@@ -16,15 +16,13 @@
#define LLVM_ANALYSIS_REGIONPASS_H
#include "llvm/Analysis/RegionInfo.h"
-#include "llvm/IR/Function.h"
#include "llvm/IR/LegacyPassManagers.h"
#include "llvm/Pass.h"
#include <deque>
namespace llvm {
-
-class RGPassManager;
class Function;
+class RGPassManager;
//===----------------------------------------------------------------------===//
/// A pass that runs on each Region in a function.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolution.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolution.h
index 5286f6a220ec..81c5fc932588 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolution.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolution.h
@@ -31,7 +31,6 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
@@ -61,6 +60,8 @@ class DominatorTree;
class GEPOperator;
class Instruction;
class LLVMContext;
+class Loop;
+class LoopInfo;
class raw_ostream;
class ScalarEvolution;
class SCEVAddRecExpr;
@@ -804,7 +805,7 @@ public:
///
/// We don't have a way to invalidate per-loop dispositions. Clear and
/// recompute is simpler.
- void forgetLoopDispositions(const Loop *L) { LoopDispositions.clear(); }
+ void forgetLoopDispositions(const Loop *L);
/// Determine the minimum number of zero bits that S is guaranteed to end in
/// (at every loop iteration). It is, at the same time, the minimum number
@@ -998,6 +999,19 @@ public:
SmallVectorImpl<const SCEV *> &Subscripts,
SmallVectorImpl<const SCEV *> &Sizes);
+ /// Gathers the individual index expressions from a GEP instruction.
+ ///
+ /// This function optimistically assumes the GEP references into a fixed size
+ /// array. If this is actually true, this function returns a list of array
+ /// subscript expressions in \p Subscripts and a list of integers describing
+ /// the size of the individual array dimensions in \p Sizes. Both lists have
+ /// either equal length or the size list is one element shorter in case there
+ /// is no known size available for the outermost array dimension. Returns true
+ /// if successful and false otherwise.
+ bool getIndexExpressionsFromGEP(const GetElementPtrInst *GEP,
+ SmallVectorImpl<const SCEV *> &Subscripts,
+ SmallVectorImpl<int> &Sizes);
+
/// Split this SCEVAddRecExpr into two vectors of SCEVs representing the
/// subscripts and sizes of an array access.
///
@@ -1693,7 +1707,7 @@ private:
const SCEV *FoundRHS);
/// Return true if the condition denoted by \p LHS \p Pred \p RHS is implied
- /// by a call to \c @llvm.experimental.guard in \p BB.
+ /// by a call to @llvm.experimental.guard in \p BB.
bool isImpliedViaGuard(BasicBlock *BB, ICmpInst::Predicate Pred,
const SCEV *LHS, const SCEV *RHS);
@@ -1886,7 +1900,7 @@ private:
/// otherwise. The second component is the `FoldingSetNodeID` that was
/// constructed to look up the SCEV and the third component is the insertion
/// point.
- std::tuple<const SCEV *, FoldingSetNodeID, void *>
+ std::tuple<SCEV *, FoldingSetNodeID, void *>
findExistingSCEVInCache(int SCEVType, ArrayRef<const SCEV *> Ops);
FoldingSet<SCEV> UniqueSCEVs;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h
new file mode 100644
index 000000000000..480f92c117a0
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionDivision.h
@@ -0,0 +1,69 @@
+//===- llvm/Analysis/ScalarEvolutionDivision.h - See below ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the class that knows how to divide SCEV's.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONDIVISION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONDIVISION_H
+
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+
+namespace llvm {
+
+class SCEV;
+
+class ScalarEvolution;
+
+struct SCEVCouldNotCompute;
+
+struct SCEVDivision : public SCEVVisitor<SCEVDivision, void> {
+public:
+ // Computes the Quotient and Remainder of the division of Numerator by
+ // Denominator.
+ static void divide(ScalarEvolution &SE, const SCEV *Numerator,
+ const SCEV *Denominator, const SCEV **Quotient,
+ const SCEV **Remainder);
+
+ // Except in the trivial case described above, we do not know how to divide
+ // Expr by Denominator for the following functions with empty implementation.
+ void visitTruncateExpr(const SCEVTruncateExpr *Numerator) {}
+ void visitZeroExtendExpr(const SCEVZeroExtendExpr *Numerator) {}
+ void visitSignExtendExpr(const SCEVSignExtendExpr *Numerator) {}
+ void visitUDivExpr(const SCEVUDivExpr *Numerator) {}
+ void visitSMaxExpr(const SCEVSMaxExpr *Numerator) {}
+ void visitUMaxExpr(const SCEVUMaxExpr *Numerator) {}
+ void visitSMinExpr(const SCEVSMinExpr *Numerator) {}
+ void visitUMinExpr(const SCEVUMinExpr *Numerator) {}
+ void visitUnknown(const SCEVUnknown *Numerator) {}
+ void visitCouldNotCompute(const SCEVCouldNotCompute *Numerator) {}
+
+ void visitConstant(const SCEVConstant *Numerator);
+
+ void visitAddRecExpr(const SCEVAddRecExpr *Numerator);
+
+ void visitAddExpr(const SCEVAddExpr *Numerator);
+
+ void visitMulExpr(const SCEVMulExpr *Numerator);
+
+private:
+ SCEVDivision(ScalarEvolution &S, const SCEV *Numerator,
+ const SCEV *Denominator);
+
+ // Convenience function for giving up on the division. We set the quotient to
+ // be equal to zero and the remainder to be equal to the numerator.
+ void cannotDivide(const SCEV *Numerator);
+
+ ScalarEvolution &SE;
+ const SCEV *Denominator, *Quotient, *Remainder, *Zero, *One;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_SCALAREVOLUTIONDIVISION_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
index d008af7b7e6f..0076e02ae1bf 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -64,7 +64,7 @@ class Type;
}
};
- static unsigned short computeExpressionSize(ArrayRef<const SCEV *> Args) {
+ inline unsigned short computeExpressionSize(ArrayRef<const SCEV *> Args) {
APInt Size(16, 1);
for (auto *Arg : Args)
Size = Size.uadd_sat(APInt(16, Arg->getExpressionSize()));
@@ -222,18 +222,22 @@ class Type;
class SCEVAddExpr : public SCEVCommutativeExpr {
friend class ScalarEvolution;
- SCEVAddExpr(const FoldingSetNodeIDRef ID,
- const SCEV *const *O, size_t N)
- : SCEVCommutativeExpr(ID, scAddExpr, O, N) {}
+ Type *Ty;
- public:
- Type *getType() const {
- // Use the type of the last operand, which is likely to be a pointer
- // type, if there is one. This doesn't usually matter, but it can help
- // reduce casts when the expressions are expanded.
- return getOperand(getNumOperands() - 1)->getType();
+ SCEVAddExpr(const FoldingSetNodeIDRef ID, const SCEV *const *O, size_t N)
+ : SCEVCommutativeExpr(ID, scAddExpr, O, N) {
+ auto *FirstPointerTypedOp = find_if(operands(), [](const SCEV *Op) {
+ return Op->getType()->isPointerTy();
+ });
+ if (FirstPointerTypedOp != operands().end())
+ Ty = (*FirstPointerTypedOp)->getType();
+ else
+ Ty = getOperand(0)->getType();
}
+ public:
+ Type *getType() const { return Ty; }
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const SCEV *S) {
return S->getSCEVType() == scAddExpr;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
index 1a05594a46ec..6ab92a3a977f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -37,13 +37,13 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
namespace llvm {
class Loop;
class ScalarEvolution;
class SCEV;
+class SCEVAddRecExpr;
typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScopedNoAliasAA.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ScopedNoAliasAA.h
index dae733bd2015..c55228eace4b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ScopedNoAliasAA.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ScopedNoAliasAA.h
@@ -15,7 +15,6 @@
#define LLVM_ANALYSIS_SCOPEDNOALIASAA_H
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include <memory>
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/StackLifetime.h b/contrib/llvm-project/llvm/include/llvm/Analysis/StackLifetime.h
new file mode 100644
index 000000000000..8abc6cc1ce00
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/StackLifetime.h
@@ -0,0 +1,202 @@
+//===- StackLifetime.h - Alloca Lifetime Analysis --------------*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_STACKLIFETIME_H
+#define LLVM_ANALYSIS_STACKLIFETIME_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+
+class AllocaInst;
+class BasicBlock;
+class Function;
+class Instruction;
+
+/// Compute live ranges of allocas.
+/// Live ranges are represented as sets of "interesting" instructions, which are
+/// defined as instructions that may start or end an alloca's lifetime. These
+/// are:
+/// * lifetime.start and lifetime.end intrinsics
+/// * first instruction of any basic block
+/// Interesting instructions are numbered in the depth-first walk of the CFG,
+/// and in the program order inside each basic block.
+class StackLifetime {
+ /// A class representing liveness information for a single basic block.
+ /// Each bit in the BitVector represents the liveness property
+ /// for a different stack slot.
+ struct BlockLifetimeInfo {
+ explicit BlockLifetimeInfo(unsigned Size)
+ : Begin(Size), End(Size), LiveIn(Size), LiveOut(Size) {}
+
+ /// Which slots BEGINs in each basic block.
+ BitVector Begin;
+
+ /// Which slots ENDs in each basic block.
+ BitVector End;
+
+ /// Which slots are marked as LIVE_IN, coming into each basic block.
+ BitVector LiveIn;
+
+ /// Which slots are marked as LIVE_OUT, coming out of each basic block.
+ BitVector LiveOut;
+ };
+
+public:
+ class LifetimeAnnotationWriter;
+
+ /// This class represents a set of interesting instructions where an alloca is
+ /// live.
+ class LiveRange {
+ BitVector Bits;
+ friend raw_ostream &operator<<(raw_ostream &OS,
+ const StackLifetime::LiveRange &R);
+
+ public:
+ LiveRange(unsigned Size, bool Set = false) : Bits(Size, Set) {}
+ void addRange(unsigned Start, unsigned End) { Bits.set(Start, End); }
+
+ bool overlaps(const LiveRange &Other) const {
+ return Bits.anyCommon(Other.Bits);
+ }
+
+ void join(const LiveRange &Other) { Bits |= Other.Bits; }
+
+ bool test(unsigned Idx) const { return Bits.test(Idx); }
+ };
+
+ // Controls what is "alive" if control flow may reach the instruction
+ // with a different liveness of the alloca.
+ enum class LivenessType {
+ May, // May be alive on some path.
+ Must, // Must be alive on every path.
+ };
+
+private:
+ const Function &F;
+ LivenessType Type;
+
+ /// Maps active slots (per bit) for each basic block.
+ using LivenessMap = DenseMap<const BasicBlock *, BlockLifetimeInfo>;
+ LivenessMap BlockLiveness;
+
+ /// Interesting instructions. Instructions of the same block are adjustent
+ /// preserve in-block order.
+ SmallVector<const IntrinsicInst *, 64> Instructions;
+
+ /// A range [Start, End) of instruction ids for each basic block.
+ /// Instructions inside each BB have monotonic and consecutive ids.
+ DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
+
+ ArrayRef<const AllocaInst *> Allocas;
+ unsigned NumAllocas;
+ DenseMap<const AllocaInst *, unsigned> AllocaNumbering;
+
+ /// LiveRange for allocas.
+ SmallVector<LiveRange, 8> LiveRanges;
+
+ /// The set of allocas that have at least one lifetime.start. All other
+ /// allocas get LiveRange that corresponds to the entire function.
+ BitVector InterestingAllocas;
+
+ struct Marker {
+ unsigned AllocaNo;
+ bool IsStart;
+ };
+
+ /// List of {InstNo, {AllocaNo, IsStart}} for each BB, ordered by InstNo.
+ DenseMap<const BasicBlock *, SmallVector<std::pair<unsigned, Marker>, 4>>
+ BBMarkers;
+
+ void dumpAllocas() const;
+ void dumpBlockLiveness() const;
+ void dumpLiveRanges() const;
+
+ void collectMarkers();
+ void calculateLocalLiveness();
+ void calculateLiveIntervals();
+
+public:
+ StackLifetime(const Function &F, ArrayRef<const AllocaInst *> Allocas,
+ LivenessType Type);
+
+ void run();
+
+ iterator_range<
+ filter_iterator<ArrayRef<const IntrinsicInst *>::const_iterator,
+ std::function<bool(const IntrinsicInst *)>>>
+ getMarkers() const {
+ std::function<bool(const IntrinsicInst *)> NotNull(
+ [](const IntrinsicInst *I) -> bool { return I; });
+ return make_filter_range(Instructions, NotNull);
+ }
+
+ /// Returns a set of "interesting" instructions where the given alloca is
+ /// live. Not all instructions in a function are interesting: we pick a set
+ /// that is large enough for LiveRange::Overlaps to be correct.
+ const LiveRange &getLiveRange(const AllocaInst *AI) const;
+
+ /// Returns true if instruction is reachable from entry.
+ bool isReachable(const Instruction *I) const;
+
+ /// Returns true if the alloca is alive after the instruction.
+ bool isAliveAfter(const AllocaInst *AI, const Instruction *I) const;
+
+ /// Returns a live range that represents an alloca that is live throughout the
+ /// entire function.
+ LiveRange getFullLiveRange() const {
+ return LiveRange(Instructions.size(), true);
+ }
+
+ void print(raw_ostream &O);
+};
+
+static inline raw_ostream &operator<<(raw_ostream &OS, const BitVector &V) {
+ OS << "{";
+ int Idx = V.find_first();
+ bool First = true;
+ while (Idx >= 0) {
+ if (!First) {
+ OS << ", ";
+ }
+ First = false;
+ OS << Idx;
+ Idx = V.find_next(Idx);
+ }
+ OS << "}";
+ return OS;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const StackLifetime::LiveRange &R) {
+ return OS << R.Bits;
+}
+
+/// Printer pass for testing.
+class StackLifetimePrinterPass
+ : public PassInfoMixin<StackLifetimePrinterPass> {
+ StackLifetime::LivenessType Type;
+ raw_ostream &OS;
+
+public:
+ StackLifetimePrinterPass(raw_ostream &OS, StackLifetime::LivenessType Type)
+ : Type(Type), OS(OS) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_ANALYSIS_STACKLIFETIME_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/StackSafetyAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/StackSafetyAnalysis.h
index f9d8b08ac142..846c2e6f7e91 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/StackSafetyAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/StackSafetyAnalysis.h
@@ -13,28 +13,70 @@
#ifndef LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
#define LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
+#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
+class AllocaInst;
+class ScalarEvolution;
+
/// Interface to access stack safety analysis results for single function.
class StackSafetyInfo {
public:
- struct FunctionInfo;
+ struct InfoTy;
private:
- std::unique_ptr<FunctionInfo> Info;
+ Function *F = nullptr;
+ std::function<ScalarEvolution &()> GetSE;
+ mutable std::unique_ptr<InfoTy> Info;
public:
StackSafetyInfo();
- StackSafetyInfo(FunctionInfo &&Info);
+ StackSafetyInfo(Function *F, std::function<ScalarEvolution &()> GetSE);
StackSafetyInfo(StackSafetyInfo &&);
StackSafetyInfo &operator=(StackSafetyInfo &&);
~StackSafetyInfo();
+ const InfoTy &getInfo() const;
+
// TODO: Add useful for client methods.
void print(raw_ostream &O) const;
+
+ /// Parameters use for a FunctionSummary.
+ /// Function collects access information of all pointer parameters.
+ /// Information includes a range of direct access of parameters by the
+ /// functions and all call sites accepting the parameter.
+ /// StackSafety assumes that missing parameter information means possibility
+ /// of access to the parameter with any offset, so we can correctly link
+ /// code without StackSafety information, e.g. non-ThinLTO.
+ std::vector<FunctionSummary::ParamAccess> getParamAccesses() const;
+};
+
+class StackSafetyGlobalInfo {
+public:
+ struct InfoTy;
+
+private:
+ Module *M = nullptr;
+ std::function<const StackSafetyInfo &(Function &F)> GetSSI;
+ const ModuleSummaryIndex *Index = nullptr;
+ mutable std::unique_ptr<InfoTy> Info;
+ const InfoTy &getInfo() const;
+
+public:
+ StackSafetyGlobalInfo();
+ StackSafetyGlobalInfo(
+ Module *M, std::function<const StackSafetyInfo &(Function &F)> GetSSI,
+ const ModuleSummaryIndex *Index);
+ StackSafetyGlobalInfo(StackSafetyGlobalInfo &&);
+ StackSafetyGlobalInfo &operator=(StackSafetyGlobalInfo &&);
+ ~StackSafetyGlobalInfo();
+
+ bool isSafe(const AllocaInst &AI) const;
+ void print(raw_ostream &O) const;
+ void dump() const;
};
/// StackSafetyInfo wrapper for the new pass manager.
@@ -72,8 +114,6 @@ public:
bool runOnFunction(Function &F) override;
};
-using StackSafetyGlobalInfo = std::map<const GlobalValue *, StackSafetyInfo>;
-
/// This pass performs the global (interprocedural) stack safety analysis (new
/// pass manager).
class StackSafetyGlobalAnalysis
@@ -99,14 +139,15 @@ public:
/// This pass performs the global (interprocedural) stack safety analysis
/// (legacy pass manager).
class StackSafetyGlobalInfoWrapperPass : public ModulePass {
- StackSafetyGlobalInfo SSI;
+ StackSafetyGlobalInfo SSGI;
public:
static char ID;
StackSafetyGlobalInfoWrapperPass();
+ ~StackSafetyGlobalInfoWrapperPass();
- const StackSafetyGlobalInfo &getResult() const { return SSI; }
+ const StackSafetyGlobalInfo &getResult() const { return SSGI; }
void print(raw_ostream &O, const Module *M) const override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
@@ -114,6 +155,10 @@ public:
bool runOnModule(Module &M) override;
};
+bool needsParamAccessSummary(const Module &M);
+
+void generateParamAccessSummary(ModuleSummaryIndex &Index);
+
} // end namespace llvm
#endif // LLVM_ANALYSIS_STACKSAFETYANALYSIS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/SyncDependenceAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/SyncDependenceAnalysis.h
index 099403b47757..2f07b3135308 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/SyncDependenceAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/SyncDependenceAnalysis.h
@@ -37,12 +37,7 @@ using ConstBlockSet = SmallPtrSet<const BasicBlock *, 4>;
/// This analysis relates points of divergent control to points of converging
/// divergent control. The analysis requires all loops to be reducible.
class SyncDependenceAnalysis {
- void visitSuccessor(const BasicBlock &succBlock, const Loop *termLoop,
- const BasicBlock *defBlock);
-
public:
- bool inRegion(const BasicBlock &BB) const;
-
~SyncDependenceAnalysis();
SyncDependenceAnalysis(const DominatorTree &DT, const PostDominatorTree &PDT,
const LoopInfo &LI);
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/SyntheticCountsUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/SyntheticCountsUtils.h
index b9b4c98bfc35..358f757314ee 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/SyntheticCountsUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/SyntheticCountsUtils.h
@@ -19,9 +19,6 @@
namespace llvm {
-class CallGraph;
-class Function;
-
/// Class with methods to propagate synthetic entry counts.
///
/// This class is templated on the type of the call graph and designed to work
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h
index 7ab6562be440..b23316ac3d9b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetFolder.h
@@ -22,22 +22,23 @@
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
-class TargetFolder {
+class TargetFolder final : public IRBuilderFolder {
const DataLayout &DL;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
- if (Constant *CF = ConstantFoldConstant(C, DL))
- return CF;
- return C;
+ return ConstantFoldConstant(C, DL);
}
+ virtual void anchor();
+
public:
explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
@@ -46,66 +47,70 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW));
}
- Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFAdd(LHS, RHS));
}
Constant *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW));
}
- Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFSub(LHS, RHS));
}
Constant *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW));
}
- Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFMul(LHS, RHS));
}
- Constant *CreateUDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ Constant *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const override {
return Fold(ConstantExpr::getUDiv(LHS, RHS, isExact));
}
- Constant *CreateSDiv(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ Constant *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const override {
return Fold(ConstantExpr::getSDiv(LHS, RHS, isExact));
}
- Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFDiv(LHS, RHS));
}
- Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getURem(LHS, RHS));
}
- Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getSRem(LHS, RHS));
}
- Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getFRem(LHS, RHS));
}
Constant *CreateShl(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW));
}
- Constant *CreateLShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ Constant *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const override {
return Fold(ConstantExpr::getLShr(LHS, RHS, isExact));
}
- Constant *CreateAShr(Constant *LHS, Constant *RHS, bool isExact = false)const{
+ Constant *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const override {
return Fold(ConstantExpr::getAShr(LHS, RHS, isExact));
}
- Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getAnd(LHS, RHS));
}
- Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getOr(LHS, RHS));
}
- Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::getXor(LHS, RHS));
}
Constant *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
+ Constant *LHS, Constant *RHS) const override {
return Fold(ConstantExpr::get(Opc, LHS, RHS));
}
@@ -114,17 +119,17 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return Fold(ConstantExpr::getNeg(C, HasNUW, HasNSW));
}
- Constant *CreateFNeg(Constant *C) const {
+ Constant *CreateFNeg(Constant *C) const override {
return Fold(ConstantExpr::getFNeg(C));
}
- Constant *CreateNot(Constant *C) const {
+ Constant *CreateNot(Constant *C) const override {
return Fold(ConstantExpr::getNot(C));
}
- Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
+ Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
return Fold(ConstantExpr::get(Opc, C));
}
@@ -133,33 +138,34 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ ArrayRef<Constant *> IdxList) const override {
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
- Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ ArrayRef<Value *> IdxList) const override {
return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
}
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ Constant *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const {
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
}
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ Constant *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
}
@@ -168,54 +174,54 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
+ Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getCast(Op, C, DestTy));
}
Constant *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
+ bool isSigned) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getIntegerCast(C, DestTy, isSigned));
}
- Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+ Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getPointerCast(C, DestTy));
}
- Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+ Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getFPCast(C, DestTy));
}
- Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
- Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
- Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
- Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getZExtOrBitCast(C, DestTy));
}
- Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getSExtOrBitCast(C, DestTy));
}
- Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getTruncOrBitCast(C, DestTy));
}
Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
- Type *DestTy) const {
+ Type *DestTy) const override {
if (C->getType() == DestTy)
return C; // avoid calling Fold
return Fold(ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy));
@@ -226,11 +232,11 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
+ Constant *RHS) const override {
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
}
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
+ Constant *RHS) const override {
return Fold(ConstantExpr::getCompare(P, LHS, RHS));
}
@@ -238,31 +244,32 @@ public:
// Other Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ Constant *CreateSelect(Constant *C, Constant *True,
+ Constant *False) const override {
return Fold(ConstantExpr::getSelect(C, True, False));
}
- Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
return Fold(ConstantExpr::getExtractElement(Vec, Idx));
}
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
+ Constant *Idx) const override {
return Fold(ConstantExpr::getInsertElement(Vec, NewElt, Idx));
}
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
+ ArrayRef<int> Mask) const override {
return Fold(ConstantExpr::getShuffleVector(V1, V2, Mask));
}
Constant *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return Fold(ConstantExpr::getExtractValue(Agg, IdxList));
}
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return Fold(ConstantExpr::getInsertValue(Agg, Val, IdxList));
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.def b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.def
index afed404f04c0..3864d4955104 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.def
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.def
@@ -136,9 +136,15 @@ TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_tRKSt9nothrow_t")
/// void operator delete[](void*, unsigned int);
TLI_DEFINE_ENUM_INTERNAL(ZdaPvj)
TLI_DEFINE_STRING_INTERNAL("_ZdaPvj")
+/// void operator delete[](void*, unsigned int, align_val_t);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPvjSt11align_val_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPvjSt11align_val_t")
/// void operator delete[](void*, unsigned long);
TLI_DEFINE_ENUM_INTERNAL(ZdaPvm)
TLI_DEFINE_STRING_INTERNAL("_ZdaPvm")
+/// void operator delete[](void*, unsigned long, align_val_t);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPvmSt11align_val_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPvmSt11align_val_t")
/// void operator delete(void*);
TLI_DEFINE_ENUM_INTERNAL(ZdlPv)
TLI_DEFINE_STRING_INTERNAL("_ZdlPv")
@@ -154,9 +160,15 @@ TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_tRKSt9nothrow_t")
/// void operator delete(void*, unsigned int);
TLI_DEFINE_ENUM_INTERNAL(ZdlPvj)
TLI_DEFINE_STRING_INTERNAL("_ZdlPvj")
+/// void operator delete(void*, unsigned int, align_val_t)
+TLI_DEFINE_ENUM_INTERNAL(ZdlPvjSt11align_val_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPvjSt11align_val_t")
/// void operator delete(void*, unsigned long);
TLI_DEFINE_ENUM_INTERNAL(ZdlPvm)
TLI_DEFINE_STRING_INTERNAL("_ZdlPvm")
+/// void operator delete(void*, unsigned long, align_val_t)
+TLI_DEFINE_ENUM_INTERNAL(ZdlPvmSt11align_val_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPvmSt11align_val_t")
/// void *new[](unsigned int);
TLI_DEFINE_ENUM_INTERNAL(Znaj)
TLI_DEFINE_STRING_INTERNAL("_Znaj")
@@ -434,6 +446,9 @@ TLI_DEFINE_STRING_INTERNAL("__strlcat_chk")
/// size_t dstsize);
TLI_DEFINE_ENUM_INTERNAL(strlcpy_chk)
TLI_DEFINE_STRING_INTERNAL("__strlcpy_chk")
+/// size_t __strlen_chk(const char *s1, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(strlen_chk)
+TLI_DEFINE_STRING_INTERNAL("__strlen_chk")
/// char *strncat_chk(char *s1, const char *s2, size_t n, size_t s1size);
TLI_DEFINE_ENUM_INTERNAL(strncat_chk)
TLI_DEFINE_STRING_INTERNAL("__strncat_chk")
@@ -478,6 +493,9 @@ TLI_DEFINE_STRING_INTERNAL("acoshl")
/// long double acosl(long double x);
TLI_DEFINE_ENUM_INTERNAL(acosl)
TLI_DEFINE_STRING_INTERNAL("acosl")
+/// void *aligned_alloc(size_t alignment, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(aligned_alloc)
+TLI_DEFINE_STRING_INTERNAL("aligned_alloc")
/// double asin(double x);
TLI_DEFINE_ENUM_INTERNAL(asin)
TLI_DEFINE_STRING_INTERNAL("asin")
@@ -1119,6 +1137,15 @@ TLI_DEFINE_STRING_INTERNAL("reallocf")
/// char *realpath(const char *file_name, char *resolved_name);
TLI_DEFINE_ENUM_INTERNAL(realpath)
TLI_DEFINE_STRING_INTERNAL("realpath")
+/// double remainder(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(remainder)
+TLI_DEFINE_STRING_INTERNAL("remainder")
+/// float remainderf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(remainderf)
+TLI_DEFINE_STRING_INTERNAL("remainderf")
+/// long double remainderl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(remainderl)
+TLI_DEFINE_STRING_INTERNAL("remainderl")
/// int remove(const char *path);
TLI_DEFINE_ENUM_INTERNAL(remove)
TLI_DEFINE_STRING_INTERNAL("remove")
@@ -1143,6 +1170,15 @@ TLI_DEFINE_STRING_INTERNAL("rmdir")
/// double round(double x);
TLI_DEFINE_ENUM_INTERNAL(round)
TLI_DEFINE_STRING_INTERNAL("round")
+/// double roundeven(double x);
+TLI_DEFINE_ENUM_INTERNAL(roundeven)
+TLI_DEFINE_STRING_INTERNAL("roundeven")
+/// float roundevenf(float x);
+TLI_DEFINE_ENUM_INTERNAL(roundevenf)
+TLI_DEFINE_STRING_INTERNAL("roundevenf")
+/// long double roundevenl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(roundevenl)
+TLI_DEFINE_STRING_INTERNAL("roundevenl")
/// float roundf(float x);
TLI_DEFINE_ENUM_INTERNAL(roundf)
TLI_DEFINE_STRING_INTERNAL("roundf")
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 1bd9db756bb3..3a7c26e1463b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -12,15 +12,15 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
namespace llvm {
template <typename T> class ArrayRef;
+class Triple;
/// Describes a possible vectorization of a function.
/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
@@ -129,7 +129,7 @@ public:
void setAvailableWithName(LibFunc F, StringRef Name) {
if (StandardNames[F] != Name) {
setState(F, CustomName);
- CustomNames[F] = Name;
+ CustomNames[F] = std::string(Name);
assert(CustomNames.find(F) != CustomNames.end());
} else {
setState(F, StandardName);
@@ -260,6 +260,21 @@ public:
return *this;
}
+ /// Determine whether a callee with the given TLI can be inlined into
+ /// caller with this TLI, based on 'nobuiltin' attributes. When requested,
+ /// allow inlining into a caller with a superset of the callee's nobuiltin
+ /// attributes, which is conservatively correct.
+ bool areInlineCompatible(const TargetLibraryInfo &CalleeTLI,
+ bool AllowCallerSuperset) const {
+ if (!AllowCallerSuperset)
+ return OverrideAsUnavailable == CalleeTLI.OverrideAsUnavailable;
+ BitVector B = OverrideAsUnavailable;
+ B |= CalleeTLI.OverrideAsUnavailable;
+ // We can inline if the union of the caller and callee's nobuiltin
+ // attributes is no stricter than the caller's nobuiltin attributes.
+ return B == OverrideAsUnavailable;
+ }
+
/// Searches for a particular function name.
///
/// If it is one of the known library functions, return true and set F to the
@@ -272,11 +287,11 @@ public:
return Impl->getLibFunc(FDecl, F);
}
- /// If a callsite does not have the 'nobuiltin' attribute, return if the
+ /// If a callbase does not have the 'nobuiltin' attribute, return if the
/// called function is a known library function and set F to that function.
- bool getLibFunc(ImmutableCallSite CS, LibFunc &F) const {
- return !CS.isNoBuiltin() && CS.getCalledFunction() &&
- getLibFunc(*(CS.getCalledFunction()), F);
+ bool getLibFunc(const CallBase &CB, LibFunc &F) const {
+ return !CB.isNoBuiltin() && CB.getCalledFunction() &&
+ getLibFunc(*(CB.getCalledFunction()), F);
}
/// Disables all builtins.
@@ -335,6 +350,7 @@ public:
case LibFunc_trunc: case LibFunc_truncf: case LibFunc_truncl:
case LibFunc_log2: case LibFunc_log2f: case LibFunc_log2l:
case LibFunc_exp2: case LibFunc_exp2f: case LibFunc_exp2l:
+ case LibFunc_memcpy: case LibFunc_memset: case LibFunc_memmove:
case LibFunc_memcmp: case LibFunc_bcmp: case LibFunc_strcmp:
case LibFunc_strcpy: case LibFunc_stpcpy: case LibFunc_strlen:
case LibFunc_strnlen: case LibFunc_memchr: case LibFunc_mempcpy:
@@ -390,12 +406,16 @@ public:
FunctionAnalysisManager::Invalidator &) {
return false;
}
-
/// Returns the largest vectorization factor used in the list of
/// vector functions.
unsigned getWidestVF(StringRef ScalarF) const {
return Impl->getWidestVF(ScalarF);
}
+
+ /// Check if the function "F" is listed in a library known to LLVM.
+ bool isKnownVectorFunctionInLibrary(StringRef F) const {
+ return this->isFunctionVectorizable(F);
+ }
};
/// Analysis pass providing the \c TargetLibraryInfo.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 5382d76813a7..b6698eefdb01 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -21,16 +21,11 @@
#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
-#include "llvm/ADT/Optional.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/Analysis/AssumptionCache.h"
#include <functional>
namespace llvm {
@@ -41,13 +36,17 @@ typedef unsigned ID;
class AssumptionCache;
class BlockFrequencyInfo;
+class DominatorTree;
class BranchInst;
+class CallBase;
+class ExtractElementInst;
class Function;
class GlobalValue;
class IntrinsicInst;
class LoadInst;
class LoopAccessInfo;
class Loop;
+class LoopInfo;
class ProfileSummaryInfo;
class SCEV;
class ScalarEvolution;
@@ -57,6 +56,7 @@ class TargetLibraryInfo;
class Type;
class User;
class Value;
+template <typename T> class Optional;
/// Information about a load/store intrinsic defined by the target.
struct MemIntrinsicInfo {
@@ -78,7 +78,8 @@ struct MemIntrinsicInfo {
bool isUnordered() const {
return (Ordering == AtomicOrdering::NotAtomic ||
- Ordering == AtomicOrdering::Unordered) && !IsVolatile;
+ Ordering == AtomicOrdering::Unordered) &&
+ !IsVolatile;
}
};
@@ -106,6 +107,68 @@ struct HardwareLoopInfo {
bool canAnalyze(LoopInfo &LI);
};
+class IntrinsicCostAttributes {
+ const IntrinsicInst *II = nullptr;
+ Type *RetTy = nullptr;
+ Intrinsic::ID IID;
+ SmallVector<Type *, 4> ParamTys;
+ SmallVector<const Value *, 4> Arguments;
+ FastMathFlags FMF;
+ unsigned VF = 1;
+ // If ScalarizationCost is UINT_MAX, the cost of scalarizing the
+ // arguments and the return value will be computed based on types.
+ unsigned ScalarizationCost = std::numeric_limits<unsigned>::max();
+
+public:
+ IntrinsicCostAttributes(const IntrinsicInst &I);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
+ unsigned Factor);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, const CallBase &CI,
+ unsigned Factor, unsigned ScalarCost);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
+ ArrayRef<Type *> Tys, FastMathFlags Flags);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
+ ArrayRef<Type *> Tys, FastMathFlags Flags,
+ unsigned ScalarCost);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
+ ArrayRef<Type *> Tys, FastMathFlags Flags,
+ unsigned ScalarCost,
+ const IntrinsicInst *I);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
+ ArrayRef<Type *> Tys);
+
+ IntrinsicCostAttributes(Intrinsic::ID Id, Type *RTy,
+ ArrayRef<const Value *> Args);
+
+ Intrinsic::ID getID() const { return IID; }
+ const IntrinsicInst *getInst() const { return II; }
+ Type *getReturnType() const { return RetTy; }
+ unsigned getVectorFactor() const { return VF; }
+ FastMathFlags getFlags() const { return FMF; }
+ unsigned getScalarizationCost() const { return ScalarizationCost; }
+ const SmallVectorImpl<const Value *> &getArgs() const { return Arguments; }
+ const SmallVectorImpl<Type *> &getArgTypes() const { return ParamTys; }
+
+ bool isTypeBasedOnly() const {
+ return Arguments.empty();
+ }
+
+ bool skipScalarizationCost() const {
+ return ScalarizationCost != std::numeric_limits<unsigned>::max();
+ }
+};
+
+class TargetTransformInfo;
+typedef TargetTransformInfo TTI;
+
/// This pass provides access to the codegen interfaces that are needed
/// for IR-level transformations.
class TargetTransformInfo {
@@ -154,7 +217,8 @@ public:
enum TargetCostKind {
TCK_RecipThroughput, ///< Reciprocal throughput.
TCK_Latency, ///< The latency of instruction.
- TCK_CodeSize ///< Instruction code size.
+ TCK_CodeSize, ///< Instruction code size.
+ TCK_SizeAndLatency ///< The weighted sum of size and latency.
};
/// Query the cost of a specified instruction.
@@ -165,7 +229,7 @@ public:
/// Note, this method does not cache the cost calculation and it
/// can be expensive in some cases.
int getInstructionCost(const Instruction *I, enum TargetCostKind kind) const {
- switch (kind){
+ switch (kind) {
case TCK_RecipThroughput:
return getInstructionThroughput(I);
@@ -173,7 +237,8 @@ public:
return getInstructionLatency(I);
case TCK_CodeSize:
- return getUserCost(I);
+ case TCK_SizeAndLatency:
+ return getUserCost(I, kind);
}
llvm_unreachable("Unknown instruction cost kind");
}
@@ -202,61 +267,10 @@ public:
TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86.
};
- /// Estimate the cost of a specific operation when lowered.
- ///
- /// Note that this is designed to work on an arbitrary synthetic opcode, and
- /// thus work for hypothetical queries before an instruction has even been
- /// formed. However, this does *not* work for GEPs, and must not be called
- /// for a GEP instruction. Instead, use the dedicated getGEPCost interface as
- /// analyzing a GEP's cost required more information.
- ///
- /// Typically only the result type is required, and the operand type can be
- /// omitted. However, if the opcode is one of the cast instructions, the
- /// operand type is required.
- ///
- /// The returned cost is defined in terms of \c TargetCostConstants, see its
- /// comments for a detailed explanation of the cost values.
- int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy = nullptr) const;
-
/// Estimate the cost of a GEP operation when lowered.
- ///
- /// The contract for this function is the same as \c getOperationCost except
- /// that it supports an interface that provides extra information specific to
- /// the GEP operation.
int getGEPCost(Type *PointeeType, const Value *Ptr,
- ArrayRef<const Value *> Operands) const;
-
- /// Estimate the cost of a EXT operation when lowered.
- ///
- /// The contract for this function is the same as \c getOperationCost except
- /// that it supports an interface that provides extra information specific to
- /// the EXT operation.
- int getExtCost(const Instruction *I, const Value *Src) const;
-
- /// Estimate the cost of a function call when lowered.
- ///
- /// The contract for this is the same as \c getOperationCost except that it
- /// supports an interface that provides extra information specific to call
- /// instructions.
- ///
- /// This is the most basic query for estimating call cost: it only knows the
- /// function type and (potentially) the number of arguments at the call site.
- /// The latter is only interesting for varargs function types.
- int getCallCost(FunctionType *FTy, int NumArgs = -1,
- const User *U = nullptr) const;
-
- /// Estimate the cost of calling a specific function when lowered.
- ///
- /// This overload adds the ability to reason about the particular function
- /// being called in the event it is a library call with special lowering.
- int getCallCost(const Function *F, int NumArgs = -1,
- const User *U = nullptr) const;
-
- /// Estimate the cost of calling a specific function when lowered.
- ///
- /// This overload allows specifying a set of candidate argument values.
- int getCallCost(const Function *F, ArrayRef<const Value *> Arguments,
- const User *U = nullptr) const;
+ ArrayRef<const Value *> Operands,
+ TargetCostKind CostKind = TCK_SizeAndLatency) const;
/// \returns A value by which our inlining threshold should be multiplied.
/// This is primarily used to bump up the inlining threshold wholesale on
@@ -270,28 +284,14 @@ public:
///
/// Vector bonuses: We want to more aggressively inline vector-dense kernels
/// and apply this bonus based on the percentage of vector instructions. A
- /// bonus is applied if the vector instructions exceed 50% and half that amount
- /// is applied if it exceeds 10%. Note that these bonuses are some what
+ /// bonus is applied if the vector instructions exceed 50% and half that
+ /// amount is applied if it exceeds 10%. Note that these bonuses are some what
/// arbitrary and evolved over time by accident as much as because they are
/// principled bonuses.
/// FIXME: It would be nice to base the bonus values on something more
/// scientific. A target may has no bonus on vector instructions.
int getInlinerVectorBonusPercent() const;
- /// Estimate the cost of an intrinsic when lowered.
- ///
- /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
- int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys,
- const User *U = nullptr) const;
-
- /// Estimate the cost of an intrinsic when lowered.
- ///
- /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
- int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments,
- const User *U = nullptr) const;
-
/// \return the expected cost of a memcpy, which could e.g. depend on the
/// source/destination type and alignment and the number of bytes copied.
int getMemcpyCost(const Instruction *I) const;
@@ -307,15 +307,7 @@ public:
/// Estimate the cost of a given IR user when lowered.
///
/// This can estimate the cost of either a ConstantExpr or Instruction when
- /// lowered. It has two primary advantages over the \c getOperationCost and
- /// \c getGEPCost above, and one significant disadvantage: it can only be
- /// used when the IR construct has already been formed.
- ///
- /// The advantages are that it can inspect the SSA use graph to reason more
- /// accurately about the cost. For example, all-constant-GEPs can often be
- /// folded into a load or other instruction, but if they are used in some
- /// other context they may not be folded. This routine can distinguish such
- /// cases.
+ /// lowered.
///
/// \p Operands is a list of operands which can be a result of transformations
/// of the current operands. The number of the operands on the list must equal
@@ -325,14 +317,15 @@ public:
///
/// The returned cost is defined in terms of \c TargetCostConstants, see its
/// comments for a detailed explanation of the cost values.
- int getUserCost(const User *U, ArrayRef<const Value *> Operands) const;
+ int getUserCost(const User *U, ArrayRef<const Value *> Operands,
+ TargetCostKind CostKind) const;
/// This is a helper function which calls the two-argument getUserCost
/// with \p Operands which are the current operands U has.
- int getUserCost(const User *U) const {
+ int getUserCost(const User *U, TargetCostKind CostKind) const {
SmallVector<const Value *, 4> Operands(U->value_op_begin(),
U->value_op_end());
- return getUserCost(U, Operands);
+ return getUserCost(U, Operands, CostKind);
}
/// Return true if branch divergence exists.
@@ -342,12 +335,16 @@ public:
/// branches.
bool hasBranchDivergence() const;
+ /// Return true if the target prefers to use GPU divergence analysis to
+ /// replace the legacy version.
+ bool useGPUDivergenceAnalysis() const;
+
/// Returns whether V is a source of divergence.
///
/// This function provides the target-dependent information for
- /// the target-independent LegacyDivergenceAnalysis. LegacyDivergenceAnalysis first
- /// builds the dependency graph, and then runs the reachability algorithm
- /// starting with the sources of divergence.
+ /// the target-independent LegacyDivergenceAnalysis. LegacyDivergenceAnalysis
+ /// first builds the dependency graph, and then runs the reachability
+ /// algorithm starting with the sources of divergence.
bool isSourceOfDivergence(const Value *V) const;
// Returns true for the target specific
@@ -380,12 +377,15 @@ public:
bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const;
+ bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const;
+
/// Rewrite intrinsic call \p II such that \p OldV will be replaced with \p
/// NewV, which has a different address space. This should happen for every
/// operand index that collectFlatAddressOperands returned for the intrinsic.
- /// \returns true if the intrinsic /// was handled.
- bool rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
- Value *OldV, Value *NewV) const;
+ /// \returns nullptr if the intrinsic was not handled. Otherwise, returns the
+ /// new value (which may be the original \p II with modified operands).
+ Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
+ Value *NewV) const;
/// Test whether calls to a function lower to actual program function
/// calls.
@@ -450,11 +450,6 @@ public:
/// transformation will select an unrolling factor based on the current cost
/// threshold and other factors.
unsigned Count;
- /// A forced peeling factor (the number of bodied of the original loop
- /// that should be peeled off before the loop body). When set to 0, the
- /// unrolling transformation will select a peeling factor based on profile
- /// information and other factors.
- unsigned PeelCount;
/// Default unroll count for loops with run-time trip count.
unsigned DefaultUnrollRuntimeCount;
// Set the maximum unrolling factor. The unrolling factor may be selected
@@ -488,22 +483,18 @@ public:
bool Force;
/// Allow using trip count upper bound to unroll loops.
bool UpperBound;
- /// Allow peeling off loop iterations.
- bool AllowPeeling;
/// Allow unrolling of all the iterations of the runtime loop remainder.
bool UnrollRemainder;
/// Allow unroll and jam. Used to enable unroll and jam for the target.
bool UnrollAndJam;
- /// Allow peeling basing on profile. Uses to enable peeling off all
- /// iterations basing on provided profile.
- /// If the value is true the peeling cost model can decide to peel only
- /// some iterations and in this case it will set this to false.
- bool PeelProfiledIterations;
/// Threshold for unroll and jam, for inner loop size. The 'Threshold'
/// value above is used during unroll and jam for the outer loop size.
/// This value is used in the same manner to limit the size of the inner
/// loop.
unsigned UnrollAndJamInnerLoopThreshold;
+ /// Don't allow loop unrolling to simulate more than this number of
+ /// iterations when checking full unroll profitability
+ unsigned MaxIterationsCountToAnalyze;
};
/// Get target-customized preferences for the generic loop unrolling
@@ -515,17 +506,42 @@ public:
/// Query the target whether it would be profitable to convert the given loop
/// into a hardware loop.
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
- AssumptionCache &AC,
- TargetLibraryInfo *LibInfo,
+ AssumptionCache &AC, TargetLibraryInfo *LibInfo,
HardwareLoopInfo &HWLoopInfo) const;
- /// Query the target whether it would be prefered to create a predicated vector
- /// loop, which can avoid the need to emit a scalar epilogue loop.
+ /// Query the target whether it would be prefered to create a predicated
+ /// vector loop, which can avoid the need to emit a scalar epilogue loop.
bool preferPredicateOverEpilogue(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
AssumptionCache &AC, TargetLibraryInfo *TLI,
DominatorTree *DT,
const LoopAccessInfo *LAI) const;
+ /// Query the target whether lowering of the llvm.get.active.lane.mask
+ /// intrinsic is supported.
+ bool emitGetActiveLaneMask() const;
+
+ // Parameters that control the loop peeling transformation
+ struct PeelingPreferences {
+ /// A forced peeling factor (the number of bodied of the original loop
+ /// that should be peeled off before the loop body). When set to 0, the
+ /// a peeling factor based on profile information and other factors.
+ unsigned PeelCount;
+ /// Allow peeling off loop iterations.
+ bool AllowPeeling;
+ /// Allow peeling off loop iterations for loop nests.
+ bool AllowLoopNestsPeeling;
+ /// Allow peeling basing on profile. Uses to enable peeling off all
+ /// iterations basing on provided profile.
+ /// If the value is true the peeling cost model can decide to peel only
+ /// some iterations and in this case it will set this to false.
+ bool PeelProfiledIterations;
+ };
+
+ /// Get target-customized preferences for the generic loop peeling
+ /// transformation. The caller will initialize \p PP with the current
+ /// target-independent defaults with information from \p L and \p SE.
+ void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ PeelingPreferences &PP) const;
/// @}
/// \name Scalar Target Information
@@ -567,6 +583,9 @@ public:
bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) const;
+ /// \returns true if LSR should not optimize a chain that includes \p I.
+ bool isProfitableLSRChainElement(Instruction *I) const;
+
/// Return true if the target can fuse a compare and branch.
/// Loop-strength-reduction (LSR) uses that knowledge to adjust its cost
/// calculation for the instructions in a loop.
@@ -587,9 +606,9 @@ public:
bool shouldFavorBackedgeIndex(const Loop *L) const;
/// Return true if the target supports masked store.
- bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) const;
+ bool isLegalMaskedStore(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked load.
- bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) const;
+ bool isLegalMaskedLoad(Type *DataType, Align Alignment) const;
/// Return true if the target supports nontemporal store.
bool isLegalNTStore(Type *DataType, Align Alignment) const;
@@ -597,9 +616,9 @@ public:
bool isLegalNTLoad(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked scatter.
- bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) const;
+ bool isLegalMaskedScatter(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked gather.
- bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) const;
+ bool isLegalMaskedGather(Type *DataType, Align Alignment) const;
/// Return true if the target supports masked compress store.
bool isLegalMaskedCompressStore(Type *DataType) const;
@@ -665,8 +684,15 @@ public:
/// should use coldcc calling convention.
bool useColdCCForColdCall(Function &F) const;
- unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) const;
+ /// Estimate the overhead of scalarizing an instruction. Insert and Extract
+ /// are set if the demanded result elements need to be inserted and/or
+ /// extracted from vectors.
+ unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
+ bool Insert, bool Extract) const;
+ /// Estimate the overhead of scalarizing an instructions unique
+ /// non-constant operands. The types of the arguments are ordinarily
+ /// scalar, in which case the costs are multiplied with VF.
unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
unsigned VF) const;
@@ -726,8 +752,8 @@ public:
bool isFPVectorizationPotentiallyUnsafe() const;
/// Determine if the target supports unaligned memory accesses.
- bool allowsMisalignedMemoryAccesses(LLVMContext &Context,
- unsigned BitWidth, unsigned AddressSpace = 0,
+ bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
+ unsigned AddressSpace = 0,
unsigned Alignment = 1,
bool *Fast = nullptr) const;
@@ -749,15 +775,15 @@ public:
/// Return the expected cost of materializing for the given integer
/// immediate of the specified type.
- int getIntImmCost(const APInt &Imm, Type *Ty) const;
+ int getIntImmCost(const APInt &Imm, Type *Ty, TargetCostKind CostKind) const;
/// Return the expected cost of materialization for the given integer
/// immediate of the specified type for a given instruction. The cost can be
/// zero if the immediate can be folded into the specified instruction.
int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) const;
+ Type *Ty, TargetCostKind CostKind) const;
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
- Type *Ty) const;
+ Type *Ty, TargetCostKind CostKind) const;
/// Return the expected cost for the given integer when optimising
/// for size. This is different than the other integer immediate cost
@@ -775,20 +801,50 @@ public:
/// The various kinds of shuffle patterns for vector queries.
enum ShuffleKind {
- SK_Broadcast, ///< Broadcast element 0 to all other elements.
- SK_Reverse, ///< Reverse the order of the vector.
- SK_Select, ///< Selects elements from the corresponding lane of
- ///< either source operand. This is equivalent to a
- ///< vector select with a constant condition operand.
- SK_Transpose, ///< Transpose two vectors.
- SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
- SK_ExtractSubvector,///< ExtractSubvector Index indicates start offset.
- SK_PermuteTwoSrc, ///< Merge elements from two source vectors into one
- ///< with any shuffle mask.
- SK_PermuteSingleSrc ///< Shuffle elements of single source vector with any
- ///< shuffle mask.
+ SK_Broadcast, ///< Broadcast element 0 to all other elements.
+ SK_Reverse, ///< Reverse the order of the vector.
+ SK_Select, ///< Selects elements from the corresponding lane of
+ ///< either source operand. This is equivalent to a
+ ///< vector select with a constant condition operand.
+ SK_Transpose, ///< Transpose two vectors.
+ SK_InsertSubvector, ///< InsertSubvector. Index indicates start offset.
+ SK_ExtractSubvector, ///< ExtractSubvector Index indicates start offset.
+ SK_PermuteTwoSrc, ///< Merge elements from two source vectors into one
+ ///< with any shuffle mask.
+ SK_PermuteSingleSrc ///< Shuffle elements of single source vector with any
+ ///< shuffle mask.
};
+ /// Kind of the reduction data.
+ enum ReductionKind {
+ RK_None, /// Not a reduction.
+ RK_Arithmetic, /// Binary reduction data.
+ RK_MinMax, /// Min/max reduction data.
+ RK_UnsignedMinMax, /// Unsigned min/max reduction data.
+ };
+
+ /// Contains opcode + LHS/RHS parts of the reduction operations.
+ struct ReductionData {
+ ReductionData() = delete;
+ ReductionData(ReductionKind Kind, unsigned Opcode, Value *LHS, Value *RHS)
+ : Opcode(Opcode), LHS(LHS), RHS(RHS), Kind(Kind) {
+ assert(Kind != RK_None && "expected binary or min/max reduction only.");
+ }
+ unsigned Opcode = 0;
+ Value *LHS = nullptr;
+ Value *RHS = nullptr;
+ ReductionKind Kind = RK_None;
+ bool hasSameData(ReductionData &RD) const {
+ return Kind == RD.Kind && Opcode == RD.Opcode;
+ }
+ };
+
+ static ReductionKind matchPairwiseReduction(
+ const ExtractElementInst *ReduxRoot, unsigned &Opcode, VectorType *&Ty);
+
+ static ReductionKind matchVectorSplittingReduction(
+ const ExtractElementInst *ReduxRoot, unsigned &Opcode, VectorType *&Ty);
+
/// Additional information about an operand's possible values.
enum OperandValueKind {
OK_AnyValue, // Operand can have any value.
@@ -804,19 +860,20 @@ public:
unsigned getNumberOfRegisters(unsigned ClassID) const;
/// \return the target-provided register class ID for the provided type,
- /// accounting for type promotion and other type-legalization techniques that the target might apply.
- /// However, it specifically does not account for the scalarization or splitting of vector types.
- /// Should a vector type require scalarization or splitting into multiple underlying vector registers,
- /// that type should be mapped to a register class containing no registers.
- /// Specifically, this is designed to provide a simple, high-level view of the register allocation
- /// later performed by the backend. These register classes don't necessarily map onto the
- /// register classes used by the backend.
+ /// accounting for type promotion and other type-legalization techniques that
+ /// the target might apply. However, it specifically does not account for the
+ /// scalarization or splitting of vector types. Should a vector type require
+ /// scalarization or splitting into multiple underlying vector registers, that
+ /// type should be mapped to a register class containing no registers.
+ /// Specifically, this is designed to provide a simple, high-level view of the
+ /// register allocation later performed by the backend. These register classes
+ /// don't necessarily map onto the register classes used by the backend.
/// FIXME: It's not currently possible to determine how many registers
/// are used by the provided type.
unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const;
/// \return the target-provided register class name
- const char* getRegisterClassName(unsigned ClassID) const;
+ const char *getRegisterClassName(unsigned ClassID) const;
/// \return The width of the largest scalar or vector register type.
unsigned getRegisterBitWidth(bool Vector) const;
@@ -848,8 +905,8 @@ public:
/// The possible cache levels
enum class CacheLevel {
- L1D, // The L1 data cache
- L2D, // The L2 data cache
+ L1D, // The L1 data cache
+ L2D, // The L2 data cache
// We currently do not model L3 caches, as their sizes differ widely between
// microarchitectures. Also, we currently do not have a use for L3 cache
@@ -857,34 +914,52 @@ public:
};
/// \return The size of the cache level in bytes, if available.
- llvm::Optional<unsigned> getCacheSize(CacheLevel Level) const;
+ Optional<unsigned> getCacheSize(CacheLevel Level) const;
/// \return The associativity of the cache level, if available.
- llvm::Optional<unsigned> getCacheAssociativity(CacheLevel Level) const;
+ Optional<unsigned> getCacheAssociativity(CacheLevel Level) const;
/// \return How much before a load we should place the prefetch
/// instruction. This is currently measured in number of
/// instructions.
unsigned getPrefetchDistance() const;
- /// \return Some HW prefetchers can handle accesses up to a certain
- /// constant stride. This is the minimum stride in bytes where it
- /// makes sense to start adding SW prefetches. The default is 1,
- /// i.e. prefetch with any stride.
- unsigned getMinPrefetchStride() const;
+ /// Some HW prefetchers can handle accesses up to a certain constant stride.
+ /// Sometimes prefetching is beneficial even below the HW prefetcher limit,
+ /// and the arguments provided are meant to serve as a basis for deciding this
+ /// for a particular loop.
+ ///
+ /// \param NumMemAccesses Number of memory accesses in the loop.
+ /// \param NumStridedMemAccesses Number of the memory accesses that
+ /// ScalarEvolution could find a known stride
+ /// for.
+ /// \param NumPrefetches Number of software prefetches that will be
+ /// emitted as determined by the addresses
+ /// involved and the cache line size.
+ /// \param HasCall True if the loop contains a call.
+ ///
+ /// \return This is the minimum stride in bytes where it makes sense to start
+ /// adding SW prefetches. The default is 1, i.e. prefetch with any
+ /// stride.
+ unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches, bool HasCall) const;
/// \return The maximum number of iterations to prefetch ahead. If
/// the required number of iterations is more than this number, no
/// prefetching is performed.
unsigned getMaxPrefetchIterationsAhead() const;
+ /// \return True if prefetching should also be done for writes.
+ bool enableWritePrefetching() const;
+
/// \return The maximum interleave factor that any transform should try to
/// perform for this target. This number depends on the level of parallelism
/// and the number of execution units in the CPU.
unsigned getMaxInterleaveFactor(unsigned VF) const;
/// Collect properties of V used in cost analysis, e.g. OP_PowerOf2.
- static OperandValueKind getOperandInfo(Value *V,
+ static OperandValueKind getOperandInfo(const Value *V,
OperandValueProperties &OpProps);
/// This is an approximation of reciprocal throughput of a math/logic op.
@@ -904,7 +979,9 @@ public:
/// \p CxtI is the optional original context instruction, if one exists, to
/// provide even more information.
int getArithmeticInstrCost(
- unsigned Opcode, Type *Ty, OperandValueKind Opd1Info = OK_AnyValue,
+ unsigned Opcode, Type *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
+ OperandValueKind Opd1Info = OK_AnyValue,
OperandValueKind Opd2Info = OK_AnyValue,
OperandValueProperties Opd1PropInfo = OP_None,
OperandValueProperties Opd2PropInfo = OP_None,
@@ -916,13 +993,14 @@ public:
/// extraction shuffle kinds to show the insert/extract point and the type of
/// the subvector being inserted/extracted.
/// NOTE: For subvector extractions Tp represents the source type.
- int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0,
- Type *SubTp = nullptr) const;
+ int getShuffleCost(ShuffleKind Kind, VectorType *Tp, int Index = 0,
+ VectorType *SubTp = nullptr) const;
/// \return The expected cost of cast instructions, such as bitcast, trunc,
/// zext, etc. If there is an existing instruction that holds Opcode, it
/// may be passed in the 'I' parameter.
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency,
const Instruction *I = nullptr) const;
/// \return The expected cost of a sign- or zero-extended vector extract. Use
@@ -932,26 +1010,30 @@ public:
/// \return The expected cost of control-flow related instructions such as
/// Phi, Ret, Br.
- int getCFInstrCost(unsigned Opcode) const;
+ int getCFInstrCost(unsigned Opcode,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const;
/// \returns The expected cost of compare and select instructions. If there
/// is an existing instruction that holds Opcode, it may be passed in the
/// 'I' parameter.
- int getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy = nullptr, const Instruction *I = nullptr) const;
+ int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy = nullptr,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
+ const Instruction *I = nullptr) const;
/// \return The expected cost of vector Insert and Extract.
/// Use -1 to indicate that there is no information on the index value.
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index = -1) const;
/// \return The cost of Load and Store instructions.
- int getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
+ int getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
unsigned AddressSpace,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
const Instruction *I = nullptr) const;
/// \return The cost of masked Load and Store instructions.
- int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) const;
+ int getMaskedMemoryOpCost(
+ unsigned Opcode, Type *Src, Align Alignment, unsigned AddressSpace,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
/// \return The cost of Gather or Scatter operation
/// \p Opcode - is a type of memory access Load or Store
@@ -960,8 +1042,12 @@ public:
/// \p VariableMask - true when the memory access is predicated with a mask
/// that is not a compile-time constant
/// \p Alignment - alignment of single element
- int getGatherScatterOpCost(unsigned Opcode, Type *DataTy, Value *Ptr,
- bool VariableMask, unsigned Alignment) const;
+ /// \p I - the optional original context instruction, if one exists, e.g. the
+ /// load/store to transform or the call to the gather/scatter intrinsic
+ int getGatherScatterOpCost(
+ unsigned Opcode, Type *DataTy, const Value *Ptr, bool VariableMask,
+ Align Alignment, TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
+ const Instruction *I = nullptr) const;
/// \return The cost of the interleaved memory operation.
/// \p Opcode is the memory operation code
@@ -973,11 +1059,11 @@ public:
/// \p AddressSpace is address space of the pointer.
/// \p UseMaskForCond indicates if the memory access is predicated.
/// \p UseMaskForGaps indicates if gaps should be masked.
- int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor,
- ArrayRef<unsigned> Indices, unsigned Alignment,
- unsigned AddressSpace,
- bool UseMaskForCond = false,
- bool UseMaskForGaps = false) const;
+ int getInterleavedMemoryOpCost(
+ unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
+ Align Alignment, unsigned AddressSpace,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
+ bool UseMaskForCond = false, bool UseMaskForGaps = false) const;
/// Calculate the cost of performing a vector reduction.
///
@@ -992,27 +1078,23 @@ public:
/// Split:
/// (v0, v1, v2, v3)
/// ((v0+v2), (v1+v3), undef, undef)
- int getArithmeticReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) const;
- int getMinMaxReductionCost(Type *Ty, Type *CondTy, bool IsPairwiseForm,
- bool IsUnsigned) const;
+ int getArithmeticReductionCost(
+ unsigned Opcode, VectorType *Ty, bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
+
+ int getMinMaxReductionCost(
+ VectorType *Ty, VectorType *CondTy, bool IsPairwiseForm, bool IsUnsigned,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput) const;
/// \returns The cost of Intrinsic instructions. Analyses the real arguments.
/// Three cases are handled: 1. scalar instruction 2. vector instruction
- /// 3. scalar instruction which is to be vectorized with VF.
- int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF,
- unsigned VF = 1) const;
-
- /// \returns The cost of Intrinsic instructions. Types analysis only.
- /// If ScalarizationCostPassed is UINT_MAX, the cost of scalarizing the
- /// arguments and the return value will be computed based on types.
- int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys, FastMathFlags FMF,
- unsigned ScalarizationCostPassed = UINT_MAX) const;
+ /// 3. scalar instruction which is to be vectorized.
+ int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) const;
/// \returns The cost of Call instructions.
- int getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) const;
+ int getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) const;
/// \returns The number of pieces into which the provided type must be
/// split during legalization. Zero is returned when the answer is unknown.
@@ -1054,6 +1136,7 @@ public:
/// \returns The type to use in a loop expansion of a memcpy call.
Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAddrSpace, unsigned DestAddrSpace,
unsigned SrcAlign, unsigned DestAlign) const;
/// \param[out] OpsOut The operand types to copy RemainingBytes of memory.
@@ -1062,11 +1145,10 @@ public:
/// Calculates the operand types to use when copying \p RemainingBytes of
/// memory, where source and destination alignments are \p SrcAlign and
/// \p DestAlign respectively.
- void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut,
- LLVMContext &Context,
- unsigned RemainingBytes,
- unsigned SrcAlign,
- unsigned DestAlign) const;
+ void getMemcpyLoopResidualLoweringType(
+ SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
+ unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
+ unsigned SrcAlign, unsigned DestAlign) const;
/// \returns True if the two functions have compatible attributes for inlining
/// purposes.
@@ -1083,11 +1165,11 @@ public:
/// The type of load/store indexing.
enum MemIndexedMode {
- MIM_Unindexed, ///< No indexing.
- MIM_PreInc, ///< Pre-incrementing.
- MIM_PreDec, ///< Pre-decrementing.
- MIM_PostInc, ///< Post-incrementing.
- MIM_PostDec ///< Post-decrementing.
+ MIM_Unindexed, ///< No indexing.
+ MIM_PreInc, ///< Pre-incrementing.
+ MIM_PreDec, ///< Pre-decrementing.
+ MIM_PostInc, ///< Post-incrementing.
+ MIM_PostDec ///< Post-decrementing.
};
/// \returns True if the specified indexed load for the given type is legal.
@@ -1107,13 +1189,11 @@ public:
bool isLegalToVectorizeStore(StoreInst *SI) const;
/// \returns True if it is legal to vectorize the given load chain.
- bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const;
/// \returns True if it is legal to vectorize the given store chain.
- bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const;
/// \returns The new vector factor value if the target doesn't support \p
@@ -1149,6 +1229,15 @@ public:
/// to a stack reload.
unsigned getGISelRematGlobalCost() const;
+ /// \name Vector Predication Information
+ /// @{
+ /// Whether the target supports the %evl parameter of VP intrinsic efficiently
+ /// in hardware. (see LLVM Language Reference - "Vector Predication
+ /// Intrinsics") Use of %evl is discouraged when that is not the case.
+ bool hasActiveVectorLength() const;
+
+ /// @}
+
/// @}
private:
@@ -1175,70 +1264,64 @@ class TargetTransformInfo::Concept {
public:
virtual ~Concept() = 0;
virtual const DataLayout &getDataLayout() const = 0;
- virtual int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0;
virtual int getGEPCost(Type *PointeeType, const Value *Ptr,
- ArrayRef<const Value *> Operands) = 0;
- virtual int getExtCost(const Instruction *I, const Value *Src) = 0;
- virtual int getCallCost(FunctionType *FTy, int NumArgs, const User *U) = 0;
- virtual int getCallCost(const Function *F, int NumArgs, const User *U) = 0;
- virtual int getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments, const User *U) = 0;
+ ArrayRef<const Value *> Operands,
+ TTI::TargetCostKind CostKind) = 0;
virtual unsigned getInliningThresholdMultiplier() = 0;
virtual int getInlinerVectorBonusPercent() = 0;
- virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys, const User *U) = 0;
- virtual int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments,
- const User *U) = 0;
virtual int getMemcpyCost(const Instruction *I) = 0;
- virtual unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
- unsigned &JTSize,
- ProfileSummaryInfo *PSI,
- BlockFrequencyInfo *BFI) = 0;
- virtual int
- getUserCost(const User *U, ArrayRef<const Value *> Operands) = 0;
+ virtual unsigned
+ getEstimatedNumberOfCaseClusters(const SwitchInst &SI, unsigned &JTSize,
+ ProfileSummaryInfo *PSI,
+ BlockFrequencyInfo *BFI) = 0;
+ virtual int getUserCost(const User *U, ArrayRef<const Value *> Operands,
+ TargetCostKind CostKind) = 0;
virtual bool hasBranchDivergence() = 0;
+ virtual bool useGPUDivergenceAnalysis() = 0;
virtual bool isSourceOfDivergence(const Value *V) = 0;
virtual bool isAlwaysUniform(const Value *V) = 0;
virtual unsigned getFlatAddressSpace() = 0;
virtual bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const = 0;
- virtual bool rewriteIntrinsicWithAddressSpace(
- IntrinsicInst *II, Value *OldV, Value *NewV) const = 0;
+ virtual bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const = 0;
+ virtual Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
+ Value *OldV,
+ Value *NewV) const = 0;
virtual bool isLoweredToCall(const Function *F) = 0;
virtual void getUnrollingPreferences(Loop *L, ScalarEvolution &,
UnrollingPreferences &UP) = 0;
+ virtual void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ PeelingPreferences &PP) = 0;
virtual bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC,
TargetLibraryInfo *LibInfo,
HardwareLoopInfo &HWLoopInfo) = 0;
- virtual bool preferPredicateOverEpilogue(Loop *L, LoopInfo *LI,
- ScalarEvolution &SE,
- AssumptionCache &AC,
- TargetLibraryInfo *TLI,
- DominatorTree *DT,
- const LoopAccessInfo *LAI) = 0;
+ virtual bool
+ preferPredicateOverEpilogue(Loop *L, LoopInfo *LI, ScalarEvolution &SE,
+ AssumptionCache &AC, TargetLibraryInfo *TLI,
+ DominatorTree *DT, const LoopAccessInfo *LAI) = 0;
+ virtual bool emitGetActiveLaneMask() = 0;
virtual bool isLegalAddImmediate(int64_t Imm) = 0;
virtual bool isLegalICmpImmediate(int64_t Imm) = 0;
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale,
- unsigned AddrSpace,
+ int64_t Scale, unsigned AddrSpace,
Instruction *I) = 0;
virtual bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) = 0;
+ virtual bool isProfitableLSRChainElement(Instruction *I) = 0;
virtual bool canMacroFuseCmp() = 0;
virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo) = 0;
virtual bool shouldFavorPostInc() const = 0;
virtual bool shouldFavorBackedgeIndex(const Loop *L) const = 0;
- virtual bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) = 0;
- virtual bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) = 0;
+ virtual bool isLegalMaskedStore(Type *DataType, Align Alignment) = 0;
+ virtual bool isLegalMaskedLoad(Type *DataType, Align Alignment) = 0;
virtual bool isLegalNTStore(Type *DataType, Align Alignment) = 0;
virtual bool isLegalNTLoad(Type *DataType, Align Alignment) = 0;
- virtual bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) = 0;
- virtual bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) = 0;
+ virtual bool isLegalMaskedScatter(Type *DataType, Align Alignment) = 0;
+ virtual bool isLegalMaskedGather(Type *DataType, Align Alignment) = 0;
virtual bool isLegalMaskedCompressStore(Type *DataType) = 0;
virtual bool isLegalMaskedExpandLoad(Type *DataType) = 0;
virtual bool hasDivRemOp(Type *DataType, bool IsSigned) = 0;
@@ -1255,10 +1338,12 @@ public:
virtual bool shouldBuildLookupTables() = 0;
virtual bool shouldBuildLookupTablesForConstant(Constant *C) = 0;
virtual bool useColdCCForColdCall(Function &F) = 0;
+ virtual unsigned getScalarizationOverhead(VectorType *Ty,
+ const APInt &DemandedElts,
+ bool Insert, bool Extract) = 0;
virtual unsigned
- getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) = 0;
- virtual unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
- unsigned VF) = 0;
+ getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
+ unsigned VF) = 0;
virtual bool supportsEfficientVectorElementLoadStore() = 0;
virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0;
virtual MemCmpExpansionOptions
@@ -1275,16 +1360,19 @@ public:
virtual bool haveFastSqrt(Type *Ty) = 0;
virtual bool isFCmpOrdCheaperThanFCmpZero(Type *Ty) = 0;
virtual int getFPOpCost(Type *Ty) = 0;
- virtual int getIntImmCodeSizeCost(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) = 0;
- virtual int getIntImmCost(const APInt &Imm, Type *Ty) = 0;
+ virtual int getIntImmCodeSizeCost(unsigned Opc, unsigned Idx,
+ const APInt &Imm, Type *Ty) = 0;
+ virtual int getIntImmCost(const APInt &Imm, Type *Ty,
+ TargetCostKind CostKind) = 0;
virtual int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) = 0;
+ Type *Ty, TargetCostKind CostKind) = 0;
virtual int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
- const APInt &Imm, Type *Ty) = 0;
+ const APInt &Imm, Type *Ty,
+ TargetCostKind CostKind) = 0;
virtual unsigned getNumberOfRegisters(unsigned ClassID) const = 0;
- virtual unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const = 0;
- virtual const char* getRegisterClassName(unsigned ClassID) const = 0;
+ virtual unsigned getRegisterClassForType(bool Vector,
+ Type *Ty = nullptr) const = 0;
+ virtual const char *getRegisterClassName(unsigned ClassID) const = 0;
virtual unsigned getRegisterBitWidth(bool Vector) const = 0;
virtual unsigned getMinVectorRegisterBitWidth() = 0;
virtual bool shouldMaximizeVectorBandwidth(bool OptSize) const = 0;
@@ -1292,8 +1380,8 @@ public:
virtual bool shouldConsiderAddressTypePromotion(
const Instruction &I, bool &AllowPromotionWithoutCommonHeader) = 0;
virtual unsigned getCacheLineSize() const = 0;
- virtual llvm::Optional<unsigned> getCacheSize(CacheLevel Level) const = 0;
- virtual llvm::Optional<unsigned> getCacheAssociativity(CacheLevel Level) const = 0;
+ virtual Optional<unsigned> getCacheSize(CacheLevel Level) const = 0;
+ virtual Optional<unsigned> getCacheAssociativity(CacheLevel Level) const = 0;
/// \return How much before a load we should place the prefetch
/// instruction. This is currently measured in number of
@@ -1303,57 +1391,72 @@ public:
/// \return Some HW prefetchers can handle accesses up to a certain
/// constant stride. This is the minimum stride in bytes where it
/// makes sense to start adding SW prefetches. The default is 1,
- /// i.e. prefetch with any stride.
- virtual unsigned getMinPrefetchStride() const = 0;
+ /// i.e. prefetch with any stride. Sometimes prefetching is beneficial
+ /// even below the HW prefetcher limit, and the arguments provided are
+ /// meant to serve as a basis for deciding this for a particular loop.
+ virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches,
+ bool HasCall) const = 0;
/// \return The maximum number of iterations to prefetch ahead. If
/// the required number of iterations is more than this number, no
/// prefetching is performed.
virtual unsigned getMaxPrefetchIterationsAhead() const = 0;
+ /// \return True if prefetching should also be done for writes.
+ virtual bool enableWritePrefetching() const = 0;
+
virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0;
virtual unsigned getArithmeticInstrCost(
- unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
+ unsigned Opcode, Type *Ty,
+ TTI::TargetCostKind CostKind,
+ OperandValueKind Opd1Info,
OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo,
OperandValueProperties Opd2PropInfo, ArrayRef<const Value *> Args,
const Instruction *CxtI = nullptr) = 0;
- virtual int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
- Type *SubTp) = 0;
+ virtual int getShuffleCost(ShuffleKind Kind, VectorType *Tp, int Index,
+ VectorType *SubTp) = 0;
virtual int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ TTI::TargetCostKind CostKind,
const Instruction *I) = 0;
virtual int getExtractWithExtendCost(unsigned Opcode, Type *Dst,
VectorType *VecTy, unsigned Index) = 0;
- virtual int getCFInstrCost(unsigned Opcode) = 0;
- virtual int getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
- Type *CondTy, const Instruction *I) = 0;
+ virtual int getCFInstrCost(unsigned Opcode,
+ TTI::TargetCostKind CostKind) = 0;
+ virtual int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ TTI::TargetCostKind CostKind,
+ const Instruction *I) = 0;
virtual int getVectorInstrCost(unsigned Opcode, Type *Val,
unsigned Index) = 0;
- virtual int getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
- unsigned AddressSpace, const Instruction *I) = 0;
- virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src,
- unsigned Alignment,
- unsigned AddressSpace) = 0;
+ virtual int getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind,
+ const Instruction *I) = 0;
+ virtual int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind) = 0;
virtual int getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
- Value *Ptr, bool VariableMask,
- unsigned Alignment) = 0;
- virtual int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
- unsigned Factor,
- ArrayRef<unsigned> Indices,
- unsigned Alignment,
- unsigned AddressSpace,
- bool UseMaskForCond = false,
- bool UseMaskForGaps = false) = 0;
- virtual int getArithmeticReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) = 0;
- virtual int getMinMaxReductionCost(Type *Ty, Type *CondTy,
- bool IsPairwiseForm, bool IsUnsigned) = 0;
- virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys, FastMathFlags FMF,
- unsigned ScalarizationCostPassed) = 0;
- virtual int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) = 0;
+ const Value *Ptr, bool VariableMask,
+ Align Alignment,
+ TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr) = 0;
+
+ virtual int getInterleavedMemoryOpCost(
+ unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
+ Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
+ bool UseMaskForCond = false, bool UseMaskForGaps = false) = 0;
+ virtual int getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
+ bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind) = 0;
+ virtual int getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
+ bool IsPairwiseForm, bool IsUnsigned,
+ TTI::TargetCostKind CostKind) = 0;
+ virtual int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) = 0;
virtual int getCallInstrCost(Function *F, Type *RetTy,
- ArrayRef<Type *> Tys) = 0;
+ ArrayRef<Type *> Tys,
+ TTI::TargetCostKind CostKind) = 0;
virtual unsigned getNumberOfParts(Type *Tp) = 0;
virtual int getAddressComputationCost(Type *Ty, ScalarEvolution *SE,
const SCEV *Ptr) = 0;
@@ -1364,26 +1467,29 @@ public:
virtual Value *getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
Type *ExpectedType) = 0;
virtual Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAddrSpace,
+ unsigned DestAddrSpace,
unsigned SrcAlign,
unsigned DestAlign) const = 0;
virtual void getMemcpyLoopResidualLoweringType(
SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
- unsigned RemainingBytes, unsigned SrcAlign, unsigned DestAlign) const = 0;
+ unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
+ unsigned SrcAlign, unsigned DestAlign) const = 0;
virtual bool areInlineCompatible(const Function *Caller,
const Function *Callee) const = 0;
virtual bool
areFunctionArgsABICompatible(const Function *Caller, const Function *Callee,
SmallPtrSetImpl<Argument *> &Args) const = 0;
virtual bool isIndexedLoadLegal(MemIndexedMode Mode, Type *Ty) const = 0;
- virtual bool isIndexedStoreLegal(MemIndexedMode Mode,Type *Ty) const = 0;
+ virtual bool isIndexedStoreLegal(MemIndexedMode Mode, Type *Ty) const = 0;
virtual unsigned getLoadStoreVecRegBitWidth(unsigned AddrSpace) const = 0;
virtual bool isLegalToVectorizeLoad(LoadInst *LI) const = 0;
virtual bool isLegalToVectorizeStore(StoreInst *SI) const = 0;
virtual bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ Align Alignment,
unsigned AddrSpace) const = 0;
virtual bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ Align Alignment,
unsigned AddrSpace) const = 0;
virtual unsigned getLoadVectorFactor(unsigned VF, unsigned LoadSize,
unsigned ChainSizeInBytes,
@@ -1395,6 +1501,7 @@ public:
ReductionFlags) const = 0;
virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0;
virtual unsigned getGISelRematGlobalCost() const = 0;
+ virtual bool hasActiveVectorLength() const = 0;
virtual int getInstructionLatency(const Instruction *I) = 0;
};
@@ -1410,48 +1517,28 @@ public:
return Impl.getDataLayout();
}
- int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override {
- return Impl.getOperationCost(Opcode, Ty, OpTy);
- }
int getGEPCost(Type *PointeeType, const Value *Ptr,
- ArrayRef<const Value *> Operands) override {
+ ArrayRef<const Value *> Operands,
+ enum TargetTransformInfo::TargetCostKind CostKind) override {
return Impl.getGEPCost(PointeeType, Ptr, Operands);
}
- int getExtCost(const Instruction *I, const Value *Src) override {
- return Impl.getExtCost(I, Src);
- }
- int getCallCost(FunctionType *FTy, int NumArgs, const User *U) override {
- return Impl.getCallCost(FTy, NumArgs, U);
- }
- int getCallCost(const Function *F, int NumArgs, const User *U) override {
- return Impl.getCallCost(F, NumArgs, U);
- }
- int getCallCost(const Function *F,
- ArrayRef<const Value *> Arguments, const User *U) override {
- return Impl.getCallCost(F, Arguments, U);
- }
unsigned getInliningThresholdMultiplier() override {
return Impl.getInliningThresholdMultiplier();
}
int getInlinerVectorBonusPercent() override {
return Impl.getInlinerVectorBonusPercent();
}
- int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys, const User *U = nullptr) override {
- return Impl.getIntrinsicCost(IID, RetTy, ParamTys, U);
- }
- int getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments,
- const User *U = nullptr) override {
- return Impl.getIntrinsicCost(IID, RetTy, Arguments, U);
- }
int getMemcpyCost(const Instruction *I) override {
return Impl.getMemcpyCost(I);
}
- int getUserCost(const User *U, ArrayRef<const Value *> Operands) override {
- return Impl.getUserCost(U, Operands);
+ int getUserCost(const User *U, ArrayRef<const Value *> Operands,
+ TargetCostKind CostKind) override {
+ return Impl.getUserCost(U, Operands, CostKind);
}
bool hasBranchDivergence() override { return Impl.hasBranchDivergence(); }
+ bool useGPUDivergenceAnalysis() override {
+ return Impl.useGPUDivergenceAnalysis();
+ }
bool isSourceOfDivergence(const Value *V) override {
return Impl.isSourceOfDivergence(V);
}
@@ -1460,17 +1547,19 @@ public:
return Impl.isAlwaysUniform(V);
}
- unsigned getFlatAddressSpace() override {
- return Impl.getFlatAddressSpace();
- }
+ unsigned getFlatAddressSpace() override { return Impl.getFlatAddressSpace(); }
bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const override {
return Impl.collectFlatAddressOperands(OpIndexes, IID);
}
- bool rewriteIntrinsicWithAddressSpace(
- IntrinsicInst *II, Value *OldV, Value *NewV) const override {
+ bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const override {
+ return Impl.isNoopAddrSpaceCast(FromAS, ToAS);
+ }
+
+ Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
+ Value *NewV) const override {
return Impl.rewriteIntrinsicWithAddressSpace(II, OldV, NewV);
}
@@ -1481,9 +1570,12 @@ public:
UnrollingPreferences &UP) override {
return Impl.getUnrollingPreferences(L, SE, UP);
}
+ void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ PeelingPreferences &PP) override {
+ return Impl.getPeelingPreferences(L, SE, PP);
+ }
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
- AssumptionCache &AC,
- TargetLibraryInfo *LibInfo,
+ AssumptionCache &AC, TargetLibraryInfo *LibInfo,
HardwareLoopInfo &HWLoopInfo) override {
return Impl.isHardwareLoopProfitable(L, SE, AC, LibInfo, HWLoopInfo);
}
@@ -1493,6 +1585,9 @@ public:
const LoopAccessInfo *LAI) override {
return Impl.preferPredicateOverEpilogue(L, LI, SE, AC, TLI, DT, LAI);
}
+ bool emitGetActiveLaneMask() override {
+ return Impl.emitGetActiveLaneMask();
+ }
bool isLegalAddImmediate(int64_t Imm) override {
return Impl.isLegalAddImmediate(Imm);
}
@@ -1500,35 +1595,32 @@ public:
return Impl.isLegalICmpImmediate(Imm);
}
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale,
- unsigned AddrSpace,
+ bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
Instruction *I) override {
- return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale, AddrSpace, I);
+ return Impl.isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
+ AddrSpace, I);
}
bool isLSRCostLess(TargetTransformInfo::LSRCost &C1,
TargetTransformInfo::LSRCost &C2) override {
return Impl.isLSRCostLess(C1, C2);
}
- bool canMacroFuseCmp() override {
- return Impl.canMacroFuseCmp();
+ bool isProfitableLSRChainElement(Instruction *I) override {
+ return Impl.isProfitableLSRChainElement(I);
}
- bool canSaveCmp(Loop *L, BranchInst **BI,
- ScalarEvolution *SE,
- LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC,
- TargetLibraryInfo *LibInfo) override {
+ bool canMacroFuseCmp() override { return Impl.canMacroFuseCmp(); }
+ bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
+ DominatorTree *DT, AssumptionCache *AC,
+ TargetLibraryInfo *LibInfo) override {
return Impl.canSaveCmp(L, BI, SE, LI, DT, AC, LibInfo);
}
- bool shouldFavorPostInc() const override {
- return Impl.shouldFavorPostInc();
- }
+ bool shouldFavorPostInc() const override { return Impl.shouldFavorPostInc(); }
bool shouldFavorBackedgeIndex(const Loop *L) const override {
return Impl.shouldFavorBackedgeIndex(L);
}
- bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) override {
+ bool isLegalMaskedStore(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedStore(DataType, Alignment);
}
- bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) override {
+ bool isLegalMaskedLoad(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedLoad(DataType, Alignment);
}
bool isLegalNTStore(Type *DataType, Align Alignment) override {
@@ -1537,10 +1629,10 @@ public:
bool isLegalNTLoad(Type *DataType, Align Alignment) override {
return Impl.isLegalNTLoad(DataType, Alignment);
}
- bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) override {
+ bool isLegalMaskedScatter(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedScatter(DataType, Alignment);
}
- bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) override {
+ bool isLegalMaskedGather(Type *DataType, Align Alignment) override {
return Impl.isLegalMaskedGather(DataType, Alignment);
}
bool isLegalMaskedCompressStore(Type *DataType) override {
@@ -1561,12 +1653,10 @@ public:
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale,
unsigned AddrSpace) override {
- return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale, AddrSpace);
- }
- bool LSRWithInstrQueries() override {
- return Impl.LSRWithInstrQueries();
+ return Impl.getScalingFactorCost(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
+ AddrSpace);
}
+ bool LSRWithInstrQueries() override { return Impl.LSRWithInstrQueries(); }
bool isTruncateFree(Type *Ty1, Type *Ty2) override {
return Impl.isTruncateFree(Ty1, Ty2);
}
@@ -1585,9 +1675,9 @@ public:
return Impl.useColdCCForColdCall(F);
}
- unsigned getScalarizationOverhead(Type *Ty, bool Insert,
- bool Extract) override {
- return Impl.getScalarizationOverhead(Ty, Insert, Extract);
+ unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
+ bool Insert, bool Extract) override {
+ return Impl.getScalarizationOverhead(Ty, DemandedElts, Insert, Extract);
}
unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
unsigned VF) override {
@@ -1614,9 +1704,9 @@ public:
bool isFPVectorizationPotentiallyUnsafe() override {
return Impl.isFPVectorizationPotentiallyUnsafe();
}
- bool allowsMisalignedMemoryAccesses(LLVMContext &Context,
- unsigned BitWidth, unsigned AddressSpace,
- unsigned Alignment, bool *Fast) override {
+ bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
+ unsigned AddressSpace, unsigned Alignment,
+ bool *Fast) override {
return Impl.allowsMisalignedMemoryAccesses(Context, BitWidth, AddressSpace,
Alignment, Fast);
}
@@ -1635,24 +1725,26 @@ public:
Type *Ty) override {
return Impl.getIntImmCodeSizeCost(Opc, Idx, Imm, Ty);
}
- int getIntImmCost(const APInt &Imm, Type *Ty) override {
- return Impl.getIntImmCost(Imm, Ty);
+ int getIntImmCost(const APInt &Imm, Type *Ty,
+ TargetCostKind CostKind) override {
+ return Impl.getIntImmCost(Imm, Ty, CostKind);
}
int getIntImmCostInst(unsigned Opc, unsigned Idx, const APInt &Imm,
- Type *Ty) override {
- return Impl.getIntImmCostInst(Opc, Idx, Imm, Ty);
+ Type *Ty, TargetCostKind CostKind) override {
+ return Impl.getIntImmCostInst(Opc, Idx, Imm, Ty, CostKind);
}
int getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
- Type *Ty) override {
- return Impl.getIntImmCostIntrin(IID, Idx, Imm, Ty);
+ Type *Ty, TargetCostKind CostKind) override {
+ return Impl.getIntImmCostIntrin(IID, Idx, Imm, Ty, CostKind);
}
unsigned getNumberOfRegisters(unsigned ClassID) const override {
return Impl.getNumberOfRegisters(ClassID);
}
- unsigned getRegisterClassForType(bool Vector, Type *Ty = nullptr) const override {
+ unsigned getRegisterClassForType(bool Vector,
+ Type *Ty = nullptr) const override {
return Impl.getRegisterClassForType(Vector, Ty);
}
- const char* getRegisterClassName(unsigned ClassID) const override {
+ const char *getRegisterClassName(unsigned ClassID) const override {
return Impl.getRegisterClassName(ClassID);
}
unsigned getRegisterBitWidth(bool Vector) const override {
@@ -1672,13 +1764,11 @@ public:
return Impl.shouldConsiderAddressTypePromotion(
I, AllowPromotionWithoutCommonHeader);
}
- unsigned getCacheLineSize() const override {
- return Impl.getCacheLineSize();
- }
- llvm::Optional<unsigned> getCacheSize(CacheLevel Level) const override {
+ unsigned getCacheLineSize() const override { return Impl.getCacheLineSize(); }
+ Optional<unsigned> getCacheSize(CacheLevel Level) const override {
return Impl.getCacheSize(Level);
}
- llvm::Optional<unsigned> getCacheAssociativity(CacheLevel Level) const override {
+ Optional<unsigned> getCacheAssociativity(CacheLevel Level) const override {
return Impl.getCacheAssociativity(Level);
}
@@ -1691,8 +1781,12 @@ public:
/// Return the minimum stride necessary to trigger software
/// prefetching.
///
- unsigned getMinPrefetchStride() const override {
- return Impl.getMinPrefetchStride();
+ unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches,
+ bool HasCall) const override {
+ return Impl.getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
+ NumPrefetches, HasCall);
}
/// Return the maximum prefetch distance in terms of loop
@@ -1702,6 +1796,11 @@ public:
return Impl.getMaxPrefetchIterationsAhead();
}
+ /// \return True if prefetching should also be done for writes.
+ bool enableWritePrefetching() const override {
+ return Impl.enableWritePrefetching();
+ }
+
unsigned getMaxInterleaveFactor(unsigned VF) override {
return Impl.getMaxInterleaveFactor(VF);
}
@@ -1712,79 +1811,89 @@ public:
return Impl.getEstimatedNumberOfCaseClusters(SI, JTSize, PSI, BFI);
}
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
+ TTI::TargetCostKind CostKind,
OperandValueKind Opd1Info,
OperandValueKind Opd2Info,
OperandValueProperties Opd1PropInfo,
OperandValueProperties Opd2PropInfo,
ArrayRef<const Value *> Args,
const Instruction *CxtI = nullptr) override {
- return Impl.getArithmeticInstrCost(Opcode, Ty, Opd1Info, Opd2Info,
+ return Impl.getArithmeticInstrCost(Opcode, Ty, CostKind, Opd1Info, Opd2Info,
Opd1PropInfo, Opd2PropInfo, Args, CxtI);
}
- int getShuffleCost(ShuffleKind Kind, Type *Tp, int Index,
- Type *SubTp) override {
+ int getShuffleCost(ShuffleKind Kind, VectorType *Tp, int Index,
+ VectorType *SubTp) override {
return Impl.getShuffleCost(Kind, Tp, Index, SubTp);
}
int getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ TTI::TargetCostKind CostKind,
const Instruction *I) override {
- return Impl.getCastInstrCost(Opcode, Dst, Src, I);
+ return Impl.getCastInstrCost(Opcode, Dst, Src, CostKind, I);
}
int getExtractWithExtendCost(unsigned Opcode, Type *Dst, VectorType *VecTy,
unsigned Index) override {
return Impl.getExtractWithExtendCost(Opcode, Dst, VecTy, Index);
}
- int getCFInstrCost(unsigned Opcode) override {
- return Impl.getCFInstrCost(Opcode);
+ int getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) override {
+ return Impl.getCFInstrCost(Opcode, CostKind);
}
int getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
+ TTI::TargetCostKind CostKind,
const Instruction *I) override {
- return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy, I);
+ return Impl.getCmpSelInstrCost(Opcode, ValTy, CondTy, CostKind, I);
}
int getVectorInstrCost(unsigned Opcode, Type *Val, unsigned Index) override {
return Impl.getVectorInstrCost(Opcode, Val, Index);
}
- int getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
- unsigned AddressSpace, const Instruction *I) override {
- return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace, I);
- }
- int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) override {
- return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace);
- }
- int getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
- Value *Ptr, bool VariableMask,
- unsigned Alignment) override {
+ int getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace, TTI::TargetCostKind CostKind,
+ const Instruction *I) override {
+ return Impl.getMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
+ CostKind, I);
+ }
+ int getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind) override {
+ return Impl.getMaskedMemoryOpCost(Opcode, Src, Alignment, AddressSpace,
+ CostKind);
+ }
+ int getGatherScatterOpCost(unsigned Opcode, Type *DataTy, const Value *Ptr,
+ bool VariableMask, Align Alignment,
+ TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr) override {
return Impl.getGatherScatterOpCost(Opcode, DataTy, Ptr, VariableMask,
- Alignment);
+ Alignment, CostKind, I);
}
int getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy, unsigned Factor,
- ArrayRef<unsigned> Indices, unsigned Alignment,
- unsigned AddressSpace, bool UseMaskForCond,
+ ArrayRef<unsigned> Indices, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind,
+ bool UseMaskForCond,
bool UseMaskForGaps) override {
return Impl.getInterleavedMemoryOpCost(Opcode, VecTy, Factor, Indices,
- Alignment, AddressSpace,
+ Alignment, AddressSpace, CostKind,
UseMaskForCond, UseMaskForGaps);
}
- int getArithmeticReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwiseForm) override {
- return Impl.getArithmeticReductionCost(Opcode, Ty, IsPairwiseForm);
+ int getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
+ bool IsPairwiseForm,
+ TTI::TargetCostKind CostKind) override {
+ return Impl.getArithmeticReductionCost(Opcode, Ty, IsPairwiseForm,
+ CostKind);
}
- int getMinMaxReductionCost(Type *Ty, Type *CondTy,
- bool IsPairwiseForm, bool IsUnsigned) override {
- return Impl.getMinMaxReductionCost(Ty, CondTy, IsPairwiseForm, IsUnsigned);
- }
- int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, ArrayRef<Type *> Tys,
- FastMathFlags FMF, unsigned ScalarizationCostPassed) override {
- return Impl.getIntrinsicInstrCost(ID, RetTy, Tys, FMF,
- ScalarizationCostPassed);
+ int getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
+ bool IsPairwiseForm, bool IsUnsigned,
+ TTI::TargetCostKind CostKind) override {
+ return Impl.getMinMaxReductionCost(Ty, CondTy, IsPairwiseForm, IsUnsigned,
+ CostKind);
}
- int getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) override {
- return Impl.getIntrinsicInstrCost(ID, RetTy, Args, FMF, VF);
+ int getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) override {
+ return Impl.getIntrinsicInstrCost(ICA, CostKind);
}
int getCallInstrCost(Function *F, Type *RetTy,
- ArrayRef<Type *> Tys) override {
- return Impl.getCallInstrCost(F, RetTy, Tys);
+ ArrayRef<Type *> Tys,
+ TTI::TargetCostKind CostKind) override {
+ return Impl.getCallInstrCost(F, RetTy, Tys, CostKind);
}
unsigned getNumberOfParts(Type *Tp) override {
return Impl.getNumberOfParts(Tp);
@@ -1808,16 +1917,18 @@ public:
return Impl.getOrCreateResultFromMemIntrinsic(Inst, ExpectedType);
}
Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAddrSpace, unsigned DestAddrSpace,
unsigned SrcAlign,
unsigned DestAlign) const override {
- return Impl.getMemcpyLoopLoweringType(Context, Length, SrcAlign, DestAlign);
+ return Impl.getMemcpyLoopLoweringType(Context, Length, SrcAddrSpace,
+ DestAddrSpace, SrcAlign, DestAlign);
}
- void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut,
- LLVMContext &Context,
- unsigned RemainingBytes,
- unsigned SrcAlign,
- unsigned DestAlign) const override {
+ void getMemcpyLoopResidualLoweringType(
+ SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
+ unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
+ unsigned SrcAlign, unsigned DestAlign) const override {
Impl.getMemcpyLoopResidualLoweringType(OpsOut, Context, RemainingBytes,
+ SrcAddrSpace, DestAddrSpace,
SrcAlign, DestAlign);
}
bool areInlineCompatible(const Function *Caller,
@@ -1844,14 +1955,12 @@ public:
bool isLegalToVectorizeStore(StoreInst *SI) const override {
return Impl.isLegalToVectorizeStore(SI);
}
- bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const override {
return Impl.isLegalToVectorizeLoadChain(ChainSizeInBytes, Alignment,
AddrSpace);
}
- bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const override {
return Impl.isLegalToVectorizeStoreChain(ChainSizeInBytes, Alignment,
AddrSpace);
@@ -1878,6 +1987,10 @@ public:
return Impl.getGISelRematGlobalCost();
}
+ bool hasActiveVectorLength() const override {
+ return Impl.hasActiveVectorLength();
+ }
+
int getInstructionLatency(const Instruction *I) override {
return Impl.getInstructionLatency(I);
}
@@ -1980,6 +2093,6 @@ public:
/// clients.
ImmutablePass *createTargetTransformInfoWrapperPass(TargetIRAnalysis TIRA);
-} // End llvm namespace
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index ac0609e29270..0ce975d6d4b5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -17,10 +17,10 @@
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Analysis/VectorUtils.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
+#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
@@ -44,66 +44,9 @@ public:
const DataLayout &getDataLayout() const { return DL; }
- unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) {
- switch (Opcode) {
- default:
- // By default, just classify everything as 'basic'.
- return TTI::TCC_Basic;
-
- case Instruction::GetElementPtr:
- llvm_unreachable("Use getGEPCost for GEP operations!");
-
- case Instruction::BitCast:
- assert(OpTy && "Cast instructions must provide the operand type");
- if (Ty == OpTy || (Ty->isPointerTy() && OpTy->isPointerTy()))
- // Identity and pointer-to-pointer casts are free.
- return TTI::TCC_Free;
-
- // Otherwise, the default basic cost is used.
- return TTI::TCC_Basic;
-
- case Instruction::FDiv:
- case Instruction::FRem:
- case Instruction::SDiv:
- case Instruction::SRem:
- case Instruction::UDiv:
- case Instruction::URem:
- return TTI::TCC_Expensive;
-
- case Instruction::IntToPtr: {
- // An inttoptr cast is free so long as the input is a legal integer type
- // which doesn't contain values outside the range of a pointer.
- unsigned OpSize = OpTy->getScalarSizeInBits();
- if (DL.isLegalInteger(OpSize) &&
- OpSize <= DL.getPointerTypeSizeInBits(Ty))
- return TTI::TCC_Free;
-
- // Otherwise it's not a no-op.
- return TTI::TCC_Basic;
- }
- case Instruction::PtrToInt: {
- // A ptrtoint cast is free so long as the result is large enough to store
- // the pointer, and a legal integer type.
- unsigned DestSize = Ty->getScalarSizeInBits();
- if (DL.isLegalInteger(DestSize) &&
- DestSize >= DL.getPointerTypeSizeInBits(OpTy))
- return TTI::TCC_Free;
-
- // Otherwise it's not a no-op.
- return TTI::TCC_Basic;
- }
- case Instruction::Trunc:
- // trunc to a native type is free (assuming the target has compare and
- // shift-right of the same width).
- if (DL.isLegalInteger(DL.getTypeSizeInBits(Ty)))
- return TTI::TCC_Free;
-
- return TTI::TCC_Basic;
- }
- }
-
int getGEPCost(Type *PointeeType, const Value *Ptr,
- ArrayRef<const Value *> Operands) {
+ ArrayRef<const Value *> Operands,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) {
// In the basic model, we just assume that all-constant GEPs will be folded
// into their uses via addressing modes.
for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx)
@@ -123,51 +66,32 @@ public:
return SI.getNumCases();
}
- int getExtCost(const Instruction *I, const Value *Src) {
- return TTI::TCC_Basic;
- }
-
- unsigned getCallCost(FunctionType *FTy, int NumArgs, const User *U) {
- assert(FTy && "FunctionType must be provided to this routine.");
-
- // The target-independent implementation just measures the size of the
- // function by approximating that each argument will take on average one
- // instruction to prepare.
-
- if (NumArgs < 0)
- // Set the argument number to the number of explicit arguments in the
- // function.
- NumArgs = FTy->getNumParams();
-
- return TTI::TCC_Basic * (NumArgs + 1);
- }
-
unsigned getInliningThresholdMultiplier() { return 1; }
int getInlinerVectorBonusPercent() { return 150; }
- unsigned getMemcpyCost(const Instruction *I) {
- return TTI::TCC_Expensive;
- }
+ unsigned getMemcpyCost(const Instruction *I) { return TTI::TCC_Expensive; }
bool hasBranchDivergence() { return false; }
+ bool useGPUDivergenceAnalysis() { return false; }
+
bool isSourceOfDivergence(const Value *V) { return false; }
bool isAlwaysUniform(const Value *V) { return false; }
- unsigned getFlatAddressSpace () {
- return -1;
- }
+ unsigned getFlatAddressSpace() { return -1; }
bool collectFlatAddressOperands(SmallVectorImpl<int> &OpIndexes,
Intrinsic::ID IID) const {
return false;
}
- bool rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
- Value *OldV, Value *NewV) const {
- return false;
+ bool isNoopAddrSpaceCast(unsigned, unsigned) const { return false; }
+
+ Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
+ Value *NewV) const {
+ return nullptr;
}
bool isLoweredToCall(const Function *F) {
@@ -207,8 +131,7 @@ public:
}
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
- AssumptionCache &AC,
- TargetLibraryInfo *LibInfo,
+ AssumptionCache &AC, TargetLibraryInfo *LibInfo,
HardwareLoopInfo &HWLoopInfo) {
return false;
}
@@ -220,16 +143,23 @@ public:
return false;
}
+ bool emitGetActiveLaneMask() const {
+ return false;
+ }
+
void getUnrollingPreferences(Loop *, ScalarEvolution &,
TTI::UnrollingPreferences &) {}
+ void getPeelingPreferences(Loop *, ScalarEvolution &,
+ TTI::PeelingPreferences &) {}
+
bool isLegalAddImmediate(int64_t Imm) { return false; }
bool isLegalICmpImmediate(int64_t Imm) { return false; }
bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
- bool HasBaseReg, int64_t Scale,
- unsigned AddrSpace, Instruction *I = nullptr) {
+ bool HasBaseReg, int64_t Scale, unsigned AddrSpace,
+ Instruction *I = nullptr) {
// Guess that only reg and reg+reg addressing is allowed. This heuristic is
// taken from the implementation of LSR.
return !BaseGV && BaseOffset == 0 && (Scale == 0 || Scale == 1);
@@ -242,6 +172,8 @@ public:
C2.ScaleCost, C2.ImmCost, C2.SetupCost);
}
+ bool isProfitableLSRChainElement(Instruction *I) { return false; }
+
bool canMacroFuseCmp() { return false; }
bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
@@ -254,9 +186,9 @@ public:
bool shouldFavorBackedgeIndex(const Loop *L) const { return false; }
- bool isLegalMaskedStore(Type *DataType, MaybeAlign Alignment) { return false; }
+ bool isLegalMaskedStore(Type *DataType, Align Alignment) { return false; }
- bool isLegalMaskedLoad(Type *DataType, MaybeAlign Alignment) { return false; }
+ bool isLegalMaskedLoad(Type *DataType, Align Alignment) { return false; }
bool isLegalNTStore(Type *DataType, Align Alignment) {
// By default, assume nontemporal memory stores are available for stores
@@ -272,13 +204,9 @@ public:
return Alignment >= DataSize && isPowerOf2_32(DataSize);
}
- bool isLegalMaskedScatter(Type *DataType, MaybeAlign Alignment) {
- return false;
- }
+ bool isLegalMaskedScatter(Type *DataType, Align Alignment) { return false; }
- bool isLegalMaskedGather(Type *DataType, MaybeAlign Alignment) {
- return false;
- }
+ bool isLegalMaskedGather(Type *DataType, Align Alignment) { return false; }
bool isLegalMaskedCompressStore(Type *DataType) { return false; }
@@ -293,8 +221,8 @@ public:
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
// Guess that all legal addressing mode are free.
- if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale, AddrSpace))
+ if (isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale,
+ AddrSpace))
return 0;
return -1;
}
@@ -314,12 +242,15 @@ public:
bool useColdCCForColdCall(Function &F) { return false; }
- unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) {
+ unsigned getScalarizationOverhead(VectorType *Ty, const APInt &DemandedElts,
+ bool Insert, bool Extract) {
return 0;
}
unsigned getOperandsScalarizationOverhead(ArrayRef<const Value *> Args,
- unsigned VF) { return 0; }
+ unsigned VF) {
+ return 0;
+ }
bool supportsEfficientVectorElementLoadStore() { return false; }
@@ -336,11 +267,11 @@ public:
bool isFPVectorizationPotentiallyUnsafe() { return false; }
- bool allowsMisalignedMemoryAccesses(LLVMContext &Context,
- unsigned BitWidth,
- unsigned AddressSpace,
- unsigned Alignment,
- bool *Fast) { return false; }
+ bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
+ unsigned AddressSpace, unsigned Alignment,
+ bool *Fast) {
+ return false;
+ }
TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) {
return TTI::PSK_Software;
@@ -357,15 +288,19 @@ public:
return 0;
}
- unsigned getIntImmCost(const APInt &Imm, Type *Ty) { return TTI::TCC_Basic; }
+ unsigned getIntImmCost(const APInt &Imm, Type *Ty,
+ TTI::TargetCostKind CostKind) {
+ return TTI::TCC_Basic;
+ }
unsigned getIntImmCostInst(unsigned Opcode, unsigned Idx, const APInt &Imm,
- Type *Ty) {
+ Type *Ty, TTI::TargetCostKind CostKind) {
return TTI::TCC_Free;
}
unsigned getIntImmCostIntrin(Intrinsic::ID IID, unsigned Idx,
- const APInt &Imm, Type *Ty) {
+ const APInt &Imm, Type *Ty,
+ TTI::TargetCostKind CostKind) {
return TTI::TCC_Free;
}
@@ -375,12 +310,14 @@ public:
return Vector ? 1 : 0;
};
- const char* getRegisterClassName(unsigned ClassID) const {
+ const char *getRegisterClassName(unsigned ClassID) const {
switch (ClassID) {
- default:
- return "Generic::Unknown Register Class";
- case 0: return "Generic::ScalarRC";
- case 1: return "Generic::VectorRC";
+ default:
+ return "Generic::Unknown Register Class";
+ case 0:
+ return "Generic::ScalarRC";
+ case 1:
+ return "Generic::VectorRC";
}
}
@@ -401,7 +338,8 @@ public:
unsigned getCacheLineSize() const { return 0; }
- llvm::Optional<unsigned> getCacheSize(TargetTransformInfo::CacheLevel Level) const {
+ llvm::Optional<unsigned>
+ getCacheSize(TargetTransformInfo::CacheLevel Level) const {
switch (Level) {
case TargetTransformInfo::CacheLevel::L1D:
LLVM_FALLTHROUGH;
@@ -411,8 +349,8 @@ public:
llvm_unreachable("Unknown TargetTransformInfo::CacheLevel");
}
- llvm::Optional<unsigned> getCacheAssociativity(
- TargetTransformInfo::CacheLevel Level) const {
+ llvm::Optional<unsigned>
+ getCacheAssociativity(TargetTransformInfo::CacheLevel Level) const {
switch (Level) {
case TargetTransformInfo::CacheLevel::L1D:
LLVM_FALLTHROUGH;
@@ -424,38 +362,98 @@ public:
}
unsigned getPrefetchDistance() const { return 0; }
- unsigned getMinPrefetchStride() const { return 1; }
+ unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches, bool HasCall) const {
+ return 1;
+ }
unsigned getMaxPrefetchIterationsAhead() const { return UINT_MAX; }
+ bool enableWritePrefetching() const { return false; }
unsigned getMaxInterleaveFactor(unsigned VF) { return 1; }
unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty,
+ TTI::TargetCostKind CostKind,
TTI::OperandValueKind Opd1Info,
TTI::OperandValueKind Opd2Info,
TTI::OperandValueProperties Opd1PropInfo,
TTI::OperandValueProperties Opd2PropInfo,
ArrayRef<const Value *> Args,
const Instruction *CxtI = nullptr) {
+ // FIXME: A number of transformation tests seem to require these values
+ // which seems a little odd for how arbitary there are.
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::FDiv:
+ case Instruction::FRem:
+ case Instruction::SDiv:
+ case Instruction::SRem:
+ case Instruction::UDiv:
+ case Instruction::URem:
+ // FIXME: Unlikely to be true for CodeSize.
+ return TTI::TCC_Expensive;
+ }
return 1;
}
- unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Ty, int Index,
- Type *SubTp) {
+ unsigned getShuffleCost(TTI::ShuffleKind Kind, VectorType *Ty, int Index,
+ VectorType *SubTp) {
return 1;
}
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
- const Instruction *I) { return 1; }
+ TTI::TargetCostKind CostKind,
+ const Instruction *I) {
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::IntToPtr: {
+ unsigned SrcSize = Src->getScalarSizeInBits();
+ if (DL.isLegalInteger(SrcSize) &&
+ SrcSize <= DL.getPointerTypeSizeInBits(Dst))
+ return 0;
+ break;
+ }
+ case Instruction::PtrToInt: {
+ unsigned DstSize = Dst->getScalarSizeInBits();
+ if (DL.isLegalInteger(DstSize) &&
+ DstSize >= DL.getPointerTypeSizeInBits(Src))
+ return 0;
+ break;
+ }
+ case Instruction::BitCast:
+ if (Dst == Src || (Dst->isPointerTy() && Src->isPointerTy()))
+ // Identity and pointer-to-pointer casts are free.
+ return 0;
+ break;
+ case Instruction::Trunc:
+ // trunc to a native type is free (assuming the target has compare and
+ // shift-right of the same width).
+ if (DL.isLegalInteger(DL.getTypeSizeInBits(Dst)))
+ return 0;
+ break;
+ }
+ return 1;
+ }
unsigned getExtractWithExtendCost(unsigned Opcode, Type *Dst,
VectorType *VecTy, unsigned Index) {
return 1;
}
- unsigned getCFInstrCost(unsigned Opcode) { return 1; }
+ unsigned getCFInstrCost(unsigned Opcode,
+ TTI::TargetCostKind CostKind) {
+ // A phi would be free, unless we're costing the throughput because it
+ // will require a register.
+ if (Opcode == Instruction::PHI && CostKind != TTI::TCK_RecipThroughput)
+ return 0;
+ return 1;
+ }
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- const Instruction *I) {
+ TTI::TargetCostKind CostKind,
+ const Instruction *I) const {
return 1;
}
@@ -463,42 +461,72 @@ public:
return 1;
}
- unsigned getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
- unsigned AddressSpace, const Instruction *I) {
+ unsigned getMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace, TTI::TargetCostKind CostKind,
+ const Instruction *I) const {
return 1;
}
- unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment,
- unsigned AddressSpace) {
+ unsigned getMaskedMemoryOpCost(unsigned Opcode, Type *Src, Align Alignment,
+ unsigned AddressSpace,
+ TTI::TargetCostKind CostKind) {
return 1;
}
- unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy, Value *Ptr,
- bool VariableMask,
- unsigned Alignment) {
+ unsigned getGatherScatterOpCost(unsigned Opcode, Type *DataTy,
+ const Value *Ptr, bool VariableMask,
+ Align Alignment, TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr) {
return 1;
}
- unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
- unsigned Factor,
- ArrayRef<unsigned> Indices,
- unsigned Alignment, unsigned AddressSpace,
- bool UseMaskForCond = false,
- bool UseMaskForGaps = false) {
+ unsigned getInterleavedMemoryOpCost(
+ unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
+ Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
+ bool UseMaskForCond, bool UseMaskForGaps) {
return 1;
}
- unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Type *> Tys, FastMathFlags FMF,
- unsigned ScalarizationCostPassed) {
- return 1;
- }
- unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF, unsigned VF) {
+ unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) {
+ switch (ICA.getID()) {
+ default:
+ break;
+ case Intrinsic::annotation:
+ case Intrinsic::assume:
+ case Intrinsic::sideeffect:
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ case Intrinsic::dbg_label:
+ case Intrinsic::invariant_start:
+ case Intrinsic::invariant_end:
+ case Intrinsic::launder_invariant_group:
+ case Intrinsic::strip_invariant_group:
+ case Intrinsic::is_constant:
+ case Intrinsic::lifetime_start:
+ case Intrinsic::lifetime_end:
+ case Intrinsic::objectsize:
+ case Intrinsic::ptr_annotation:
+ case Intrinsic::var_annotation:
+ case Intrinsic::experimental_gc_result:
+ case Intrinsic::experimental_gc_relocate:
+ case Intrinsic::coro_alloc:
+ case Intrinsic::coro_begin:
+ case Intrinsic::coro_free:
+ case Intrinsic::coro_end:
+ case Intrinsic::coro_frame:
+ case Intrinsic::coro_size:
+ case Intrinsic::coro_suspend:
+ case Intrinsic::coro_param:
+ case Intrinsic::coro_subfn_addr:
+ // These intrinsics don't actually represent code after lowering.
+ return 0;
+ }
return 1;
}
- unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) {
+ unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys,
+ TTI::TargetCostKind CostKind) {
return 1;
}
@@ -509,9 +537,11 @@ public:
return 0;
}
- unsigned getArithmeticReductionCost(unsigned, Type *, bool) { return 1; }
+ unsigned getArithmeticReductionCost(unsigned, VectorType *, bool,
+ TTI::TargetCostKind) { return 1; }
- unsigned getMinMaxReductionCost(Type *, Type *, bool, bool) { return 1; }
+ unsigned getMinMaxReductionCost(VectorType *, VectorType *, bool, bool,
+ TTI::TargetCostKind) { return 1; }
unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) { return 0; }
@@ -534,15 +564,15 @@ public:
}
Type *getMemcpyLoopLoweringType(LLVMContext &Context, Value *Length,
+ unsigned SrcAddrSpace, unsigned DestAddrSpace,
unsigned SrcAlign, unsigned DestAlign) const {
return Type::getInt8Ty(Context);
}
- void getMemcpyLoopResidualLoweringType(SmallVectorImpl<Type *> &OpsOut,
- LLVMContext &Context,
- unsigned RemainingBytes,
- unsigned SrcAlign,
- unsigned DestAlign) const {
+ void getMemcpyLoopResidualLoweringType(
+ SmallVectorImpl<Type *> &OpsOut, LLVMContext &Context,
+ unsigned RemainingBytes, unsigned SrcAddrSpace, unsigned DestAddrSpace,
+ unsigned SrcAlign, unsigned DestAlign) const {
for (unsigned i = 0; i != RemainingBytes; ++i)
OpsOut.push_back(Type::getInt8Ty(Context));
}
@@ -555,7 +585,8 @@ public:
Callee->getFnAttribute("target-features"));
}
- bool areFunctionArgsABICompatible(const Function *Caller, const Function *Callee,
+ bool areFunctionArgsABICompatible(const Function *Caller,
+ const Function *Callee,
SmallPtrSetImpl<Argument *> &Args) const {
return (Caller->getFnAttribute("target-cpu") ==
Callee->getFnAttribute("target-cpu")) &&
@@ -579,14 +610,12 @@ public:
bool isLegalToVectorizeStore(StoreInst *SI) const { return true; }
- bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeLoadChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const {
return true;
}
- bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes,
- unsigned Alignment,
+ bool isLegalToVectorizeStoreChain(unsigned ChainSizeInBytes, Align Alignment,
unsigned AddrSpace) const {
return true;
}
@@ -608,20 +637,18 @@ public:
return false;
}
- bool shouldExpandReduction(const IntrinsicInst *II) const {
- return true;
- }
+ bool shouldExpandReduction(const IntrinsicInst *II) const { return true; }
- unsigned getGISelRematGlobalCost() const {
- return 1;
- }
+ unsigned getGISelRematGlobalCost() const { return 1; }
+
+ bool hasActiveVectorLength() const { return false; }
protected:
// Obtain the minimum required size to hold the value (without the sign)
// In case of a vector it returns the min required size for one element.
- unsigned minRequiredElementSize(const Value* Val, bool &isSigned) {
+ unsigned minRequiredElementSize(const Value *Val, bool &isSigned) {
if (isa<ConstantDataVector>(Val) || isa<ConstantVector>(Val)) {
- const auto* VectorValue = cast<Constant>(Val);
+ const auto *VectorValue = cast<Constant>(Val);
// In case of a vector need to pick the max between the min
// required size for each element
@@ -630,24 +657,23 @@ protected:
// Assume unsigned elements
isSigned = false;
- // The max required size is the total vector width divided by num
- // of elements in the vector
- unsigned MaxRequiredSize = VT->getBitWidth() / VT->getNumElements();
+ // The max required size is the size of the vector element type
+ unsigned MaxRequiredSize =
+ VT->getElementType()->getPrimitiveSizeInBits().getFixedSize();
unsigned MinRequiredSize = 0;
- for(unsigned i = 0, e = VT->getNumElements(); i < e; ++i) {
- if (auto* IntElement =
- dyn_cast<ConstantInt>(VectorValue->getAggregateElement(i))) {
+ for (unsigned i = 0, e = VT->getNumElements(); i < e; ++i) {
+ if (auto *IntElement =
+ dyn_cast<ConstantInt>(VectorValue->getAggregateElement(i))) {
bool signedElement = IntElement->getValue().isNegative();
// Get the element min required size.
unsigned ElementMinRequiredSize =
- IntElement->getValue().getMinSignedBits() - 1;
+ IntElement->getValue().getMinSignedBits() - 1;
// In case one element is signed then all the vector is signed.
isSigned |= signedElement;
// Save the max required bit size between all the elements.
MinRequiredSize = std::max(MinRequiredSize, ElementMinRequiredSize);
- }
- else {
+ } else {
// not an int constant element
return MaxRequiredSize;
}
@@ -655,17 +681,17 @@ protected:
return MinRequiredSize;
}
- if (const auto* CI = dyn_cast<ConstantInt>(Val)) {
+ if (const auto *CI = dyn_cast<ConstantInt>(Val)) {
isSigned = CI->getValue().isNegative();
return CI->getValue().getMinSignedBits() - 1;
}
- if (const auto* Cast = dyn_cast<SExtInst>(Val)) {
+ if (const auto *Cast = dyn_cast<SExtInst>(Val)) {
isSigned = true;
return Cast->getSrcTy()->getScalarSizeInBits() - 1;
}
- if (const auto* Cast = dyn_cast<ZExtInst>(Val)) {
+ if (const auto *Cast = dyn_cast<ZExtInst>(Val)) {
isSigned = false;
return Cast->getSrcTy()->getScalarSizeInBits();
}
@@ -710,42 +736,11 @@ protected:
explicit TargetTransformInfoImplCRTPBase(const DataLayout &DL) : BaseT(DL) {}
public:
- using BaseT::getCallCost;
-
- unsigned getCallCost(const Function *F, int NumArgs, const User *U) {
- assert(F && "A concrete function must be provided to this routine.");
-
- if (NumArgs < 0)
- // Set the argument number to the number of explicit arguments in the
- // function.
- NumArgs = F->arg_size();
-
- if (Intrinsic::ID IID = F->getIntrinsicID()) {
- FunctionType *FTy = F->getFunctionType();
- SmallVector<Type *, 8> ParamTys(FTy->param_begin(), FTy->param_end());
- return static_cast<T *>(this)
- ->getIntrinsicCost(IID, FTy->getReturnType(), ParamTys, U);
- }
-
- if (!static_cast<T *>(this)->isLoweredToCall(F))
- return TTI::TCC_Basic; // Give a basic cost if it will be lowered
- // directly.
-
- return static_cast<T *>(this)->getCallCost(F->getFunctionType(), NumArgs, U);
- }
-
- unsigned getCallCost(const Function *F, ArrayRef<const Value *> Arguments,
- const User *U) {
- // Simply delegate to generic handling of the call.
- // FIXME: We should use instsimplify or something else to catch calls which
- // will constant fold with these arguments.
- return static_cast<T *>(this)->getCallCost(F, Arguments.size(), U);
- }
-
using BaseT::getGEPCost;
int getGEPCost(Type *PointeeType, const Value *Ptr,
- ArrayRef<const Value *> Operands) {
+ ArrayRef<const Value *> Operands,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) {
assert(PointeeType && Ptr && "can't get GEPCost of nullptr");
// TODO: will remove this when pointers have an opaque type.
assert(Ptr->getType()->getScalarType()->getPointerElementType() ==
@@ -802,108 +797,228 @@ public:
return TTI::TCC_Basic;
}
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys, const User *U) {
- switch (IID) {
- default:
- // Intrinsics rarely (if ever) have normal argument setup constraints.
- // Model them as having a basic instruction cost.
- return TTI::TCC_Basic;
-
- // TODO: other libc intrinsics.
- case Intrinsic::memcpy:
- return static_cast<T *>(this)->getMemcpyCost(dyn_cast<Instruction>(U));
+ int getUserCost(const User *U, ArrayRef<const Value *> Operands,
+ TTI::TargetCostKind CostKind) {
+ auto *TargetTTI = static_cast<T *>(this);
- case Intrinsic::annotation:
- case Intrinsic::assume:
- case Intrinsic::sideeffect:
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_label:
- case Intrinsic::invariant_start:
- case Intrinsic::invariant_end:
- case Intrinsic::launder_invariant_group:
- case Intrinsic::strip_invariant_group:
- case Intrinsic::is_constant:
- case Intrinsic::lifetime_start:
- case Intrinsic::lifetime_end:
- case Intrinsic::objectsize:
- case Intrinsic::ptr_annotation:
- case Intrinsic::var_annotation:
- case Intrinsic::experimental_gc_result:
- case Intrinsic::experimental_gc_relocate:
- case Intrinsic::coro_alloc:
- case Intrinsic::coro_begin:
- case Intrinsic::coro_free:
- case Intrinsic::coro_end:
- case Intrinsic::coro_frame:
- case Intrinsic::coro_size:
- case Intrinsic::coro_suspend:
- case Intrinsic::coro_param:
- case Intrinsic::coro_subfn_addr:
- // These intrinsics don't actually represent code after lowering.
- return TTI::TCC_Free;
+ // FIXME: We shouldn't have to special-case intrinsics here.
+ if (CostKind == TTI::TCK_RecipThroughput) {
+ if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
+ IntrinsicCostAttributes CostAttrs(*II);
+ return TargetTTI->getIntrinsicInstrCost(CostAttrs, CostKind);
+ }
}
- }
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments, const User *U) {
- // Delegate to the generic intrinsic handling code. This mostly provides an
- // opportunity for targets to (for example) special case the cost of
- // certain intrinsics based on constants used as arguments.
- SmallVector<Type *, 8> ParamTys;
- ParamTys.reserve(Arguments.size());
- for (unsigned Idx = 0, Size = Arguments.size(); Idx != Size; ++Idx)
- ParamTys.push_back(Arguments[Idx]->getType());
- return static_cast<T *>(this)->getIntrinsicCost(IID, RetTy, ParamTys, U);
- }
+ // FIXME: Unlikely to be true for anything but CodeSize.
+ if (const auto *CB = dyn_cast<CallBase>(U)) {
+ const Function *F = CB->getCalledFunction();
+ if (F) {
+ FunctionType *FTy = F->getFunctionType();
+ if (Intrinsic::ID IID = F->getIntrinsicID()) {
+ IntrinsicCostAttributes Attrs(IID, *CB);
+ return TargetTTI->getIntrinsicInstrCost(Attrs, CostKind);
+ }
- unsigned getUserCost(const User *U, ArrayRef<const Value *> Operands) {
- if (isa<PHINode>(U))
- return TTI::TCC_Free; // Model all PHI nodes as free.
+ if (!TargetTTI->isLoweredToCall(F))
+ return TTI::TCC_Basic; // Give a basic cost if it will be lowered
- if (isa<ExtractValueInst>(U))
- return TTI::TCC_Free; // Model all ExtractValue nodes as free.
+ return TTI::TCC_Basic * (FTy->getNumParams() + 1);
+ }
+ return TTI::TCC_Basic * (CB->arg_size() + 1);
+ }
- // Static alloca doesn't generate target instructions.
- if (auto *A = dyn_cast<AllocaInst>(U))
- if (A->isStaticAlloca())
+ Type *Ty = U->getType();
+ Type *OpTy =
+ U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr;
+ unsigned Opcode = Operator::getOpcode(U);
+ auto *I = dyn_cast<Instruction>(U);
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::Br:
+ case Instruction::Ret:
+ case Instruction::PHI:
+ return TargetTTI->getCFInstrCost(Opcode, CostKind);
+ case Instruction::ExtractValue:
+ case Instruction::Freeze:
+ return TTI::TCC_Free;
+ case Instruction::Alloca:
+ if (cast<AllocaInst>(U)->isStaticAlloca())
return TTI::TCC_Free;
-
- if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U)) {
- return static_cast<T *>(this)->getGEPCost(GEP->getSourceElementType(),
- GEP->getPointerOperand(),
- Operands.drop_front());
+ break;
+ case Instruction::GetElementPtr: {
+ const GEPOperator *GEP = cast<GEPOperator>(U);
+ return TargetTTI->getGEPCost(GEP->getSourceElementType(),
+ GEP->getPointerOperand(),
+ Operands.drop_front());
}
-
- if (auto CS = ImmutableCallSite(U)) {
- const Function *F = CS.getCalledFunction();
- if (!F) {
- // Just use the called value type.
- Type *FTy = CS.getCalledValue()->getType()->getPointerElementType();
- return static_cast<T *>(this)
- ->getCallCost(cast<FunctionType>(FTy), CS.arg_size(), U);
+ case Instruction::Add:
+ case Instruction::FAdd:
+ case Instruction::Sub:
+ case Instruction::FSub:
+ case Instruction::Mul:
+ case Instruction::FMul:
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ case Instruction::FDiv:
+ case Instruction::URem:
+ case Instruction::SRem:
+ case Instruction::FRem:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
+ case Instruction::FNeg: {
+ TTI::OperandValueProperties Op1VP = TTI::OP_None;
+ TTI::OperandValueProperties Op2VP = TTI::OP_None;
+ TTI::OperandValueKind Op1VK =
+ TTI::getOperandInfo(U->getOperand(0), Op1VP);
+ TTI::OperandValueKind Op2VK = Opcode != Instruction::FNeg ?
+ TTI::getOperandInfo(U->getOperand(1), Op2VP) : TTI::OK_AnyValue;
+ SmallVector<const Value *, 2> Operands(U->operand_values());
+ return TargetTTI->getArithmeticInstrCost(Opcode, Ty, CostKind,
+ Op1VK, Op2VK,
+ Op1VP, Op2VP, Operands, I);
+ }
+ case Instruction::IntToPtr:
+ case Instruction::PtrToInt:
+ case Instruction::SIToFP:
+ case Instruction::UIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::Trunc:
+ case Instruction::FPTrunc:
+ case Instruction::BitCast:
+ case Instruction::FPExt:
+ case Instruction::SExt:
+ case Instruction::ZExt:
+ case Instruction::AddrSpaceCast:
+ return TargetTTI->getCastInstrCost(Opcode, Ty, OpTy, CostKind, I);
+ case Instruction::Store: {
+ auto *SI = cast<StoreInst>(U);
+ Type *ValTy = U->getOperand(0)->getType();
+ return TargetTTI->getMemoryOpCost(Opcode, ValTy, SI->getAlign(),
+ SI->getPointerAddressSpace(),
+ CostKind, I);
+ }
+ case Instruction::Load: {
+ auto *LI = cast<LoadInst>(U);
+ return TargetTTI->getMemoryOpCost(Opcode, U->getType(), LI->getAlign(),
+ LI->getPointerAddressSpace(),
+ CostKind, I);
+ }
+ case Instruction::Select: {
+ Type *CondTy = U->getOperand(0)->getType();
+ return TargetTTI->getCmpSelInstrCost(Opcode, U->getType(), CondTy,
+ CostKind, I);
+ }
+ case Instruction::ICmp:
+ case Instruction::FCmp: {
+ Type *ValTy = U->getOperand(0)->getType();
+ return TargetTTI->getCmpSelInstrCost(Opcode, ValTy, U->getType(),
+ CostKind, I);
+ }
+ case Instruction::InsertElement: {
+ auto *IE = dyn_cast<InsertElementInst>(U);
+ if (!IE)
+ return TTI::TCC_Basic; // FIXME
+ auto *CI = dyn_cast<ConstantInt>(IE->getOperand(2));
+ unsigned Idx = CI ? CI->getZExtValue() : -1;
+ return TargetTTI->getVectorInstrCost(Opcode, Ty, Idx);
+ }
+ case Instruction::ShuffleVector: {
+ auto *Shuffle = dyn_cast<ShuffleVectorInst>(U);
+ if (!Shuffle)
+ return TTI::TCC_Basic; // FIXME
+ auto *VecTy = cast<VectorType>(U->getType());
+ auto *VecSrcTy = cast<VectorType>(U->getOperand(0)->getType());
+
+ // TODO: Identify and add costs for insert subvector, etc.
+ int SubIndex;
+ if (Shuffle->isExtractSubvectorMask(SubIndex))
+ return TargetTTI->getShuffleCost(TTI::SK_ExtractSubvector, VecSrcTy,
+ SubIndex, VecTy);
+ else if (Shuffle->changesLength())
+ return CostKind == TTI::TCK_RecipThroughput ? -1 : 1;
+ else if (Shuffle->isIdentity())
+ return 0;
+ else if (Shuffle->isReverse())
+ return TargetTTI->getShuffleCost(TTI::SK_Reverse, VecTy, 0, nullptr);
+ else if (Shuffle->isSelect())
+ return TargetTTI->getShuffleCost(TTI::SK_Select, VecTy, 0, nullptr);
+ else if (Shuffle->isTranspose())
+ return TargetTTI->getShuffleCost(TTI::SK_Transpose, VecTy, 0, nullptr);
+ else if (Shuffle->isZeroEltSplat())
+ return TargetTTI->getShuffleCost(TTI::SK_Broadcast, VecTy, 0, nullptr);
+ else if (Shuffle->isSingleSource())
+ return TargetTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, VecTy, 0,
+ nullptr);
+
+ return TargetTTI->getShuffleCost(TTI::SK_PermuteTwoSrc, VecTy, 0,
+ nullptr);
+ }
+ case Instruction::ExtractElement: {
+ unsigned Idx = -1;
+ auto *EEI = dyn_cast<ExtractElementInst>(U);
+ if (!EEI)
+ return TTI::TCC_Basic; // FIXME
+
+ auto *CI = dyn_cast<ConstantInt>(EEI->getOperand(1));
+ if (CI)
+ Idx = CI->getZExtValue();
+
+ // Try to match a reduction sequence (series of shufflevector and
+ // vector adds followed by a extractelement).
+ unsigned ReduxOpCode;
+ VectorType *ReduxType;
+
+ switch (TTI::matchVectorSplittingReduction(EEI, ReduxOpCode,
+ ReduxType)) {
+ case TTI::RK_Arithmetic:
+ return TargetTTI->getArithmeticReductionCost(ReduxOpCode, ReduxType,
+ /*IsPairwiseForm=*/false,
+ CostKind);
+ case TTI::RK_MinMax:
+ return TargetTTI->getMinMaxReductionCost(
+ ReduxType, cast<VectorType>(CmpInst::makeCmpResultType(ReduxType)),
+ /*IsPairwiseForm=*/false, /*IsUnsigned=*/false, CostKind);
+ case TTI::RK_UnsignedMinMax:
+ return TargetTTI->getMinMaxReductionCost(
+ ReduxType, cast<VectorType>(CmpInst::makeCmpResultType(ReduxType)),
+ /*IsPairwiseForm=*/false, /*IsUnsigned=*/true, CostKind);
+ case TTI::RK_None:
+ break;
}
- SmallVector<const Value *, 8> Arguments(CS.arg_begin(), CS.arg_end());
- return static_cast<T *>(this)->getCallCost(F, Arguments, U);
+ switch (TTI::matchPairwiseReduction(EEI, ReduxOpCode, ReduxType)) {
+ case TTI::RK_Arithmetic:
+ return TargetTTI->getArithmeticReductionCost(ReduxOpCode, ReduxType,
+ /*IsPairwiseForm=*/true, CostKind);
+ case TTI::RK_MinMax:
+ return TargetTTI->getMinMaxReductionCost(
+ ReduxType, cast<VectorType>(CmpInst::makeCmpResultType(ReduxType)),
+ /*IsPairwiseForm=*/true, /*IsUnsigned=*/false, CostKind);
+ case TTI::RK_UnsignedMinMax:
+ return TargetTTI->getMinMaxReductionCost(
+ ReduxType, cast<VectorType>(CmpInst::makeCmpResultType(ReduxType)),
+ /*IsPairwiseForm=*/true, /*IsUnsigned=*/true, CostKind);
+ case TTI::RK_None:
+ break;
+ }
+ return TargetTTI->getVectorInstrCost(Opcode, U->getOperand(0)->getType(),
+ Idx);
}
-
- if (isa<SExtInst>(U) || isa<ZExtInst>(U) || isa<FPExtInst>(U))
- // The old behaviour of generally treating extensions of icmp to be free
- // has been removed. A target that needs it should override getUserCost().
- return static_cast<T *>(this)->getExtCost(cast<Instruction>(U),
- Operands.back());
-
- return static_cast<T *>(this)->getOperationCost(
- Operator::getOpcode(U), U->getType(),
- U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr);
+ }
+ // By default, just classify everything as 'basic'.
+ return TTI::TCC_Basic;
}
int getInstructionLatency(const Instruction *I) {
SmallVector<const Value *, 4> Operands(I->value_op_begin(),
I->value_op_end());
- if (getUserCost(I, Operands) == TTI::TCC_Free)
+ if (getUserCost(I, Operands, TTI::TCK_Latency) == TTI::TCC_Free)
return 0;
if (isa<LoadInst>(I))
@@ -919,7 +1034,7 @@ public:
return 40;
// Some intrinsics return a value and a flag, we use the value type
// to decide its latency.
- if (StructType* StructTy = dyn_cast<StructType>(DstTy))
+ if (StructType *StructTy = dyn_cast<StructType>(DstTy))
DstTy = StructTy->getElementType(0);
// Fall through to simple instructions.
}
@@ -932,6 +1047,6 @@ public:
return 1;
}
};
-}
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
index 344f26806618..345f11a3aad5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TypeBasedAliasAnalysis.h
@@ -16,13 +16,13 @@
#define LLVM_ANALYSIS_TYPEBASEDALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include <memory>
namespace llvm {
+class CallBase;
class Function;
class MDNode;
class MemoryLocation;
@@ -53,7 +53,6 @@ public:
private:
bool Aliases(const MDNode *A, const MDNode *B) const;
- bool PathAliases(const MDNode *A, const MDNode *B) const;
};
/// Analysis pass providing a never-invalidated alias analysis result.
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h
index 43ce26147c2e..3f7603142900 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/TypeMetadataUtils.h
@@ -15,11 +15,16 @@
#define LLVM_ANALYSIS_TYPEMETADATAUTILS_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/CallSite.h"
+#include <cstdint>
namespace llvm {
+class CallBase;
+class CallInst;
+class Constant;
class DominatorTree;
+class Instruction;
+class Module;
/// The type of CFI jumptable needed for a function.
enum CfiFunctionLinkage {
@@ -33,7 +38,7 @@ struct DevirtCallSite {
/// The offset from the address point to the virtual function.
uint64_t Offset;
/// The call site itself.
- CallSite CS;
+ CallBase &CB;
};
/// Given a call to the intrinsic \@llvm.type.test, find all devirtualizable
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/Local.h b/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/Local.h
index ca505960cbeb..f31b56345424 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/Local.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/Local.h
@@ -14,7 +14,7 @@
#ifndef LLVM_ANALYSIS_UTILS_LOCAL_H
#define LLVM_ANALYSIS_UTILS_LOCAL_H
-#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GetElementPtrTypeIterator.h"
@@ -57,39 +57,41 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
if (Size)
Result = Builder->CreateAdd(Result, ConstantInt::get(IntIdxTy, Size),
- GEP->getName()+".offs");
+ GEP->getName().str()+".offs");
continue;
}
// Splat the constant if needed.
if (IntIdxTy->isVectorTy() && !OpC->getType()->isVectorTy())
- OpC = ConstantVector::getSplat(IntIdxTy->getVectorNumElements(), OpC);
+ OpC = ConstantVector::getSplat(
+ cast<VectorType>(IntIdxTy)->getElementCount(), OpC);
Constant *Scale = ConstantInt::get(IntIdxTy, Size);
Constant *OC = ConstantExpr::getIntegerCast(OpC, IntIdxTy, true /*SExt*/);
Scale =
ConstantExpr::getMul(OC, Scale, false /*NUW*/, isInBounds /*NSW*/);
// Emit an add instruction.
- Result = Builder->CreateAdd(Result, Scale, GEP->getName()+".offs");
+ Result = Builder->CreateAdd(Result, Scale, GEP->getName().str()+".offs");
continue;
}
// Splat the index if needed.
if (IntIdxTy->isVectorTy() && !Op->getType()->isVectorTy())
- Op = Builder->CreateVectorSplat(IntIdxTy->getVectorNumElements(), Op);
+ Op = Builder->CreateVectorSplat(
+ cast<VectorType>(IntIdxTy)->getNumElements(), Op);
// Convert to correct type.
if (Op->getType() != IntIdxTy)
- Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName()+".c");
+ Op = Builder->CreateIntCast(Op, IntIdxTy, true, Op->getName().str()+".c");
if (Size != 1) {
// We'll let instcombine(mul) convert this to a shl if possible.
Op = Builder->CreateMul(Op, ConstantInt::get(IntIdxTy, Size),
- GEP->getName() + ".idx", false /*NUW*/,
+ GEP->getName().str() + ".idx", false /*NUW*/,
isInBounds /*NSW*/);
}
// Emit an add instruction.
- Result = Builder->CreateAdd(Op, Result, GEP->getName()+".offs");
+ Result = Builder->CreateAdd(Op, Result, GEP->getName().str()+".offs");
}
return Result;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/TFUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/TFUtils.h
new file mode 100644
index 000000000000..2ab2c7a57d94
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/Utils/TFUtils.h
@@ -0,0 +1,115 @@
+//===- TFUtils.h - utilities for tensorflow C API ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+#ifndef LLVM_ANALYSIS_UTILS_TFUTILS_H
+#define LLVM_ANALYSIS_UTILS_TFUTILS_H
+
+#include "llvm/Config/config.h"
+
+#ifdef LLVM_HAVE_TF_API
+#include "llvm/IR/LLVMContext.h"
+
+#include <memory>
+#include <vector>
+
+namespace llvm {
+
+/// Load a SavedModel, find the given inputs and outputs, and setup storage
+/// for input tensors. The user is responsible for correctly dimensioning the
+/// input tensors and setting their values before calling evaluate().
+/// To initialize:
+/// - construct the object
+/// - initialize the input tensors using initInput. Indices must correspond to
+/// indices in the InputNames used at construction.
+/// To use:
+/// - set input values by using getInput to get each input tensor, and then
+/// setting internal scalars, for all dimensions (tensors are row-major:
+/// https://github.com/tensorflow/tensorflow/blob/r1.5/tensorflow/c/c_api.h#L205)
+/// - call evaluate. The input tensors' values are not consumed after this, and
+/// may still be read.
+/// - use the outputs in the output vector
+class TFModelEvaluatorImpl;
+class EvaluationResultImpl;
+
+class TFModelEvaluator final {
+public:
+ /// The result of a model evaluation. Handles the lifetime of the output
+ /// tensors, which means that their values need to be used before
+ /// the EvaluationResult's dtor is called.
+ class EvaluationResult {
+ public:
+ EvaluationResult(const EvaluationResult &) = delete;
+ EvaluationResult(EvaluationResult &&Other);
+ ~EvaluationResult();
+
+ /// Get a pointer to the first element of the tensor at Index.
+ template <typename T> T *getTensorValue(size_t Index) {
+ return static_cast<T *>(getUntypedTensorValue(Index));
+ }
+
+ private:
+ friend class TFModelEvaluator;
+ EvaluationResult(std::unique_ptr<EvaluationResultImpl> Impl);
+ void *getUntypedTensorValue(size_t Index);
+ std::unique_ptr<EvaluationResultImpl> Impl;
+ };
+
+ TFModelEvaluator(StringRef SavedModelPath,
+ const std::vector<std::string> &InputNames,
+ const std::vector<std::string> &OutputNames,
+ const char *Tags = "serve");
+ ~TFModelEvaluator();
+ TFModelEvaluator(const TFModelEvaluator &) = delete;
+ TFModelEvaluator(TFModelEvaluator &&) = delete;
+
+ /// Evaluate the model, assuming it is valid. Returns None if the evaluation
+ /// fails or the model is invalid, or an EvaluationResult otherwise. The
+ /// inputs are assumed to have been already provided via getInput(). When
+ /// returning None, it also invalidates this object.
+ Optional<EvaluationResult> evaluate();
+
+ /// Provides access to the input vector.
+ template <typename T> T *getInput(size_t Index) {
+ return static_cast<T *>(getUntypedInput(Index));
+ }
+
+ /// Returns true if the tensorflow model was loaded successfully, false
+ /// otherwise.
+ bool isValid() const { return !!Impl; }
+
+ /// Initialize the input at Index as a tensor of the given type and
+ /// dimensions.
+ template <typename T>
+ void initInput(size_t Index, const std::vector<int64_t> &Dimensions) {
+ return initInput(Index, getModelTypeIndex<T>(), Dimensions);
+ }
+
+private:
+ void *getUntypedInput(size_t Index);
+ template <typename T> int getModelTypeIndex();
+ void initInput(size_t Index, int TypeIndex,
+ const std::vector<int64_t> &Dimensions);
+
+ std::unique_ptr<TFModelEvaluatorImpl> Impl;
+};
+
+template <> int TFModelEvaluator::getModelTypeIndex<float>();
+template <> int TFModelEvaluator::getModelTypeIndex<double>();
+template <> int TFModelEvaluator::getModelTypeIndex<int8_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<uint8_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<int16_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<uint16_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<int32_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<uint32_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<int64_t>();
+template <> int TFModelEvaluator::getModelTypeIndex<uint64_t>();
+
+} // namespace llvm
+
+#endif // LLVM_HAVE_TF_API
+#endif // LLVM_ANALYSIS_UTILS_TFUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ValueLattice.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ValueLattice.h
index 415c32e7c23c..bf5bab9ced22 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ValueLattice.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ValueLattice.h
@@ -29,31 +29,55 @@ class ValueLatticeElement {
/// producing instruction is dead. Caution: We use this as the starting
/// state in our local meet rules. In this usage, it's taken to mean
/// "nothing known yet".
+ /// Transition to any other state allowed.
unknown,
- /// This Value has a specific constant value. (For constant integers,
- /// constantrange is used instead. Integer typed constantexprs can appear
- /// as constant.)
+ /// This Value is an UndefValue constant or produces undef. Undefined values
+ /// can be merged with constants (or single element constant ranges),
+ /// assuming all uses of the result will be replaced.
+ /// Transition allowed to the following states:
+ /// constant
+ /// constantrange_including_undef
+ /// overdefined
+ undef,
+
+ /// This Value has a specific constant value. The constant cannot be undef.
+ /// (For constant integers, constantrange is used instead. Integer typed
+ /// constantexprs can appear as constant.) Note that the constant state
+ /// can be reached by merging undef & constant states.
+ /// Transition allowed to the following states:
+ /// overdefined
constant,
- /// This Value is known to not have the specified value. (For constant
+ /// This Value is known to not have the specified value. (For constant
/// integers, constantrange is used instead. As above, integer typed
/// constantexprs can appear here.)
+ /// Transition allowed to the following states:
+ /// overdefined
notconstant,
/// The Value falls within this range. (Used only for integer typed values.)
+ /// Transition allowed to the following states:
+ /// constantrange (new range must be a superset of the existing range)
+ /// constantrange_including_undef
+ /// overdefined
constantrange,
+ /// This Value falls within this range, but also may be undef.
+ /// Merging it with other constant ranges results in
+ /// constantrange_including_undef.
+ /// Transition allowed to the following states:
+ /// overdefined
+ constantrange_including_undef,
+
/// We can not precisely model the dynamic values this value might take.
+ /// No transitions are allowed after reaching overdefined.
overdefined,
-
- /// This Value is an UndefValue constant or produces undef. Undefined values
- /// can be merged with constants (or single element constant ranges),
- /// assuming all uses of the result will be replaced.
- undef
};
- ValueLatticeElementTy Tag;
+ ValueLatticeElementTy Tag : 8;
+ /// Number of times a constant range has been extended with widening enabled.
+ unsigned NumRangeExtensions : 8;
/// The union either stores a pointer to a constant or a constant range,
/// associated to the lattice element. We have to ensure that Range is
@@ -63,13 +87,8 @@ class ValueLatticeElement {
ConstantRange Range;
};
-public:
- // Const and Range are initialized on-demand.
- ValueLatticeElement() : Tag(unknown) {}
-
- /// Custom destructor to ensure Range is properly destroyed, when the object
- /// is deallocated.
- ~ValueLatticeElement() {
+ /// Destroy contents of lattice value, without destructing the object.
+ void destroy() {
switch (Tag) {
case overdefined:
case unknown:
@@ -77,38 +96,63 @@ public:
case constant:
case notconstant:
break;
+ case constantrange_including_undef:
case constantrange:
Range.~ConstantRange();
break;
};
}
- /// Custom copy constructor, to ensure Range gets initialized when
- /// copying a constant range lattice element.
- ValueLatticeElement(const ValueLatticeElement &Other) : Tag(unknown) {
- *this = Other;
- }
+public:
+ /// Struct to control some aspects related to merging constant ranges.
+ struct MergeOptions {
+ /// The merge value may include undef.
+ bool MayIncludeUndef;
- /// Custom assignment operator, to ensure Range gets initialized when
- /// assigning a constant range lattice element.
- ValueLatticeElement &operator=(const ValueLatticeElement &Other) {
- // If we change the state of this from constant range to non constant range,
- // destroy Range.
- if (isConstantRange() && !Other.isConstantRange())
- Range.~ConstantRange();
+ /// Handle repeatedly extending a range by going to overdefined after a
+ /// number of steps.
+ bool CheckWiden;
+
+ /// The number of allowed widening steps (including setting the range
+ /// initially).
+ unsigned MaxWidenSteps;
+
+ MergeOptions() : MergeOptions(false, false) {}
+
+ MergeOptions(bool MayIncludeUndef, bool CheckWiden,
+ unsigned MaxWidenSteps = 1)
+ : MayIncludeUndef(MayIncludeUndef), CheckWiden(CheckWiden),
+ MaxWidenSteps(MaxWidenSteps) {}
- // If we change the state of this from a valid ConstVal to another a state
- // without a valid ConstVal, zero the pointer.
- if ((isConstant() || isNotConstant()) && !Other.isConstant() &&
- !Other.isNotConstant())
- ConstVal = nullptr;
+ MergeOptions &setMayIncludeUndef(bool V = true) {
+ MayIncludeUndef = V;
+ return *this;
+ }
+
+ MergeOptions &setCheckWiden(bool V = true) {
+ CheckWiden = V;
+ return *this;
+ }
+ MergeOptions &setMaxWidenSteps(unsigned Steps = 1) {
+ CheckWiden = true;
+ MaxWidenSteps = Steps;
+ return *this;
+ }
+ };
+
+ // ConstVal and Range are initialized on-demand.
+ ValueLatticeElement() : Tag(unknown), NumRangeExtensions(0) {}
+
+ ~ValueLatticeElement() { destroy(); }
+
+ ValueLatticeElement(const ValueLatticeElement &Other)
+ : Tag(Other.Tag), NumRangeExtensions(0) {
switch (Other.Tag) {
case constantrange:
- if (!isConstantRange())
- new (&Range) ConstantRange(Other.Range);
- else
- Range = Other.Range;
+ case constantrange_including_undef:
+ new (&Range) ConstantRange(Other.Range);
+ NumRangeExtensions = Other.NumRangeExtensions;
break;
case constant:
case notconstant:
@@ -119,7 +163,37 @@ public:
case undef:
break;
}
- Tag = Other.Tag;
+ }
+
+ ValueLatticeElement(ValueLatticeElement &&Other)
+ : Tag(Other.Tag), NumRangeExtensions(0) {
+ switch (Other.Tag) {
+ case constantrange:
+ case constantrange_including_undef:
+ new (&Range) ConstantRange(std::move(Other.Range));
+ NumRangeExtensions = Other.NumRangeExtensions;
+ break;
+ case constant:
+ case notconstant:
+ ConstVal = Other.ConstVal;
+ break;
+ case overdefined:
+ case unknown:
+ case undef:
+ break;
+ }
+ Other.Tag = unknown;
+ }
+
+ ValueLatticeElement &operator=(const ValueLatticeElement &Other) {
+ destroy();
+ new (this) ValueLatticeElement(Other);
+ return *this;
+ }
+
+ ValueLatticeElement &operator=(ValueLatticeElement &&Other) {
+ destroy();
+ new (this) ValueLatticeElement(std::move(Other));
return *this;
}
@@ -137,9 +211,21 @@ public:
Res.markNotConstant(C);
return Res;
}
- static ValueLatticeElement getRange(ConstantRange CR) {
+ static ValueLatticeElement getRange(ConstantRange CR,
+ bool MayIncludeUndef = false) {
+ if (CR.isFullSet())
+ return getOverdefined();
+
+ if (CR.isEmptySet()) {
+ ValueLatticeElement Res;
+ if (MayIncludeUndef)
+ Res.markUndef();
+ return Res;
+ }
+
ValueLatticeElement Res;
- Res.markConstantRange(std::move(CR));
+ Res.markConstantRange(std::move(CR),
+ MergeOptions().setMayIncludeUndef(MayIncludeUndef));
return Res;
}
static ValueLatticeElement getOverdefined() {
@@ -151,10 +237,19 @@ public:
bool isUndef() const { return Tag == undef; }
bool isUnknown() const { return Tag == unknown; }
bool isUnknownOrUndef() const { return Tag == unknown || Tag == undef; }
- bool isUndefined() const { return isUnknownOrUndef(); }
bool isConstant() const { return Tag == constant; }
bool isNotConstant() const { return Tag == notconstant; }
- bool isConstantRange() const { return Tag == constantrange; }
+ bool isConstantRangeIncludingUndef() const {
+ return Tag == constantrange_including_undef;
+ }
+ /// Returns true if this value is a constant range. Use \p UndefAllowed to
+ /// exclude non-singleton constant ranges that may also be undef. Note that
+ /// this function also returns true if the range may include undef, but only
+ /// contains a single element. In that case, it can be replaced by a constant.
+ bool isConstantRange(bool UndefAllowed = true) const {
+ return Tag == constantrange || (Tag == constantrange_including_undef &&
+ (UndefAllowed || Range.isSingleElement()));
+ }
bool isOverdefined() const { return Tag == overdefined; }
Constant *getConstant() const {
@@ -167,8 +262,12 @@ public:
return ConstVal;
}
- const ConstantRange &getConstantRange() const {
- assert(isConstantRange() &&
+ /// Returns the constant range for this value. Use \p UndefAllowed to exclude
+ /// non-singleton constant ranges that may also be undef. Note that this
+ /// function also returns a range if the range may include undef, but only
+ /// contains a single element. In that case, it can be replaced by a constant.
+ const ConstantRange &getConstantRange(bool UndefAllowed = true) const {
+ assert(isConstantRange(UndefAllowed) &&
"Cannot get the constant-range of a non-constant-range!");
return Range;
}
@@ -185,10 +284,7 @@ public:
bool markOverdefined() {
if (isOverdefined())
return false;
- if (isConstant() || isNotConstant())
- ConstVal = nullptr;
- if (isConstantRange())
- Range.~ConstantRange();
+ destroy();
Tag = overdefined;
return true;
}
@@ -202,7 +298,7 @@ public:
return true;
}
- bool markConstant(Constant *V) {
+ bool markConstant(Constant *V, bool MayIncludeUndef = false) {
if (isa<UndefValue>(V))
return markUndef();
@@ -212,7 +308,9 @@ public:
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
- return markConstantRange(ConstantRange(CI->getValue()));
+ return markConstantRange(
+ ConstantRange(CI->getValue()),
+ MergeOptions().setMayIncludeUndef(MayIncludeUndef));
assert(isUnknown() || isUndef());
Tag = constant;
@@ -242,14 +340,30 @@ public:
/// Mark the object as constant range with \p NewR. If the object is already a
/// constant range, nothing changes if the existing range is equal to \p
- /// NewR. Otherwise \p NewR must be a superset of the existing range or the
- /// object must be undef.
- bool markConstantRange(ConstantRange NewR) {
+ /// NewR and the tag. Otherwise \p NewR must be a superset of the existing
+ /// range or the object must be undef. The tag is set to
+ /// constant_range_including_undef if either the existing value or the new
+ /// range may include undef.
+ bool markConstantRange(ConstantRange NewR,
+ MergeOptions Opts = MergeOptions()) {
+ assert(!NewR.isEmptySet() && "should only be called for non-empty sets");
+
+ if (NewR.isFullSet())
+ return markOverdefined();
+
+ ValueLatticeElementTy OldTag = Tag;
+ ValueLatticeElementTy NewTag =
+ (isUndef() || isConstantRangeIncludingUndef() || Opts.MayIncludeUndef)
+ ? constantrange_including_undef
+ : constantrange;
if (isConstantRange()) {
+ Tag = NewTag;
if (getConstantRange() == NewR)
- return false;
+ return Tag != OldTag;
- if (NewR.isEmptySet())
+ // Simple form of widening. If a range is extended multiple times, go to
+ // overdefined.
+ if (Opts.CheckWiden && ++NumRangeExtensions > Opts.MaxWidenSteps)
return markOverdefined();
assert(NewR.contains(getConstantRange()) &&
@@ -259,17 +373,17 @@ public:
}
assert(isUnknown() || isUndef());
- if (NewR.isEmptySet())
- return markOverdefined();
- Tag = constantrange;
+ NumRangeExtensions = 0;
+ Tag = NewTag;
new (&Range) ConstantRange(std::move(NewR));
return true;
}
/// Updates this object to approximate both this object and RHS. Returns
/// true if this object has been changed.
- bool mergeIn(const ValueLatticeElement &RHS, const DataLayout &DL) {
+ bool mergeIn(const ValueLatticeElement &RHS,
+ MergeOptions Opts = MergeOptions()) {
if (RHS.isUnknown() || isOverdefined())
return false;
if (RHS.isOverdefined()) {
@@ -282,9 +396,10 @@ public:
if (RHS.isUndef())
return false;
if (RHS.isConstant())
- return markConstant(RHS.getConstant());
- if (RHS.isConstantRange() && RHS.getConstantRange().isSingleElement())
- return markConstantRange(RHS.getConstantRange());
+ return markConstant(RHS.getConstant(), true);
+ if (RHS.isConstantRange())
+ return markConstantRange(RHS.getConstantRange(true),
+ Opts.setMayIncludeUndef());
return markOverdefined();
}
@@ -310,9 +425,12 @@ public:
return true;
}
+ auto OldTag = Tag;
assert(isConstantRange() && "New ValueLattice type?");
- if (RHS.isUndef() && getConstantRange().isSingleElement())
- return false;
+ if (RHS.isUndef()) {
+ Tag = constantrange_including_undef;
+ return OldTag != Tag;
+ }
if (!RHS.isConstantRange()) {
// We can get here if we've encountered a constantexpr of integer type
@@ -320,16 +438,14 @@ public:
markOverdefined();
return true;
}
+
ConstantRange NewR = getConstantRange().unionWith(RHS.getConstantRange());
- if (NewR.isFullSet())
- return markOverdefined();
- else if (NewR == getConstantRange())
- return false;
- else
- return markConstantRange(std::move(NewR));
+ return markConstantRange(
+ std::move(NewR),
+ Opts.setMayIncludeUndef(RHS.isConstantRangeIncludingUndef()));
}
- /// Compares this symbolic value with Other using Pred and returns either
+ // Compares this symbolic value with Other using Pred and returns either
/// true, false or undef constants, or nullptr if the comparison cannot be
/// evaluated.
Constant *getCompare(CmpInst::Predicate Pred, Type *Ty,
@@ -356,9 +472,14 @@ public:
return nullptr;
}
+
+ unsigned getNumRangeExtensions() const { return NumRangeExtensions; }
+ void setNumRangeExtensions(unsigned N) { NumRangeExtensions = N; }
};
-raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val);
+static_assert(sizeof(ValueLatticeElement) <= 40,
+ "size of ValueLatticeElement changed unexpectedly");
+raw_ostream &operator<<(raw_ostream &OS, const ValueLatticeElement &Val);
} // end namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ValueTracking.h b/contrib/llvm-project/llvm/include/llvm/Analysis/ValueTracking.h
index 89cf9abdc8ba..9510739ef5ab 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ValueTracking.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/ValueTracking.h
@@ -17,10 +17,9 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Instruction.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Intrinsics.h"
#include <cassert>
#include <cstdint>
@@ -33,6 +32,7 @@ class AssumptionCache;
class DominatorTree;
class GEPOperator;
class IntrinsicInst;
+class LoadInst;
class WithOverflowInst;
struct KnownBits;
class Loop;
@@ -59,6 +59,22 @@ class Value;
OptimizationRemarkEmitter *ORE = nullptr,
bool UseInstrInfo = true);
+ /// Determine which bits of V are known to be either zero or one and return
+ /// them in the KnownZero/KnownOne bit sets.
+ ///
+ /// This function is defined on values with integer type, values with pointer
+ /// type, and vectors of integers. In the case
+ /// where V is a vector, the known zero and known one values are the
+ /// same width as the vector element, and the bit is set only if it is true
+ /// for all of the demanded elements in the vector.
+ void computeKnownBits(const Value *V, const APInt &DemandedElts,
+ KnownBits &Known, const DataLayout &DL,
+ unsigned Depth = 0, AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr,
+ bool UseInstrInfo = true);
+
/// Returns the known bits rather than passing by reference.
KnownBits computeKnownBits(const Value *V, const DataLayout &DL,
unsigned Depth = 0, AssumptionCache *AC = nullptr,
@@ -67,6 +83,15 @@ class Value;
OptimizationRemarkEmitter *ORE = nullptr,
bool UseInstrInfo = true);
+ /// Returns the known bits rather than passing by reference.
+ KnownBits computeKnownBits(const Value *V, const APInt &DemandedElts,
+ const DataLayout &DL, unsigned Depth = 0,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CxtI = nullptr,
+ const DominatorTree *DT = nullptr,
+ OptimizationRemarkEmitter *ORE = nullptr,
+ bool UseInstrInfo = true);
+
/// Compute known bits from the range metadata.
/// \p KnownZero the set of bits that are known to be zero
/// \p KnownOne the set of bits that are known to be one
@@ -185,7 +210,7 @@ class Value;
/// Map a call instruction to an intrinsic ID. Libcalls which have equivalent
/// intrinsics are treated as-if they were intrinsics.
- Intrinsic::ID getIntrinsicForCallSite(ImmutableCallSite ICS,
+ Intrinsic::ID getIntrinsicForCallSite(const CallBase &CB,
const TargetLibraryInfo *TLI);
/// Return true if we can prove that the specified FP value is never equal to
@@ -506,7 +531,10 @@ class Value;
/// Determine the possible constant range of an integer or vector of integer
/// value. This is intended as a cheap, non-recursive check.
- ConstantRange computeConstantRange(const Value *V, bool UseInstrInfo = true);
+ ConstantRange computeConstantRange(const Value *V, bool UseInstrInfo = true,
+ AssumptionCache *AC = nullptr,
+ const Instruction *CtxI = nullptr,
+ unsigned Depth = 0);
/// Return true if this function can prove that the instruction I will
/// always transfer execution to one of its successors (including the next
@@ -537,39 +565,51 @@ class Value;
bool isGuaranteedToExecuteForEveryIteration(const Instruction *I,
const Loop *L);
- /// Return true if this function can prove that I is guaranteed to yield
- /// full-poison (all bits poison) if at least one of its operands are
- /// full-poison (all bits poison).
- ///
- /// The exact rules for how poison propagates through instructions have
- /// not been settled as of 2015-07-10, so this function is conservative
- /// and only considers poison to be propagated in uncontroversial
- /// cases. There is no attempt to track values that may be only partially
+ /// Return true if I yields poison or raises UB if any of its operands is
/// poison.
- bool propagatesFullPoison(const Instruction *I);
+ /// Formally, given I = `r = op v1 v2 .. vN`, propagatesPoison returns true
+ /// if, for all i, r is evaluated to poison or op raises UB if vi = poison.
+ /// To filter out operands that raise UB on poison, you can use
+ /// getGuaranteedNonPoisonOp.
+ bool propagatesPoison(const Instruction *I);
/// Return either nullptr or an operand of I such that I will trigger
- /// undefined behavior if I is executed and that operand has a full-poison
- /// value (all bits poison).
- const Value *getGuaranteedNonFullPoisonOp(const Instruction *I);
+ /// undefined behavior if I is executed and that operand has a poison
+ /// value.
+ const Value *getGuaranteedNonPoisonOp(const Instruction *I);
/// Return true if the given instruction must trigger undefined behavior.
/// when I is executed with any operands which appear in KnownPoison holding
- /// a full-poison value at the point of execution.
+ /// a poison value at the point of execution.
bool mustTriggerUB(const Instruction *I,
const SmallSet<const Value *, 16>& KnownPoison);
/// Return true if this function can prove that if PoisonI is executed
- /// and yields a full-poison value (all bits poison), then that will
- /// trigger undefined behavior.
+ /// and yields a poison value, then that will trigger undefined behavior.
///
/// Note that this currently only considers the basic block that is
/// the parent of I.
- bool programUndefinedIfFullPoison(const Instruction *PoisonI);
+ bool programUndefinedIfPoison(const Instruction *PoisonI);
+
+ /// Return true if I can create poison from non-poison operands.
+ /// For vectors, canCreatePoison returns true if there is potential poison in
+ /// any element of the result when vectors without poison are given as
+ /// operands.
+ /// For example, given `I = shl <2 x i32> %x, <0, 32>`, this function returns
+ /// true. If I raises immediate UB but never creates poison (e.g. sdiv I, 0),
+ /// canCreatePoison returns false.
+ bool canCreatePoison(const Instruction *I);
/// Return true if this function can prove that V is never undef value
/// or poison value.
- bool isGuaranteedNotToBeUndefOrPoison(const Value *V);
+ //
+ /// If CtxI and DT are specified this method performs flow-sensitive analysis
+ /// and returns true if it is guaranteed to be never undef or poison
+ /// immediately before the CtxI.
+ bool isGuaranteedNotToBeUndefOrPoison(const Value *V,
+ const Instruction *CtxI = nullptr,
+ const DominatorTree *DT = nullptr,
+ unsigned Depth = 0);
/// Specific patterns of select instructions we can match.
enum SelectPatternFlavor {
@@ -673,12 +713,21 @@ class Value;
Optional<bool> isImpliedCondition(const Value *LHS, const Value *RHS,
const DataLayout &DL, bool LHSIsTrue = true,
unsigned Depth = 0);
+ Optional<bool> isImpliedCondition(const Value *LHS,
+ CmpInst::Predicate RHSPred,
+ const Value *RHSOp0, const Value *RHSOp1,
+ const DataLayout &DL, bool LHSIsTrue = true,
+ unsigned Depth = 0);
/// Return the boolean condition value in the context of the given instruction
/// if it is known based on dominating conditions.
Optional<bool> isImpliedByDomCondition(const Value *Cond,
const Instruction *ContextI,
const DataLayout &DL);
+ Optional<bool> isImpliedByDomCondition(CmpInst::Predicate Pred,
+ const Value *LHS, const Value *RHS,
+ const Instruction *ContextI,
+ const DataLayout &DL);
/// If Ptr1 is provably equal to Ptr2 plus a constant offset, return that
/// offset. For example, Ptr1 might be &A[42], and Ptr2 might be &A[40]. In
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/VecFuncs.def b/contrib/llvm-project/llvm/include/llvm/Analysis/VecFuncs.def
index 86bec0be7546..2f64b0fedc7a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/VecFuncs.def
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/VecFuncs.def
@@ -245,6 +245,29 @@ TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf4", 4)
TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf8", 8)
TLI_DEFINE_VECFUNC("llvm.log.f32", "__svml_logf16", 16)
+TLI_DEFINE_VECFUNC("exp2", "__svml_exp22", 2)
+TLI_DEFINE_VECFUNC("exp2", "__svml_exp24", 4)
+TLI_DEFINE_VECFUNC("exp2", "__svml_exp28", 8)
+
+TLI_DEFINE_VECFUNC("exp2f", "__svml_exp2f4", 4)
+TLI_DEFINE_VECFUNC("exp2f", "__svml_exp2f8", 8)
+TLI_DEFINE_VECFUNC("exp2f", "__svml_exp2f16", 16)
+
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "__svml_exp22", 2)
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "__svml_exp24", 4)
+TLI_DEFINE_VECFUNC("llvm.exp2.f64", "__svml_exp28", 8)
+
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "__svml_exp2f4", 4)
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "__svml_exp2f8", 8)
+TLI_DEFINE_VECFUNC("llvm.exp2.f32", "__svml_exp2f16", 16)
+
+TLI_DEFINE_VECFUNC("__exp2_finite", "__svml_exp22", 2)
+TLI_DEFINE_VECFUNC("__exp2_finite", "__svml_exp24", 4)
+TLI_DEFINE_VECFUNC("__exp2_finite", "__svml_exp28", 8)
+
+TLI_DEFINE_VECFUNC("__exp2f_finite", "__svml_exp2f4", 4)
+TLI_DEFINE_VECFUNC("__exp2f_finite", "__svml_exp2f8", 8)
+TLI_DEFINE_VECFUNC("__exp2f_finite", "__svml_exp2f16", 16)
#else
#error "Must choose which vector library functions are to be defined."
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/VectorUtils.h b/contrib/llvm-project/llvm/include/llvm/Analysis/VectorUtils.h
index 0ca69bebc127..b1d7850442fb 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Analysis/VectorUtils.h
@@ -16,7 +16,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/IR/IRBuilder.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Support/CheckedArithmetic.h"
namespace llvm {
@@ -63,7 +63,7 @@ struct VFParameter {
unsigned ParamPos; // Parameter Position in Scalar Function.
VFParamKind ParamKind; // Kind of Parameter.
int LinearStepOrPos = 0; // Step or Position of the Parameter.
- Align Alignment = Align(); // Optional aligment in bytes, defaulted to 1.
+ Align Alignment = Align(); // Optional alignment in bytes, defaulted to 1.
// Comparison operator.
bool operator==(const VFParameter &Other) const {
@@ -82,7 +82,7 @@ struct VFParameter {
struct VFShape {
unsigned VF; // Vectorization factor.
bool IsScalable; // True if the function is a scalable function.
- SmallVector<VFParameter, 8> Parameters; // List of parameter informations.
+ SmallVector<VFParameter, 8> Parameters; // List of parameter information.
// Comparison operator.
bool operator==(const VFShape &Other) const {
return std::tie(VF, IsScalable, Parameters) ==
@@ -96,6 +96,12 @@ struct VFShape {
assert(hasValidParameterList() && "Invalid parameter list");
}
+ // Retrieve the VFShape that can be used to map a (scalar) function to itself,
+ // with VF = 1.
+ static VFShape getScalarShape(const CallInst &CI) {
+ return VFShape::get(CI, /*EC*/ {1, false}, /*HasGlobalPredicate*/ false);
+ }
+
// Retrieve the basic vectorization shape of the function, where all
// parameters are mapped to VFParamKind::Vector with \p EC
// lanes. Specifies whether the function has a Global Predicate
@@ -116,10 +122,10 @@ struct VFShape {
/// Holds the VFShape for a specific scalar to vector function mapping.
struct VFInfo {
- VFShape Shape; // Classification of the vector function.
- StringRef ScalarName; // Scalar Function Name.
- StringRef VectorName; // Vector Function Name associated to this VFInfo.
- VFISAKind ISA; // Instruction Set Architecture.
+ VFShape Shape; /// Classification of the vector function.
+ std::string ScalarName; /// Scalar Function Name.
+ std::string VectorName; /// Vector Function Name associated to this VFInfo.
+ VFISAKind ISA; /// Instruction Set Architecture.
// Comparison operator.
bool operator==(const VFInfo &Other) const {
@@ -131,15 +137,22 @@ struct VFInfo {
namespace VFABI {
/// LLVM Internal VFABI ISA token for vector functions.
static constexpr char const *_LLVM_ = "_LLVM_";
-
-/// Function to contruct a VFInfo out of a mangled names in the
+/// Prefix for internal name redirection for vector function that
+/// tells the compiler to scalarize the call using the scalar name
+/// of the function. For example, a mangled name like
+/// `_ZGV_LLVM_N2v_foo(_LLVM_Scalarize_foo)` would tell the
+/// vectorizer to vectorize the scalar call `foo`, and to scalarize
+/// it once vectorization is done.
+static constexpr char const *_LLVM_Scalarize_ = "_LLVM_Scalarize_";
+
+/// Function to construct a VFInfo out of a mangled names in the
/// following format:
///
/// <VFABI_name>{(<redirection>)}
///
/// where <VFABI_name> is the name of the vector function, mangled according
/// to the rules described in the Vector Function ABI of the target vector
-/// extentsion (or <isa> from now on). The <VFABI_name> is in the following
+/// extension (or <isa> from now on). The <VFABI_name> is in the following
/// format:
///
/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)]
@@ -153,7 +166,31 @@ static constexpr char const *_LLVM_ = "_LLVM_";
///
/// \param MangledName -> input string in the format
/// _ZGV<isa><mask><vlen><parameters>_<scalarname>[(<redirection>)].
-Optional<VFInfo> tryDemangleForVFABI(StringRef MangledName);
+/// \param M -> Module used to retrieve informations about the vector
+/// function that are not possible to retrieve from the mangled
+/// name. At the moment, this parameter is needed only to retrieve the
+/// Vectorization Factor of scalable vector functions from their
+/// respective IR declarations.
+Optional<VFInfo> tryDemangleForVFABI(StringRef MangledName, const Module &M);
+
+/// This routine mangles the given VectorName according to the LangRef
+/// specification for vector-function-abi-variant attribute and is specific to
+/// the TLI mappings. It is the responsibility of the caller to make sure that
+/// this is only used if all parameters in the vector function are vector type.
+/// This returned string holds scalar-to-vector mapping:
+/// _ZGV<isa><mask><vlen><vparams>_<scalarname>(<vectorname>)
+///
+/// where:
+///
+/// <isa> = "_LLVM_"
+/// <mask> = "N". Note: TLI does not support masked interfaces.
+/// <vlen> = Number of concurrent lanes, stored in the `VectorizationFactor`
+/// field of the `VecDesc` struct.
+/// <vparams> = "v", as many as are the numArgs.
+/// <scalarname> = the name of the scalar function.
+/// <vectorname> = the name of the vector function.
+std::string mangleTLIVectorName(StringRef VectorName, StringRef ScalarName,
+ unsigned numArgs, unsigned VF);
/// Retrieve the `VFParamKind` from a string token.
VFParamKind getVFParamKindFromString(const StringRef Token);
@@ -162,15 +199,96 @@ VFParamKind getVFParamKindFromString(const StringRef Token);
static constexpr char const *MappingsAttrName = "vector-function-abi-variant";
/// Populates a set of strings representing the Vector Function ABI variants
-/// associated to the CallInst CI.
+/// associated to the CallInst CI. If the CI does not contain the
+/// vector-function-abi-variant attribute, we return without populating
+/// VariantMappings, i.e. callers of getVectorVariantNames need not check for
+/// the presence of the attribute (see InjectTLIMappings).
void getVectorVariantNames(const CallInst &CI,
SmallVectorImpl<std::string> &VariantMappings);
} // end namespace VFABI
+/// The Vector Function Database.
+///
+/// Helper class used to find the vector functions associated to a
+/// scalar CallInst.
+class VFDatabase {
+ /// The Module of the CallInst CI.
+ const Module *M;
+ /// The CallInst instance being queried for scalar to vector mappings.
+ const CallInst &CI;
+ /// List of vector functions descriptors associated to the call
+ /// instruction.
+ const SmallVector<VFInfo, 8> ScalarToVectorMappings;
+
+ /// Retrieve the scalar-to-vector mappings associated to the rule of
+ /// a vector Function ABI.
+ static void getVFABIMappings(const CallInst &CI,
+ SmallVectorImpl<VFInfo> &Mappings) {
+ if (!CI.getCalledFunction())
+ return;
+
+ const StringRef ScalarName = CI.getCalledFunction()->getName();
+
+ SmallVector<std::string, 8> ListOfStrings;
+ // The check for the vector-function-abi-variant attribute is done when
+ // retrieving the vector variant names here.
+ VFABI::getVectorVariantNames(CI, ListOfStrings);
+ if (ListOfStrings.empty())
+ return;
+ for (const auto &MangledName : ListOfStrings) {
+ const Optional<VFInfo> Shape =
+ VFABI::tryDemangleForVFABI(MangledName, *(CI.getModule()));
+ // A match is found via scalar and vector names, and also by
+ // ensuring that the variant described in the attribute has a
+ // corresponding definition or declaration of the vector
+ // function in the Module M.
+ if (Shape.hasValue() && (Shape.getValue().ScalarName == ScalarName)) {
+ assert(CI.getModule()->getFunction(Shape.getValue().VectorName) &&
+ "Vector function is missing.");
+ Mappings.push_back(Shape.getValue());
+ }
+ }
+ }
+
+public:
+ /// Retrieve all the VFInfo instances associated to the CallInst CI.
+ static SmallVector<VFInfo, 8> getMappings(const CallInst &CI) {
+ SmallVector<VFInfo, 8> Ret;
+
+ // Get mappings from the Vector Function ABI variants.
+ getVFABIMappings(CI, Ret);
+
+ // Other non-VFABI variants should be retrieved here.
+
+ return Ret;
+ }
+
+ /// Constructor, requires a CallInst instance.
+ VFDatabase(CallInst &CI)
+ : M(CI.getModule()), CI(CI),
+ ScalarToVectorMappings(VFDatabase::getMappings(CI)) {}
+ /// \defgroup VFDatabase query interface.
+ ///
+ /// @{
+ /// Retrieve the Function with VFShape \p Shape.
+ Function *getVectorizedFunction(const VFShape &Shape) const {
+ if (Shape == VFShape::getScalarShape(CI))
+ return CI.getCalledFunction();
+
+ for (const auto &Info : ScalarToVectorMappings)
+ if (Info.Shape == Shape)
+ return M->getFunction(Info.VectorName);
+
+ return nullptr;
+ }
+ /// @}
+};
+
template <typename T> class ArrayRef;
class DemandedBits;
class GetElementPtrInst;
template <typename InstTy> class InterleaveGroup;
+class IRBuilderBase;
class Loop;
class ScalarEvolution;
class TargetTransformInfo;
@@ -181,6 +299,15 @@ namespace Intrinsic {
typedef unsigned ID;
}
+/// A helper function for converting Scalar types to vector types.
+/// If the incoming type is void, we return void. If the VF is 1, we return
+/// the scalar type.
+inline Type *ToVectorTy(Type *Scalar, unsigned VF, bool isScalable = false) {
+ if (Scalar->isVoidTy() || VF == 1)
+ return Scalar;
+ return VectorType::get(Scalar, {VF, isScalable});
+}
+
/// Identify if the intrinsic is trivially vectorizable.
/// This method returns true if the intrinsic's argument types are all scalars
/// for the scalar form of the intrinsic and all vectors (or scalars handled by
@@ -218,16 +345,55 @@ Value *getStrideFromPointer(Value *Ptr, ScalarEvolution *SE, Loop *Lp);
/// from the vector.
Value *findScalarElement(Value *V, unsigned EltNo);
+/// If all non-negative \p Mask elements are the same value, return that value.
+/// If all elements are negative (undefined) or \p Mask contains different
+/// non-negative values, return -1.
+int getSplatIndex(ArrayRef<int> Mask);
+
/// Get splat value if the input is a splat vector or return nullptr.
/// The value may be extracted from a splat constants vector or from
/// a sequence of instructions that broadcast a single value into a vector.
const Value *getSplatValue(const Value *V);
-/// Return true if the input value is known to be a vector with all identical
-/// elements (potentially including undefined elements).
+/// Return true if each element of the vector value \p V is poisoned or equal to
+/// every other non-poisoned element. If an index element is specified, either
+/// every element of the vector is poisoned or the element at that index is not
+/// poisoned and equal to every other non-poisoned element.
/// This may be more powerful than the related getSplatValue() because it is
/// not limited by finding a scalar source value to a splatted vector.
-bool isSplatValue(const Value *V, unsigned Depth = 0);
+bool isSplatValue(const Value *V, int Index = -1, unsigned Depth = 0);
+
+/// Replace each shuffle mask index with the scaled sequential indices for an
+/// equivalent mask of narrowed elements. Mask elements that are less than 0
+/// (sentinel values) are repeated in the output mask.
+///
+/// Example with Scale = 4:
+/// <4 x i32> <3, 2, 0, -1> -->
+/// <16 x i8> <12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, -1, -1, -1, -1>
+///
+/// This is the reverse process of widening shuffle mask elements, but it always
+/// succeeds because the indexes can always be multiplied (scaled up) to map to
+/// narrower vector elements.
+void narrowShuffleMaskElts(int Scale, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask);
+
+/// Try to transform a shuffle mask by replacing elements with the scaled index
+/// for an equivalent mask of widened elements. If all mask elements that would
+/// map to a wider element of the new mask are the same negative number
+/// (sentinel value), that element of the new mask is the same value. If any
+/// element in a given slice is negative and some other element in that slice is
+/// not the same value, return false (partial matches with sentinel values are
+/// not allowed).
+///
+/// Example with Scale = 4:
+/// <16 x i8> <12, 13, 14, 15, 8, 9, 10, 11, 0, 1, 2, 3, -1, -1, -1, -1> -->
+/// <4 x i32> <3, 2, 0, -1>
+///
+/// This is the reverse process of narrowing shuffle mask elements if it
+/// succeeds. This transform is not always possible because indexes may not
+/// divide evenly (scale down) to map to wider vector elements.
+bool widenShuffleMaskElts(int Scale, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask);
/// Compute a map of integer instructions to their minimum legal type
/// size.
@@ -304,7 +470,7 @@ Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL);
/// Note: The result is a mask of 0's and 1's, as opposed to the other
/// create[*]Mask() utilities which create a shuffle mask (mask that
/// consists of indices).
-Constant *createBitMaskForGaps(IRBuilder<> &Builder, unsigned VF,
+Constant *createBitMaskForGaps(IRBuilderBase &Builder, unsigned VF,
const InterleaveGroup<Instruction> &Group);
/// Create a mask with replicated elements.
@@ -319,8 +485,8 @@ Constant *createBitMaskForGaps(IRBuilder<> &Builder, unsigned VF,
/// For example, the mask for \p ReplicationFactor=3 and \p VF=4 is:
///
/// <0,0,0,1,1,1,2,2,2,3,3,3>
-Constant *createReplicatedMask(IRBuilder<> &Builder, unsigned ReplicationFactor,
- unsigned VF);
+llvm::SmallVector<int, 16> createReplicatedMask(unsigned ReplicationFactor,
+ unsigned VF);
/// Create an interleave shuffle mask.
///
@@ -333,8 +499,7 @@ Constant *createReplicatedMask(IRBuilder<> &Builder, unsigned ReplicationFactor,
/// For example, the mask for VF = 4 and NumVecs = 2 is:
///
/// <0, 4, 1, 5, 2, 6, 3, 7>.
-Constant *createInterleaveMask(IRBuilder<> &Builder, unsigned VF,
- unsigned NumVecs);
+llvm::SmallVector<int, 16> createInterleaveMask(unsigned VF, unsigned NumVecs);
/// Create a stride shuffle mask.
///
@@ -348,8 +513,8 @@ Constant *createInterleaveMask(IRBuilder<> &Builder, unsigned VF,
/// For example, the mask for Start = 0, Stride = 2, and VF = 4 is:
///
/// <0, 2, 4, 6>
-Constant *createStrideMask(IRBuilder<> &Builder, unsigned Start,
- unsigned Stride, unsigned VF);
+llvm::SmallVector<int, 16> createStrideMask(unsigned Start, unsigned Stride,
+ unsigned VF);
/// Create a sequential shuffle mask.
///
@@ -362,8 +527,8 @@ Constant *createStrideMask(IRBuilder<> &Builder, unsigned Start,
/// For example, the mask for Start = 0, NumInsts = 4, and NumUndefs = 4 is:
///
/// <0, 1, 2, 3, undef, undef, undef, undef>
-Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start,
- unsigned NumInts, unsigned NumUndefs);
+llvm::SmallVector<int, 16>
+createSequentialMask(unsigned Start, unsigned NumInts, unsigned NumUndefs);
/// Concatenate a list of vectors.
///
@@ -372,7 +537,7 @@ Constant *createSequentialMask(IRBuilder<> &Builder, unsigned Start,
/// their element types should be the same. The number of elements in the
/// vectors should also be the same; however, if the last vector has fewer
/// elements, it will be padded with undefs.
-Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs);
+Value *concatenateVectors(IRBuilderBase &Builder, ArrayRef<Value *> Vecs);
/// Given a mask vector of the form <Y x i1>, Return true if all of the
/// elements of this predicate mask are false or undef. That is, return true
@@ -431,7 +596,11 @@ public:
bool isReverse() const { return Reverse; }
uint32_t getFactor() const { return Factor; }
- uint32_t getAlignment() const { return Alignment.value(); }
+ LLVM_ATTRIBUTE_DEPRECATED(uint32_t getAlignment() const,
+ "Use getAlign instead.") {
+ return Alignment.value();
+ }
+ Align getAlign() const { return Alignment; }
uint32_t getNumMembers() const { return Members.size(); }
/// Try to insert a new member \p Instr with index \p Index and
@@ -564,7 +733,7 @@ public:
const LoopAccessInfo *LAI)
: PSE(PSE), TheLoop(L), DT(DT), LI(LI), LAI(LAI) {}
- ~InterleavedAccessInfo() { reset(); }
+ ~InterleavedAccessInfo() { invalidateGroups(); }
/// Analyze the interleaved accesses and collect them in interleave
/// groups. Substitute symbolic strides using \p Strides.
@@ -575,16 +744,24 @@ public:
/// Invalidate groups, e.g., in case all blocks in loop will be predicated
/// contrary to original assumption. Although we currently prevent group
/// formation for predicated accesses, we may be able to relax this limitation
- /// in the future once we handle more complicated blocks.
- void reset() {
+ /// in the future once we handle more complicated blocks. Returns true if any
+ /// groups were invalidated.
+ bool invalidateGroups() {
+ if (InterleaveGroups.empty()) {
+ assert(
+ !RequiresScalarEpilogue &&
+ "RequiresScalarEpilog should not be set without interleave groups");
+ return false;
+ }
+
InterleaveGroupMap.clear();
for (auto *Ptr : InterleaveGroups)
delete Ptr;
InterleaveGroups.clear();
RequiresScalarEpilogue = false;
+ return true;
}
-
/// Check if \p Instr belongs to any interleave group.
bool isInterleaved(Instruction *Instr) const {
return InterleaveGroupMap.find(Instr) != InterleaveGroupMap.end();
diff --git a/contrib/llvm-project/llvm/include/llvm/AsmParser/Parser.h b/contrib/llvm-project/llvm/include/llvm/AsmParser/Parser.h
index b0c603497805..e1c7f746a335 100644
--- a/contrib/llvm-project/llvm/include/llvm/AsmParser/Parser.h
+++ b/contrib/llvm-project/llvm/include/llvm/AsmParser/Parser.h
@@ -13,18 +13,24 @@
#ifndef LLVM_ASMPARSER_PARSER_H
#define LLVM_ASMPARSER_PARSER_H
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
namespace llvm {
class Constant;
class LLVMContext;
+class MemoryBufferRef;
class Module;
class ModuleSummaryIndex;
struct SlotMapping;
class SMDiagnostic;
class Type;
+typedef llvm::function_ref<Optional<std::string>(StringRef)>
+ DataLayoutCallbackTy;
+
/// This function is a main interface to the LLVM Assembly Parser. It parses
/// an ASCII file that (presumably) contains LLVM Assembly code. It returns a
/// Module (intermediate representation) with the corresponding features. Note
@@ -36,14 +42,9 @@ class Type;
/// \param Context Context in which to allocate globals info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-std::unique_ptr<Module>
-parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
- SlotMapping *Slots = nullptr, bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+std::unique_ptr<Module> parseAssemblyFile(StringRef Filename, SMDiagnostic &Err,
+ LLVMContext &Context,
+ SlotMapping *Slots = nullptr);
/// The function is a secondary interface to the LLVM Assembly Parser. It parses
/// an ASCII string that (presumably) contains LLVM Assembly code. It returns a
@@ -56,16 +57,10 @@ parseAssemblyFile(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
/// \param Context Context in which to allocate globals info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
std::unique_ptr<Module> parseAssemblyString(StringRef AsmString,
SMDiagnostic &Err,
LLVMContext &Context,
- SlotMapping *Slots = nullptr,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+ SlotMapping *Slots = nullptr);
/// Holds the Module and ModuleSummaryIndex returned by the interfaces
/// that parse both.
@@ -86,15 +81,16 @@ struct ParsedModuleAndIndex {
/// \param Context Context in which to allocate globals info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-ParsedModuleAndIndex
-parseAssemblyFileWithIndex(StringRef Filename, SMDiagnostic &Err,
- LLVMContext &Context, SlotMapping *Slots = nullptr,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+/// \param DataLayoutCallback Override datalayout in the llvm assembly.
+ParsedModuleAndIndex parseAssemblyFileWithIndex(
+ StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
+ SlotMapping *Slots = nullptr,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
+
+/// Only for use in llvm-as for testing; this does not produce a valid module.
+ParsedModuleAndIndex parseAssemblyFileWithIndexNoUpgradeDebugInfo(
+ StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
+ SlotMapping *Slots, DataLayoutCallbackTy DataLayoutCallback);
/// This function is a main interface to the LLVM Assembly Parser. It parses
/// an ASCII file that (presumably) contains LLVM Assembly code for a module
@@ -113,15 +109,11 @@ parseSummaryIndexAssemblyFile(StringRef Filename, SMDiagnostic &Err);
/// \param Err Error result info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-std::unique_ptr<Module> parseAssembly(MemoryBufferRef F, SMDiagnostic &Err,
- LLVMContext &Context,
- SlotMapping *Slots = nullptr,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+/// \param DataLayoutCallback Override datalayout in the llvm assembly.
+std::unique_ptr<Module> parseAssembly(
+ MemoryBufferRef F, SMDiagnostic &Err, LLVMContext &Context,
+ SlotMapping *Slots = nullptr,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
/// Parse LLVM Assembly including the summary index from a MemoryBuffer.
///
@@ -129,18 +121,12 @@ std::unique_ptr<Module> parseAssembly(MemoryBufferRef F, SMDiagnostic &Err,
/// \param Err Error result info.
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
///
/// parseAssemblyFileWithIndex is a wrapper around this function.
ParsedModuleAndIndex parseAssemblyWithIndex(MemoryBufferRef F,
SMDiagnostic &Err,
LLVMContext &Context,
- SlotMapping *Slots = nullptr,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+ SlotMapping *Slots = nullptr);
/// Parse LLVM Assembly for summary index from a MemoryBuffer.
///
@@ -163,14 +149,11 @@ parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err);
/// \param Slots The optional slot mapping that will be initialized during
/// parsing.
/// \return true on error.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-bool parseAssemblyInto(MemoryBufferRef F, Module *M, ModuleSummaryIndex *Index,
- SMDiagnostic &Err, SlotMapping *Slots = nullptr,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+/// \param DataLayoutCallback Override datalayout in the llvm assembly.
+bool parseAssemblyInto(
+ MemoryBufferRef F, Module *M, ModuleSummaryIndex *Index, SMDiagnostic &Err,
+ SlotMapping *Slots = nullptr,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
/// Parse a type and a constant value in the given string.
///
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/COFF.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/COFF.h
index 626e0a431e93..1919d7f0dece 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/COFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/COFF.h
@@ -642,6 +642,11 @@ enum DLLCharacteristics : unsigned {
IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE = 0x8000
};
+enum ExtendedDLLCharacteristics : unsigned {
+ /// Image is CET compatible
+ IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT = 0x0001
+};
+
enum DebugType : unsigned {
IMAGE_DEBUG_TYPE_UNKNOWN = 0,
IMAGE_DEBUG_TYPE_COFF = 1,
@@ -660,6 +665,7 @@ enum DebugType : unsigned {
IMAGE_DEBUG_TYPE_ILTCG = 14,
IMAGE_DEBUG_TYPE_MPX = 15,
IMAGE_DEBUG_TYPE_REPRO = 16,
+ IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS = 20,
};
enum BaseRelocationType : unsigned {
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.def
index 3faf3be65032..f0337ef4fb54 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -17,11 +17,12 @@
defined HANDLE_DW_VIRTUALITY || defined HANDLE_DW_DEFAULTED || \
defined HANDLE_DW_CC || defined HANDLE_DW_LNS || defined HANDLE_DW_LNE || \
defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
+ defined HANDLE_MACRO_FLAG || \
defined HANDLE_DW_RLE || defined HANDLE_DW_LLE || \
(defined HANDLE_DW_CFA && defined HANDLE_DW_CFA_PRED) || \
defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
- defined HANDLE_DW_END)
+ defined HANDLE_DW_END || defined HANDLE_DW_SECT)
#error "Missing macro definition of HANDLE_DW*"
#endif
@@ -87,6 +88,10 @@
#define HANDLE_DW_MACRO(ID, NAME)
#endif
+#ifndef HANDLE_MACRO_FLAG
+#define HANDLE_MACRO_FLAG(ID, NAME)
+#endif
+
#ifndef HANDLE_DW_RLE
#define HANDLE_DW_RLE(ID, NAME)
#endif
@@ -112,7 +117,7 @@
#endif
#ifndef HANDLE_DWARF_SECTION
-#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME)
+#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION)
#endif
#ifndef HANDLE_DW_IDX
@@ -123,6 +128,10 @@
#define HANDLE_DW_END(ID, NAME)
#endif
+#ifndef HANDLE_DW_SECT
+#define HANDLE_DW_SECT(ID, NAME)
+#endif
+
HANDLE_DW_TAG(0x0000, null, 2, DWARF, DW_KIND_NONE)
HANDLE_DW_TAG(0x0001, array_type, 2, DWARF, DW_KIND_TYPE)
HANDLE_DW_TAG(0x0002, class_type, 2, DWARF, DW_KIND_TYPE)
@@ -407,7 +416,11 @@ HANDLE_DW_AT(0x3e00, LLVM_include_path, 0, LLVM)
HANDLE_DW_AT(0x3e01, LLVM_config_macros, 0, LLVM)
HANDLE_DW_AT(0x3e02, LLVM_sysroot, 0, LLVM)
HANDLE_DW_AT(0x3e03, LLVM_tag_offset, 0, LLVM)
+// The missing numbers here are reserved for ptrauth support.
+HANDLE_DW_AT(0x3e07, LLVM_apinotes, 0, APPLE)
+
// Apple extensions.
+
HANDLE_DW_AT(0x3fe1, APPLE_optimized, 0, APPLE)
HANDLE_DW_AT(0x3fe2, APPLE_flags, 0, APPLE)
HANDLE_DW_AT(0x3fe3, APPLE_isa, 0, APPLE)
@@ -422,6 +435,7 @@ HANDLE_DW_AT(0x3feb, APPLE_property_attribute, 0, APPLE)
HANDLE_DW_AT(0x3fec, APPLE_objc_complete_type, 0, APPLE)
HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE)
HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE)
+HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE)
// Attribute form encodings.
HANDLE_DW_FORM(0x01, addr, 2, DWARF)
@@ -650,6 +664,7 @@ HANDLE_DW_OP(0xa9, reinterpret, 5, DWARF)
HANDLE_DW_OP(0xe0, GNU_push_tls_address, 0, GNU)
// Extensions for WebAssembly.
HANDLE_DW_OP(0xed, WASM_location, 0, WASM)
+HANDLE_DW_OP(0xee, WASM_location_int, 0, WASM)
// The GNU entry value extension.
HANDLE_DW_OP(0xf3, GNU_entry_value, 0, GNU)
// Extensions for Fission proposal.
@@ -822,6 +837,11 @@ HANDLE_DW_MACRO(0x0a, import_sup)
HANDLE_DW_MACRO(0x0b, define_strx)
HANDLE_DW_MACRO(0x0c, undef_strx)
+// DWARF v5 Macro header flags.
+HANDLE_MACRO_FLAG(0x01, OFFSET_SIZE)
+HANDLE_MACRO_FLAG(0x02, DEBUG_LINE_OFFSET)
+HANDLE_MACRO_FLAG(0x04, OPCODE_OPERANDS_TABLE)
+
// DWARF v5 Range List Entry encoding values.
HANDLE_DW_RLE(0x00, end_of_list)
HANDLE_DW_RLE(0x01, base_addressx)
@@ -878,7 +898,8 @@ HANDLE_DW_CFA_PRED(0x2d, AARCH64_negate_ra_state, SELECT_AARCH64)
HANDLE_DW_CFA_PRED(0x2e, GNU_args_size, SELECT_X86)
// Apple Objective-C Property Attributes.
-// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
+// Keep this list in sync with clang's DeclObjCCommon.h
+// ObjCPropertyAttribute::Kind!
HANDLE_DW_APPLE_PROPERTY(0x01, readonly)
HANDLE_DW_APPLE_PROPERTY(0x02, getter)
HANDLE_DW_APPLE_PROPERTY(0x04, assign)
@@ -903,38 +924,38 @@ HANDLE_DW_UT(0x04, skeleton)
HANDLE_DW_UT(0x05, split_compile)
HANDLE_DW_UT(0x06, split_type)
-// DWARF section types. (enum name, ELF name, ELF DWO name, cmdline name)
+// DWARF section types. (enum name, ELF name, ELF DWO name, cmdline name, option)
// Note that these IDs don't mean anything.
// TODO: Add Mach-O and COFF names.
// Official DWARF sections.
-HANDLE_DWARF_SECTION(DebugAbbrev, ".debug_abbrev", "debug-abbrev")
-HANDLE_DWARF_SECTION(DebugAddr, ".debug_addr", "debug-addr")
-HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges")
-HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info")
-HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
-HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
-HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str")
-HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
-HANDLE_DWARF_SECTION(DebugLoclists, ".debug_loclists", "debug-loclists")
-HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
-HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")
-HANDLE_DWARF_SECTION(DebugNames, ".debug_names", "debug-names")
-HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames")
-HANDLE_DWARF_SECTION(DebugPubtypes, ".debug_pubtypes", "debug-pubtypes")
-HANDLE_DWARF_SECTION(DebugGnuPubnames, ".debug_gnu_pubnames", "debug-gnu-pubnames")
-HANDLE_DWARF_SECTION(DebugGnuPubtypes, ".debug_gnu_pubtypes", "debug-gnu-pubtypes")
-HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges")
-HANDLE_DWARF_SECTION(DebugRnglists, ".debug_rnglists", "debug-rnglists")
-HANDLE_DWARF_SECTION(DebugStr, ".debug_str", "debug-str")
-HANDLE_DWARF_SECTION(DebugStrOffsets, ".debug_str_offsets", "debug-str-offsets")
-HANDLE_DWARF_SECTION(DebugCUIndex, ".debug_cu_index", "debug-cu-index")
-HANDLE_DWARF_SECTION(DebugTUIndex, ".debug_tu_index", "debug-tu-index")
+HANDLE_DWARF_SECTION(DebugAbbrev, ".debug_abbrev", "debug-abbrev", BoolOption)
+HANDLE_DWARF_SECTION(DebugAddr, ".debug_addr", "debug-addr", BoolOption)
+HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges", BoolOption)
+HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info", OffsetOption)
+HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types", OffsetOption)
+HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line", OffsetOption)
+HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str", BoolOption)
+HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc", OffsetOption)
+HANDLE_DWARF_SECTION(DebugLoclists, ".debug_loclists", "debug-loclists", OffsetOption)
+HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame", OffsetOption)
+HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro", BoolOption)
+HANDLE_DWARF_SECTION(DebugNames, ".debug_names", "debug-names", BoolOption)
+HANDLE_DWARF_SECTION(DebugPubnames, ".debug_pubnames", "debug-pubnames", BoolOption)
+HANDLE_DWARF_SECTION(DebugPubtypes, ".debug_pubtypes", "debug-pubtypes", BoolOption)
+HANDLE_DWARF_SECTION(DebugGnuPubnames, ".debug_gnu_pubnames", "debug-gnu-pubnames", BoolOption)
+HANDLE_DWARF_SECTION(DebugGnuPubtypes, ".debug_gnu_pubtypes", "debug-gnu-pubtypes", BoolOption)
+HANDLE_DWARF_SECTION(DebugRanges, ".debug_ranges", "debug-ranges", BoolOption)
+HANDLE_DWARF_SECTION(DebugRnglists, ".debug_rnglists", "debug-rnglists", BoolOption)
+HANDLE_DWARF_SECTION(DebugStr, ".debug_str", "debug-str", BoolOption)
+HANDLE_DWARF_SECTION(DebugStrOffsets, ".debug_str_offsets", "debug-str-offsets", BoolOption)
+HANDLE_DWARF_SECTION(DebugCUIndex, ".debug_cu_index", "debug-cu-index", BoolOption)
+HANDLE_DWARF_SECTION(DebugTUIndex, ".debug_tu_index", "debug-tu-index", BoolOption)
// Vendor extensions.
-HANDLE_DWARF_SECTION(AppleNames, ".apple_names", "apple-names")
-HANDLE_DWARF_SECTION(AppleTypes, ".apple_types", "apple-types")
-HANDLE_DWARF_SECTION(AppleNamespaces, ".apple_namespaces", "apple-namespaces")
-HANDLE_DWARF_SECTION(AppleObjC, ".apple_objc", "apple-objc")
-HANDLE_DWARF_SECTION(GdbIndex, ".gdb_index", "gdb-index")
+HANDLE_DWARF_SECTION(AppleNames, ".apple_names", "apple-names", BoolOption)
+HANDLE_DWARF_SECTION(AppleTypes, ".apple_types", "apple-types", BoolOption)
+HANDLE_DWARF_SECTION(AppleNamespaces, ".apple_namespaces", "apple-namespaces", BoolOption)
+HANDLE_DWARF_SECTION(AppleObjC, ".apple_objc", "apple-objc", BoolOption)
+HANDLE_DWARF_SECTION(GdbIndex, ".gdb_index", "gdb-index", BoolOption)
HANDLE_DW_IDX(0x01, compile_unit)
HANDLE_DW_IDX(0x02, type_unit)
@@ -942,6 +963,15 @@ HANDLE_DW_IDX(0x03, die_offset)
HANDLE_DW_IDX(0x04, parent)
HANDLE_DW_IDX(0x05, type_hash)
+// DWARF package file section identifiers.
+// DWARFv5, section 7.3.5.3, table 7.1.
+HANDLE_DW_SECT(1, INFO)
+HANDLE_DW_SECT(3, ABBREV)
+HANDLE_DW_SECT(4, LINE)
+HANDLE_DW_SECT(5, LOCLISTS)
+HANDLE_DW_SECT(6, STR_OFFSETS)
+HANDLE_DW_SECT(7, MACRO)
+HANDLE_DW_SECT(8, RNGLISTS)
#undef HANDLE_DW_TAG
#undef HANDLE_DW_AT
@@ -956,6 +986,7 @@ HANDLE_DW_IDX(0x05, type_hash)
#undef HANDLE_DW_LNE
#undef HANDLE_DW_LNCT
#undef HANDLE_DW_MACRO
+#undef HANDLE_MACRO_FLAG
#undef HANDLE_DW_RLE
#undef HANDLE_DW_LLE
#undef HANDLE_DW_CFA
@@ -965,3 +996,4 @@ HANDLE_DW_IDX(0x05, type_hash)
#undef HANDLE_DWARF_SECTION
#undef HANDLE_DW_IDX
#undef HANDLE_DW_END
+#undef HANDLE_DW_SECT
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.h
index 2ad201831d2b..4e8b708f39bb 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -357,7 +357,8 @@ enum Constants {
};
/// Constants for the DW_APPLE_PROPERTY_attributes attribute.
-/// Keep this list in sync with clang's DeclSpec.h ObjCPropertyAttributeKind!
+/// Keep this list in sync with clang's DeclObjCCommon.h
+/// ObjCPropertyAttribute::Kind!
enum ApplePropertyAttributes {
#define HANDLE_DW_APPLE_PROPERTY(ID, NAME) DW_APPLE_PROPERTY_##NAME = ID,
#include "llvm/BinaryFormat/Dwarf.def"
@@ -470,6 +471,7 @@ StringRef ArrayOrderString(unsigned Order);
StringRef LNStandardString(unsigned Standard);
StringRef LNExtendedString(unsigned Encoding);
StringRef MacinfoString(unsigned Encoding);
+StringRef MacroString(unsigned Encoding);
StringRef RangeListEncodingString(unsigned Encoding);
StringRef LocListEncodingString(unsigned Encoding);
StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch);
@@ -479,6 +481,8 @@ StringRef AtomTypeString(unsigned Atom);
StringRef GDBIndexEntryKindString(GDBIndexEntryKind Kind);
StringRef GDBIndexEntryLinkageString(GDBIndexEntryLinkage Linkage);
StringRef IndexString(unsigned Idx);
+StringRef FormatString(DwarfFormat Format);
+StringRef FormatString(bool IsDWARF64);
/// @}
/// \defgroup DwarfConstantsParsing Dwarf constants parsing functions
@@ -498,6 +502,7 @@ unsigned getLanguage(StringRef LanguageString);
unsigned getCallingConvention(StringRef LanguageString);
unsigned getAttributeEncoding(StringRef EncodingString);
unsigned getMacinfo(StringRef MacinfoString);
+unsigned getMacro(StringRef MacroString);
/// @}
/// \defgroup DwarfConstantsVersioning Dwarf version for constants
@@ -532,6 +537,17 @@ unsigned LanguageVendor(SourceLanguage L);
Optional<unsigned> LanguageLowerBound(SourceLanguage L);
+/// The size of a reference determined by the DWARF 32/64-bit format.
+inline uint8_t getDwarfOffsetByteSize(DwarfFormat Format) {
+ switch (Format) {
+ case DwarfFormat::DWARF32:
+ return 4;
+ case DwarfFormat::DWARF64:
+ return 8;
+ }
+ llvm_unreachable("Invalid Format value");
+}
+
/// A helper struct providing information about the byte size of DW_FORM
/// values that vary in size depending on the DWARF version, address byte
/// size, or DWARF32/DWARF64.
@@ -551,13 +567,7 @@ struct FormParams {
/// The size of a reference is determined by the DWARF 32/64-bit format.
uint8_t getDwarfOffsetByteSize() const {
- switch (Format) {
- case DwarfFormat::DWARF32:
- return 4;
- case DwarfFormat::DWARF64:
- return 8;
- }
- llvm_unreachable("Invalid Format value");
+ return dwarf::getDwarfOffsetByteSize(Format);
}
explicit operator bool() const { return Version && AddrSize; }
@@ -654,6 +664,16 @@ template <> struct EnumTraits<Tag> : public std::true_type {
static constexpr char Type[4] = "TAG";
static constexpr StringRef (*StringFn)(unsigned) = &TagString;
};
+
+template <> struct EnumTraits<LineNumberOps> : public std::true_type {
+ static constexpr char Type[4] = "LNS";
+ static constexpr StringRef (*StringFn)(unsigned) = &LNStandardString;
+};
+
+template <> struct EnumTraits<LocationAtom> : public std::true_type {
+ static constexpr char Type[3] = "OP";
+ static constexpr StringRef (*StringFn)(unsigned) = &OperationEncodingString;
+};
} // End of namespace dwarf
/// Dwarf constants format_provider
@@ -662,8 +682,7 @@ template <> struct EnumTraits<Tag> : public std::true_type {
/// dumping functions above, these format unknown enumerator values as
/// DW_TYPE_unknown_1234 (e.g. DW_TAG_unknown_ffff).
template <typename Enum>
-struct format_provider<
- Enum, typename std::enable_if<dwarf::EnumTraits<Enum>::value>::type> {
+struct format_provider<Enum, std::enable_if_t<dwarf::EnumTraits<Enum>::value>> {
static void format(const Enum &E, raw_ostream &OS, StringRef Style) {
StringRef Str = dwarf::EnumTraits<Enum>::StringFn(E);
if (Str.empty()) {
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h
index 6488aeb7e41e..bdcf10fd1640 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELF.h
@@ -311,6 +311,7 @@ enum {
EM_RISCV = 243, // RISC-V
EM_LANAI = 244, // Lanai 32-bit processor
EM_BPF = 247, // Linux kernel bpf virtual machine
+ EM_VE = 251, // NEC SX-Aurora VE
};
// Object file classes.
@@ -393,12 +394,6 @@ static inline int64_t decodePPC64LocalEntryOffset(unsigned Other) {
unsigned Val = (Other & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT;
return ((1 << Val) >> 2) << 2;
}
-static inline unsigned encodePPC64LocalEntryOffset(int64_t Offset) {
- unsigned Val =
- (Offset >= 4 * 4 ? (Offset >= 8 * 4 ? (Offset >= 16 * 4 ? 6 : 5) : 4)
- : (Offset >= 2 * 4 ? 3 : (Offset >= 1 * 4 ? 2 : 0)));
- return Val << STO_PPC64_LOCAL_BIT;
-}
// ELF Relocation types for PPC64
enum {
@@ -573,15 +568,17 @@ enum {
// Hexagon-specific e_flags
enum {
// Object processor version flags, bits[11:0]
- EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2
- EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3
- EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4
- EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5
- EF_HEXAGON_MACH_V55 = 0x00000005, // Hexagon V55
- EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60
- EF_HEXAGON_MACH_V62 = 0x00000062, // Hexagon V62
- EF_HEXAGON_MACH_V65 = 0x00000065, // Hexagon V65
- EF_HEXAGON_MACH_V66 = 0x00000066, // Hexagon V66
+ EF_HEXAGON_MACH_V2 = 0x00000001, // Hexagon V2
+ EF_HEXAGON_MACH_V3 = 0x00000002, // Hexagon V3
+ EF_HEXAGON_MACH_V4 = 0x00000003, // Hexagon V4
+ EF_HEXAGON_MACH_V5 = 0x00000004, // Hexagon V5
+ EF_HEXAGON_MACH_V55 = 0x00000005, // Hexagon V55
+ EF_HEXAGON_MACH_V60 = 0x00000060, // Hexagon V60
+ EF_HEXAGON_MACH_V62 = 0x00000062, // Hexagon V62
+ EF_HEXAGON_MACH_V65 = 0x00000065, // Hexagon V65
+ EF_HEXAGON_MACH_V66 = 0x00000066, // Hexagon V66
+ EF_HEXAGON_MACH_V67 = 0x00000067, // Hexagon V67
+ EF_HEXAGON_MACH_V67T = 0x00008067, // Hexagon V67T
// Highest ISA version flags
EF_HEXAGON_ISA_MACH = 0x00000000, // Same as specified in bits[11:0]
@@ -595,6 +592,7 @@ enum {
EF_HEXAGON_ISA_V62 = 0x00000062, // Hexagon V62 ISA
EF_HEXAGON_ISA_V65 = 0x00000065, // Hexagon V65 ISA
EF_HEXAGON_ISA_V66 = 0x00000066, // Hexagon V66 ISA
+ EF_HEXAGON_ISA_V67 = 0x00000067, // Hexagon V67 ISA
};
// Hexagon-specific section indexes for common small data
@@ -708,6 +706,7 @@ enum : unsigned {
EF_AMDGPU_MACH_AMDGCN_GFX1010 = 0x033,
EF_AMDGPU_MACH_AMDGCN_GFX1011 = 0x034,
EF_AMDGPU_MACH_AMDGCN_GFX1012 = 0x035,
+ EF_AMDGPU_MACH_AMDGCN_GFX1030 = 0x036,
// Reserved for AMDGCN-based processors.
EF_AMDGPU_MACH_AMDGCN_RESERVED0 = 0x027,
@@ -715,7 +714,7 @@ enum : unsigned {
// First/last AMDGCN-based processors.
EF_AMDGPU_MACH_AMDGCN_FIRST = EF_AMDGPU_MACH_AMDGCN_GFX600,
- EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX1012,
+ EF_AMDGPU_MACH_AMDGCN_LAST = EF_AMDGPU_MACH_AMDGCN_GFX1030,
// Indicates if the "xnack" target feature is enabled for all code contained
// in the object.
@@ -767,6 +766,11 @@ enum {
#include "ELFRelocs/MSP430.def"
};
+// ELF Relocation type for VE.
+enum {
+#include "ELFRelocs/VE.def"
+};
+
#undef ELF_RELOC
// Section header.
@@ -813,50 +817,51 @@ enum {
// Section types.
enum : unsigned {
- SHT_NULL = 0, // No associated section (inactive entry).
- SHT_PROGBITS = 1, // Program-defined contents.
- SHT_SYMTAB = 2, // Symbol table.
- SHT_STRTAB = 3, // String table.
- SHT_RELA = 4, // Relocation entries; explicit addends.
- SHT_HASH = 5, // Symbol hash table.
- SHT_DYNAMIC = 6, // Information for dynamic linking.
- SHT_NOTE = 7, // Information about the file.
- SHT_NOBITS = 8, // Data occupies no space in the file.
- SHT_REL = 9, // Relocation entries; no explicit addends.
- SHT_SHLIB = 10, // Reserved.
- SHT_DYNSYM = 11, // Symbol table.
- SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
- SHT_FINI_ARRAY = 15, // Pointers to termination functions.
- SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
- SHT_GROUP = 17, // Section group.
- SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_INIT_ARRAY = 14, // Pointers to initialization functions.
+ SHT_FINI_ARRAY = 15, // Pointers to termination functions.
+ SHT_PREINIT_ARRAY = 16, // Pointers to pre-init functions.
+ SHT_GROUP = 17, // Section group.
+ SHT_SYMTAB_SHNDX = 18, // Indices for SHN_XINDEX entries.
// Experimental support for SHT_RELR sections. For details, see proposal
// at https://groups.google.com/forum/#!topic/generic-abi/bX460iggiKg
- SHT_RELR = 19, // Relocation entries; only offsets.
- SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
+ SHT_RELR = 19, // Relocation entries; only offsets.
+ SHT_LOOS = 0x60000000, // Lowest operating system-specific type.
// Android packed relocation section types.
// https://android.googlesource.com/platform/bionic/+/6f12bfece5dcc01325e0abba56a46b1bcf991c69/tools/relocation_packer/src/elf_file.cc#37
SHT_ANDROID_REL = 0x60000001,
SHT_ANDROID_RELA = 0x60000002,
- SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
- SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
+ SHT_LLVM_ODRTAB = 0x6fff4c00, // LLVM ODR table.
+ SHT_LLVM_LINKER_OPTIONS = 0x6fff4c01, // LLVM Linker Options.
SHT_LLVM_CALL_GRAPH_PROFILE = 0x6fff4c02, // LLVM Call Graph Profile.
- SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols
- // for safe ICF.
- SHT_LLVM_DEPENDENT_LIBRARIES = 0x6fff4c04, // LLVM Dependent Library Specifiers.
- SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
- SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
- SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
+ SHT_LLVM_ADDRSIG = 0x6fff4c03, // List of address-significant symbols
+ // for safe ICF.
+ SHT_LLVM_DEPENDENT_LIBRARIES =
+ 0x6fff4c04, // LLVM Dependent Library Specifiers.
+ SHT_LLVM_SYMPART = 0x6fff4c05, // Symbol partition specification.
+ SHT_LLVM_PART_EHDR = 0x6fff4c06, // ELF header for loadable partition.
+ SHT_LLVM_PART_PHDR = 0x6fff4c07, // Phdrs for loadable partition.
// Android's experimental support for SHT_RELR sections.
// https://android.googlesource.com/platform/bionic/+/b7feec74547f84559a1467aca02708ff61346d2a/libc/include/elf.h#512
- SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
- SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
- SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
- SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
- SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
- SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
- SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
- SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
+ SHT_ANDROID_RELR = 0x6fffff00, // Relocation entries; only offsets.
+ SHT_GNU_ATTRIBUTES = 0x6ffffff5, // Object attributes.
+ SHT_GNU_HASH = 0x6ffffff6, // GNU-style hash table.
+ SHT_GNU_verdef = 0x6ffffffd, // GNU version definitions.
+ SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
+ SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
+ SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
+ SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
// Fixme: All this is duplicated in MCSectionELF. Why??
// Exception Index table
SHT_ARM_EXIDX = 0x70000001U,
@@ -866,20 +871,22 @@ enum : unsigned {
SHT_ARM_ATTRIBUTES = 0x70000003U,
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
- SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
- // this section based on their sizes
- SHT_X86_64_UNWIND = 0x70000001, // Unwind information
+ SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
+ // this section based on their sizes
+ SHT_X86_64_UNWIND = 0x70000001, // Unwind information
- SHT_MIPS_REGINFO = 0x70000006, // Register usage information
- SHT_MIPS_OPTIONS = 0x7000000d, // General options
- SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
- SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
+ SHT_MIPS_REGINFO = 0x70000006, // Register usage information
+ SHT_MIPS_OPTIONS = 0x7000000d, // General options
+ SHT_MIPS_DWARF = 0x7000001e, // DWARF debugging section.
+ SHT_MIPS_ABIFLAGS = 0x7000002a, // ABI information.
SHT_MSP430_ATTRIBUTES = 0x70000003U,
- SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
- SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
- SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+ SHT_RISCV_ATTRIBUTES = 0x70000003U,
+
+ SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
};
// Section flags.
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
index c8364133e31f..96a4efe82560 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/AArch64.def
@@ -58,6 +58,7 @@ ELF_RELOC(R_AARCH64_LD64_GOTOFF_LO15, 0x136)
ELF_RELOC(R_AARCH64_ADR_GOT_PAGE, 0x137)
ELF_RELOC(R_AARCH64_LD64_GOT_LO12_NC, 0x138)
ELF_RELOC(R_AARCH64_LD64_GOTPAGE_LO15, 0x139)
+ELF_RELOC(R_AARCH64_PLT32, 0x13a)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PREL21, 0x200)
ELF_RELOC(R_AARCH64_TLSGD_ADR_PAGE21, 0x201)
ELF_RELOC(R_AARCH64_TLSGD_ADD_LO12_NC, 0x202)
@@ -120,6 +121,7 @@ ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12, 0x23a)
ELF_RELOC(R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC, 0x23b)
ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12, 0x23c)
ELF_RELOC(R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC, 0x23d)
+// Dynamic relocations start
ELF_RELOC(R_AARCH64_COPY, 0x400)
ELF_RELOC(R_AARCH64_GLOB_DAT, 0x401)
ELF_RELOC(R_AARCH64_JUMP_SLOT, 0x402)
@@ -162,6 +164,7 @@ ELF_RELOC(R_AARCH64_P32_GOT_LD_PREL19, 0x019)
ELF_RELOC(R_AARCH64_P32_ADR_GOT_PAGE, 0x01a)
ELF_RELOC(R_AARCH64_P32_LD32_GOT_LO12_NC, 0x01b)
ELF_RELOC(R_AARCH64_P32_LD32_GOTPAGE_LO14, 0x01c)
+ELF_RELOC(R_AARCH64_P32_PLT32, 0x01d)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PREL21, 0x050)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADR_PAGE21, 0x051)
ELF_RELOC(R_AARCH64_P32_TLSGD_ADD_LO12_NC, 0x052)
@@ -210,6 +213,7 @@ ELF_RELOC(R_AARCH64_P32_TLSDESC_ADR_PAGE21, 0x07c)
ELF_RELOC(R_AARCH64_P32_TLSDESC_LD32_LO12, 0x07d)
ELF_RELOC(R_AARCH64_P32_TLSDESC_ADD_LO12, 0x07e)
ELF_RELOC(R_AARCH64_P32_TLSDESC_CALL, 0x07f)
+// Dynamic relocations start
ELF_RELOC(R_AARCH64_P32_COPY, 0x0b4)
ELF_RELOC(R_AARCH64_P32_GLOB_DAT, 0x0b5)
ELF_RELOC(R_AARCH64_P32_JUMP_SLOT, 0x0b6)
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
index 719d0c9c36ac..e28c9caaefaf 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
@@ -96,6 +96,9 @@
#undef R_PPC64_TPREL16_HIGHA
#undef R_PPC64_DTPREL16_HIGH
#undef R_PPC64_DTPREL16_HIGHA
+#undef R_PPC64_REL24_NOTOC
+#undef R_PPC64_PCREL34
+#undef R_PPC64_GOT_PCREL34
#undef R_PPC64_IRELATIVE
#undef R_PPC64_REL16
#undef R_PPC64_REL16_LO
@@ -190,6 +193,9 @@ ELF_RELOC(R_PPC64_TPREL16_HIGH, 112)
ELF_RELOC(R_PPC64_TPREL16_HIGHA, 113)
ELF_RELOC(R_PPC64_DTPREL16_HIGH, 114)
ELF_RELOC(R_PPC64_DTPREL16_HIGHA, 115)
+ELF_RELOC(R_PPC64_REL24_NOTOC, 116)
+ELF_RELOC(R_PPC64_PCREL34, 132)
+ELF_RELOC(R_PPC64_GOT_PCREL34, 133)
ELF_RELOC(R_PPC64_IRELATIVE, 248)
ELF_RELOC(R_PPC64_REL16, 249)
ELF_RELOC(R_PPC64_REL16_LO, 250)
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
index 5cc4c0ec3029..9f2f0540bcbd 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/RISCV.def
@@ -57,3 +57,4 @@ ELF_RELOC(R_RISCV_SET8, 54)
ELF_RELOC(R_RISCV_SET16, 55)
ELF_RELOC(R_RISCV_SET32, 56)
ELF_RELOC(R_RISCV_32_PCREL, 57)
+ELF_RELOC(R_RISCV_IRELATIVE, 58)
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/VE.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/VE.def
new file mode 100644
index 000000000000..9bfdbf1b0960
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/VE.def
@@ -0,0 +1,48 @@
+
+#ifndef ELF_RELOC
+#error "ELF_RELOC must be defined"
+#endif
+
+// Relocation types defined in following documents.
+//
+// - System V Application Binary Interface - VE Architecture
+// Processor Supplement
+// - ELF Handling For Thread-Local Storage - VE Architecture
+// Processor Supplement
+
+ELF_RELOC(R_VE_NONE, 0)
+ELF_RELOC(R_VE_REFLONG, 1)
+ELF_RELOC(R_VE_REFQUAD, 2)
+ELF_RELOC(R_VE_SREL32, 3)
+ELF_RELOC(R_VE_HI32, 4)
+ELF_RELOC(R_VE_LO32, 5)
+ELF_RELOC(R_VE_PC_HI32, 6)
+ELF_RELOC(R_VE_PC_LO32, 7)
+ELF_RELOC(R_VE_GOT32, 8)
+ELF_RELOC(R_VE_GOT_HI32, 9)
+ELF_RELOC(R_VE_GOT_LO32, 10)
+ELF_RELOC(R_VE_GOTOFF32, 11)
+ELF_RELOC(R_VE_GOTOFF_HI32, 12)
+ELF_RELOC(R_VE_GOTOFF_LO32, 13)
+ELF_RELOC(R_VE_PLT32, 14)
+ELF_RELOC(R_VE_PLT_HI32, 15)
+ELF_RELOC(R_VE_PLT_LO32, 16)
+ELF_RELOC(R_VE_RELATIVE, 17)
+ELF_RELOC(R_VE_GLOB_DAT, 18)
+ELF_RELOC(R_VE_JUMP_SLOT, 19)
+ELF_RELOC(R_VE_COPY, 20)
+ELF_RELOC(R_VE_DTPMOD64, 22)
+ELF_RELOC(R_VE_DTPOFF64, 23)
+// ELF_RELOC(R_VE_TPOFF64, 24)
+ELF_RELOC(R_VE_TLS_GD_HI32, 25)
+ELF_RELOC(R_VE_TLS_GD_LO32, 26)
+// ELF_RELOC(R_VE_TLS_LD_HI32, 27)
+// ELF_RELOC(R_VE_TLS_LD_LO32, 28)
+// ELF_RELOC(R_VE_DTPOFF32, 29)
+// ELF_RELOC(R_VE_TLS_IE_HI32, 30)
+// ELF_RELOC(R_VE_TLS_IE_LO32, 31)
+ELF_RELOC(R_VE_TPOFF_HI32, 32)
+ELF_RELOC(R_VE_TPOFF_LO32, 33)
+// ELF_RELOC(R_VE_TPOFF32, 34)
+ELF_RELOC(R_VE_CALL_HI32, 35)
+ELF_RELOC(R_VE_CALL_LO32, 36)
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MachO.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MachO.h
index fb50e549cb9d..e43fea0a2465 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MachO.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MachO.h
@@ -15,9 +15,13 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
-#include "llvm/Support/Host.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/SwapByteOrder.h"
namespace llvm {
+
+class Triple;
+
namespace MachO {
// Enums from <mach-o/loader.h>
enum : uint32_t {
@@ -78,7 +82,8 @@ enum {
MH_HAS_TLV_DESCRIPTORS = 0x00800000u,
MH_NO_HEAP_EXECUTION = 0x01000000u,
MH_APP_EXTENSION_SAFE = 0x02000000u,
- MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u
+ MH_NLIST_OUTOFSYNC_WITH_DYLDINFO = 0x04000000u,
+ MH_DYLIB_IN_CACHE = 0x80000000u,
};
enum : uint32_t {
@@ -948,13 +953,8 @@ struct fat_arch_64 {
// Structs from <mach-o/reloc.h>
struct relocation_info {
int32_t r_address;
-#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && (BYTE_ORDER == BIG_ENDIAN)
- uint32_t r_type : 4, r_extern : 1, r_length : 2, r_pcrel : 1,
- r_symbolnum : 24;
-#else
uint32_t r_symbolnum : 24, r_pcrel : 1, r_length : 2, r_extern : 1,
r_type : 4;
-#endif
};
struct scattered_relocation_info {
@@ -1518,6 +1518,9 @@ enum CPUSubTypePowerPC {
CPU_SUBTYPE_MC98601 = CPU_SUBTYPE_POWERPC_601
};
+Expected<uint32_t> getCPUType(const Triple &T);
+Expected<uint32_t> getCPUSubType(const Triple &T);
+
struct x86_thread_state32_t {
uint32_t eax;
uint32_t ebx;
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Magic.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Magic.h
index 64c687262f4a..78227ddbe095 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Magic.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Magic.h
@@ -9,12 +9,12 @@
#ifndef LLVM_BINARYFORMAT_MAGIC_H
#define LLVM_BINARYFORMAT_MAGIC_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
-
#include <system_error>
namespace llvm {
+class StringRef;
+class Twine;
+
/// file_magic - An "enum class" enumeration of file types based on magic (the
/// first N bytes of the file).
struct file_magic {
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackDocument.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackDocument.h
index 824ecc353207..91778f6a99df 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackDocument.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackDocument.h
@@ -62,6 +62,8 @@ protected:
};
public:
+ // Default constructor gives an empty node with no associated Document. All
+ // you can do with it is "isEmpty()".
DocNode() : KindAndDoc(nullptr) {}
// Type methods
@@ -70,8 +72,10 @@ public:
bool isScalar() const { return !isMap() && !isArray(); }
bool isString() const { return getKind() == Type::String; }
- // Accessors
- bool isEmpty() const { return !KindAndDoc; }
+ // Accessors. isEmpty() returns true for both a default-constructed DocNode
+ // that has no associated Document, and the result of getEmptyNode(), which
+ // does have an associated document.
+ bool isEmpty() const { return !KindAndDoc || getKind() == Type::Empty; }
Type getKind() const { return KindAndDoc->Kind; }
Document *getDocument() const { return KindAndDoc->Doc; }
@@ -146,10 +150,10 @@ public:
friend bool operator<(const DocNode &Lhs, const DocNode &Rhs) {
// This has to cope with one or both of the nodes being default-constructed,
// such that KindAndDoc is not set.
+ if (Rhs.isEmpty())
+ return false;
if (Lhs.KindAndDoc != Rhs.KindAndDoc) {
- if (!Rhs.KindAndDoc)
- return false;
- if (!Lhs.KindAndDoc)
+ if (Lhs.isEmpty())
return true;
return (unsigned)Lhs.getKind() < (unsigned)Rhs.getKind();
}
@@ -177,6 +181,11 @@ public:
return !(Lhs < Rhs) && !(Rhs < Lhs);
}
+ /// Inequality operator
+ friend bool operator!=(const DocNode &Lhs, const DocNode &Rhs) {
+ return !(Lhs == Rhs);
+ }
+
/// Convert this node to a string, assuming it is scalar.
std::string toString() const;
@@ -185,6 +194,19 @@ public:
/// not rely on S having a lifetime beyond this call. Tag is "" or a YAML tag.
StringRef fromString(StringRef S, StringRef Tag = "");
+ /// Convenience assignment operators. This only works if the destination
+ /// DocNode has an associated Document, i.e. it was not constructed using the
+ /// default constructor. The string one does not copy, so the string must
+ /// remain valid for the lifetime of the Document. Use fromString to avoid
+ /// that restriction.
+ DocNode &operator=(const char *Val) { return *this = StringRef(Val); }
+ DocNode &operator=(StringRef Val);
+ DocNode &operator=(bool Val);
+ DocNode &operator=(int Val);
+ DocNode &operator=(unsigned Val);
+ DocNode &operator=(int64_t Val);
+ DocNode &operator=(uint64_t Val);
+
private:
// Private constructor setting KindAndDoc, used by methods in Document.
DocNode(const KindAndDocument *KindAndDoc) : KindAndDoc(KindAndDoc) {}
@@ -206,11 +228,21 @@ public:
MapTy::iterator end() { return Map->end(); }
MapTy::iterator find(DocNode Key) { return Map->find(Key); }
MapTy::iterator find(StringRef Key);
+ MapTy::iterator erase(MapTy::const_iterator I) { return Map->erase(I); }
+ size_t erase(DocNode Key) { return Map->erase(Key); }
+ MapTy::iterator erase(MapTy::const_iterator First,
+ MapTy::const_iterator Second) {
+ return Map->erase(First, Second);
+ }
/// Member access. The string data must remain valid for the lifetime of the
/// Document.
DocNode &operator[](StringRef S);
- /// Member access.
+ /// Member access, with convenience versions for an integer key.
DocNode &operator[](DocNode Key);
+ DocNode &operator[](int Key);
+ DocNode &operator[](unsigned Key);
+ DocNode &operator[](int64_t Key);
+ DocNode &operator[](uint64_t Key);
};
/// A DocNode that is an array.
@@ -222,14 +254,15 @@ public:
// Array access methods.
size_t size() const { return Array->size(); }
bool empty() const { return !size(); }
+ DocNode &back() const { return Array->back(); }
ArrayTy::iterator begin() { return Array->begin(); }
ArrayTy::iterator end() { return Array->end(); }
void push_back(DocNode N) {
- assert(N.getDocument() == getDocument());
+ assert(N.isEmpty() || N.getDocument() == getDocument());
Array->push_back(N);
}
- /// Element access. This extends the array if necessary.
+ /// Element access. This extends the array if necessary, with empty nodes.
DocNode &operator[](size_t Index);
};
@@ -247,7 +280,7 @@ class Document {
DocNode Root;
// The KindAndDocument structs pointed to by nodes in the document.
- KindAndDocument KindAndDocs[size_t(Type::Extension) + 1];
+ KindAndDocument KindAndDocs[size_t(Type::Empty) + 1];
// Whether YAML output uses hex for UInt.
bool HexMode = false;
@@ -255,7 +288,7 @@ class Document {
public:
Document() {
clear();
- for (unsigned T = 0; T != size_t(Type::Extension) + 1; ++T)
+ for (unsigned T = 0; T != unsigned(Type::Empty) + 1; ++T)
KindAndDocs[T] = {this, Type(T)};
}
@@ -263,7 +296,13 @@ public:
DocNode &getRoot() { return Root; }
/// Restore the Document to an empty state.
- void clear() { getRoot() = getNode(); }
+ void clear() { getRoot() = getEmptyNode(); }
+
+ /// Create an empty node associated with this Document.
+ DocNode getEmptyNode() {
+ auto N = DocNode(&KindAndDocs[size_t(Type::Empty)]);
+ return N;
+ }
/// Create a nil node associated with this Document.
DocNode getNode() {
@@ -345,15 +384,35 @@ public:
return N.getArray();
}
- /// Read a MsgPack document from a binary MsgPack blob.
- /// The blob data must remain valid for the lifetime of this Document (because
- /// a string object in the document contains a StringRef into the original
- /// blob).
- /// If Multi, then this sets root to an array and adds top-level objects to
- /// it. If !Multi, then it only reads a single top-level object, even if there
- /// are more, and sets root to that.
- /// Returns false if failed due to illegal format.
- bool readFromBlob(StringRef Blob, bool Multi);
+ /// Read a document from a binary msgpack blob, merging into anything already
+ /// in the Document. The blob data must remain valid for the lifetime of this
+ /// Document (because a string object in the document contains a StringRef
+ /// into the original blob). If Multi, then this sets root to an array and
+ /// adds top-level objects to it. If !Multi, then it only reads a single
+ /// top-level object, even if there are more, and sets root to that. Returns
+ /// false if failed due to illegal format or merge error.
+ ///
+ /// The Merger arg is a callback function that is called when the merge has a
+ /// conflict, that is, it is trying to set an item that is already set. If the
+ /// conflict cannot be resolved, the callback function returns -1. If the
+ /// conflict can be resolved, the callback returns a non-negative number and
+ /// sets *DestNode to the resolved node. The returned non-negative number is
+ /// significant only for an array node; it is then the array index to start
+ /// populating at. That allows Merger to choose whether to merge array
+ /// elements (returns 0) or append new elements (returns existing size).
+ ///
+ /// If SrcNode is an array or map, the resolution must be that *DestNode is an
+ /// array or map respectively, although it could be the array or map
+ /// (respectively) that was already there. MapKey is the key if *DestNode is a
+ /// map entry, a nil node otherwise.
+ ///
+ /// The default for Merger is to disallow any conflict.
+ bool readFromBlob(
+ StringRef Blob, bool Multi,
+ function_ref<int(DocNode *DestNode, DocNode SrcNode, DocNode MapKey)>
+ Merger = [](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
+ return -1;
+ });
/// Write a MsgPack document to a binary MsgPack blob.
void writeToBlob(std::string &Blob);
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h
index 2d332f531b23..a6ae542637fd 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/MsgPackReader.h
@@ -33,6 +33,7 @@
#ifndef LLVM_SUPPORT_MSGPACKREADER_H
#define LLVM_SUPPORT_MSGPACKREADER_H
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>
@@ -56,6 +57,7 @@ enum class Type : uint8_t {
Array,
Map,
Extension,
+ Empty, // Used by MsgPackDocument to represent an empty node
};
/// Extension types are composed of a user-defined type ID and an uninterpreted
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Wasm.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Wasm.h
index 59f99cc8cd37..1aca692e30a7 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Wasm.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/Wasm.h
@@ -15,6 +15,7 @@
#define LLVM_BINARYFORMAT_WASM_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -62,8 +63,8 @@ struct WasmExport {
struct WasmLimits {
uint8_t Flags;
- uint32_t Initial;
- uint32_t Maximum;
+ uint64_t Initial;
+ uint64_t Maximum;
};
struct WasmTable {
@@ -76,8 +77,8 @@ struct WasmInitExpr {
union {
int32_t Int32;
int64_t Int64;
- int32_t Float32;
- int64_t Float64;
+ uint32_t Float32;
+ uint64_t Float64;
uint32_t Global;
} Value;
};
@@ -131,7 +132,7 @@ struct WasmFunction {
uint32_t CodeSectionOffset;
uint32_t Size;
uint32_t CodeOffset; // start of Locals and Body
- StringRef ExportName; // from the "export" section
+ Optional<StringRef> ExportName; // from the "export" section
StringRef SymbolName; // from the "linking" section
StringRef DebugName; // from the "name" section
uint32_t Comdat; // from the "comdat info" section
@@ -158,8 +159,8 @@ struct WasmElemSegment {
// the index of the segment, and the offset and size within the segment.
struct WasmDataReference {
uint32_t Segment;
- uint32_t Offset;
- uint32_t Size;
+ uint64_t Offset;
+ uint64_t Size;
};
struct WasmRelocation {
@@ -178,9 +179,12 @@ struct WasmSymbolInfo {
StringRef Name;
uint8_t Kind;
uint32_t Flags;
- StringRef ImportModule; // For undefined symbols the module of the import
- StringRef ImportName; // For undefined symbols the name of the import
- StringRef ExportName; // For symbols to be exported from the final module
+ // For undefined symbols the module of the import
+ Optional<StringRef> ImportModule;
+ // For undefined symbols the name of the import
+ Optional<StringRef> ImportName;
+ // For symbols to be exported from the final module
+ Optional<StringRef> ExportName;
union {
// For function or global symbols, the index in function or global index
// space.
@@ -228,6 +232,7 @@ enum : unsigned {
WASM_TYPE_V128 = 0x7B,
WASM_TYPE_FUNCREF = 0x70,
WASM_TYPE_EXNREF = 0x68,
+ WASM_TYPE_EXTERNREF = 0x6F,
WASM_TYPE_FUNC = 0x60,
WASM_TYPE_NORESULT = 0x40, // for blocks with no result values
};
@@ -249,11 +254,14 @@ enum : unsigned {
WASM_OPCODE_GLOBAL_GET = 0x23,
WASM_OPCODE_GLOBAL_SET = 0x24,
WASM_OPCODE_I32_STORE = 0x36,
+ WASM_OPCODE_I64_STORE = 0x37,
WASM_OPCODE_I32_CONST = 0x41,
WASM_OPCODE_I64_CONST = 0x42,
WASM_OPCODE_F32_CONST = 0x43,
WASM_OPCODE_F64_CONST = 0x44,
WASM_OPCODE_I32_ADD = 0x6a,
+ WASM_OPCODE_I64_ADD = 0x7c,
+ WASM_OPCODE_REF_NULL = 0xd0,
};
// Opcodes used in synthetic functions.
@@ -272,8 +280,10 @@ enum : unsigned {
};
enum : unsigned {
+ WASM_LIMITS_FLAG_NONE = 0x0,
WASM_LIMITS_FLAG_HAS_MAX = 0x1,
WASM_LIMITS_FLAG_IS_SHARED = 0x2,
+ WASM_LIMITS_FLAG_IS_64 = 0x4,
};
enum : unsigned {
@@ -351,6 +361,7 @@ enum class ValType {
F64 = WASM_TYPE_F64,
V128 = WASM_TYPE_V128,
EXNREF = WASM_TYPE_EXNREF,
+ EXTERNREF = WASM_TYPE_EXTERNREF,
};
struct WasmSignature {
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/WasmRelocs.def b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/WasmRelocs.def
index 00dacf72abb0..05c5147e6314 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/WasmRelocs.def
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/WasmRelocs.def
@@ -2,16 +2,21 @@
#error "WASM_RELOC must be defined"
#endif
-WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0)
-WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1)
-WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2)
-WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3)
-WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4)
-WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5)
-WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6)
-WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7)
-WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8)
-WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9)
-WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
-WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
-WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
+WASM_RELOC(R_WASM_FUNCTION_INDEX_LEB, 0)
+WASM_RELOC(R_WASM_TABLE_INDEX_SLEB, 1)
+WASM_RELOC(R_WASM_TABLE_INDEX_I32, 2)
+WASM_RELOC(R_WASM_MEMORY_ADDR_LEB, 3)
+WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB, 4)
+WASM_RELOC(R_WASM_MEMORY_ADDR_I32, 5)
+WASM_RELOC(R_WASM_TYPE_INDEX_LEB, 6)
+WASM_RELOC(R_WASM_GLOBAL_INDEX_LEB, 7)
+WASM_RELOC(R_WASM_FUNCTION_OFFSET_I32, 8)
+WASM_RELOC(R_WASM_SECTION_OFFSET_I32, 9)
+WASM_RELOC(R_WASM_EVENT_INDEX_LEB, 10)
+WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB, 11)
+WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB, 12)
+WASM_RELOC(R_WASM_GLOBAL_INDEX_I32, 13)
+WASM_RELOC(R_WASM_MEMORY_ADDR_LEB64, 14)
+WASM_RELOC(R_WASM_MEMORY_ADDR_SLEB64, 15)
+WASM_RELOC(R_WASM_MEMORY_ADDR_I64, 16)
+WASM_RELOC(R_WASM_MEMORY_ADDR_REL_SLEB64, 17)
diff --git a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/XCOFF.h b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/XCOFF.h
index b6c3aaa51fc4..5a7ce80a2f62 100644
--- a/contrib/llvm-project/llvm/include/llvm/BinaryFormat/XCOFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/BinaryFormat/XCOFF.h
@@ -13,16 +13,23 @@
#ifndef LLVM_BINARYFORMAT_XCOFF_H
#define LLVM_BINARYFORMAT_XCOFF_H
-#include "llvm/ADT/StringRef.h"
-#include <cstdint>
+#include <stddef.h>
+#include <stdint.h>
namespace llvm {
+class StringRef;
+
namespace XCOFF {
// Constants used in the XCOFF definition.
-enum { FileNamePadSize = 6, NameSize = 8, SymbolTableEntrySize = 18 };
-enum ReservedSectionNum { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
+constexpr size_t FileNamePadSize = 6;
+constexpr size_t NameSize = 8;
+constexpr size_t SymbolTableEntrySize = 18;
+constexpr size_t RelocationSerializationSize32 = 10;
+constexpr uint16_t RelocOverflow = 65535;
+
+enum ReservedSectionNum : int16_t { N_DEBUG = -2, N_ABS = -1, N_UNDEF = 0 };
// x_smclas field of x_csect from system header: /usr/include/syms.h
/// Storage Mapping Class definitions.
@@ -54,9 +61,10 @@ enum StorageMappingClass : uint8_t {
XMC_TE = 22 ///< Symbol mapped at the end of TOC
};
-// Flags for defining the section type. Used for the s_flags field of
-// the section header structure. Defined in the system header `scnhdr.h`.
-enum SectionTypeFlags {
+// Flags for defining the section type. Masks for use with the (signed, 32-bit)
+// s_flags field of the section header structure, selecting for values in the
+// lower 16 bits. Defined in the system header `scnhdr.h`.
+enum SectionTypeFlags : int32_t {
STYP_PAD = 0x0008,
STYP_DWARF = 0x0010,
STYP_TEXT = 0x0020,
@@ -72,6 +80,24 @@ enum SectionTypeFlags {
STYP_OVRFLO = 0x8000
};
+/// Values for defining the section subtype of sections of type STYP_DWARF as
+/// they would appear in the (signed, 32-bit) s_flags field of the section
+/// header structure, contributing to the 16 most significant bits. Defined in
+/// the system header `scnhdr.h`.
+enum DwarfSectionSubtypeFlags : int32_t {
+ SSUBTYP_DWINFO = 0x1'0000, ///< DWARF info section
+ SSUBTYP_DWLINE = 0x2'0000, ///< DWARF line section
+ SSUBTYP_DWPBNMS = 0x3'0000, ///< DWARF pubnames section
+ SSUBTYP_DWPBTYP = 0x4'0000, ///< DWARF pubtypes section
+ SSUBTYP_DWARNGE = 0x5'0000, ///< DWARF aranges section
+ SSUBTYP_DWABREV = 0x6'0000, ///< DWARF abbrev section
+ SSUBTYP_DWSTR = 0x7'0000, ///< DWARF str section
+ SSUBTYP_DWRNGES = 0x8'0000, ///< DWARF ranges section
+ SSUBTYP_DWLOC = 0x9'0000, ///< DWARF loc section
+ SSUBTYP_DWFRAME = 0xA'0000, ///< DWARF frame section
+ SSUBTYP_DWMAC = 0xB'0000 ///< DWARF macinfo section
+};
+
// STORAGE CLASSES, n_sclass field of syment.
// The values come from `storclass.h` and `dbxstclass.h`.
enum StorageClass : uint8_t {
@@ -141,7 +167,10 @@ enum StorageClass : uint8_t {
C_TCSYM = 134 // Reserved
};
-enum SymbolType {
+// Flags for defining the symbol type. Values to be encoded into the lower 3
+// bits of the (unsigned, 8-bit) x_smtyp field of csect auxiliary symbol table
+// entries. Defined in the system header `syms.h`.
+enum SymbolType : uint8_t {
XTY_ER = 0, ///< External reference.
XTY_SD = 1, ///< Csect definition for initialized storage.
XTY_LD = 2, ///< Label definition.
@@ -149,6 +178,17 @@ enum SymbolType {
XTY_CM = 3 ///< Common csect definition. For uninitialized storage.
};
+/// Values for visibility as they would appear when encoded in the high 4 bits
+/// of the 16-bit unsigned n_type field of symbol table entries. Valid for
+/// 32-bit XCOFF only when the vstamp in the auxiliary header is greater than 1.
+enum VisibilityType : uint16_t {
+ SYM_V_UNSPECIFIED = 0x0000,
+ SYM_V_INTERNAL = 0x1000,
+ SYM_V_HIDDEN = 0x2000,
+ SYM_V_PROTECTED = 0x3000,
+ SYM_V_EXPORTED = 0x4000
+};
+
// Relocation types, defined in `/usr/include/reloc.h`.
enum RelocationType : uint8_t {
R_POS = 0x00, ///< Positive relocation. Provides the address of the referenced
@@ -253,6 +293,7 @@ enum CFileCpuId : uint8_t {
};
StringRef getMappingClassString(XCOFF::StorageMappingClass SMC);
+StringRef getRelocationTypeString(XCOFF::RelocationType Type);
} // end namespace XCOFF
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Bitcode/BitcodeReader.h b/contrib/llvm-project/llvm/include/llvm/Bitcode/BitcodeReader.h
index ba61da733bea..a82791c8720b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -31,6 +31,9 @@ namespace llvm {
class LLVMContext;
class Module;
+typedef llvm::function_ref<Optional<std::string>(StringRef)>
+ DataLayoutCallbackTy;
+
// These functions are for converting Expected/Error values to
// ErrorOr/std::error_code for compatibility with legacy clients. FIXME:
// Remove these functions once no longer needed by the C and libLTO APIs.
@@ -77,10 +80,10 @@ class Module;
friend Expected<BitcodeFileContents>
getBitcodeFileContents(MemoryBufferRef Buffer);
- Expected<std::unique_ptr<Module>> getModuleImpl(LLVMContext &Context,
- bool MaterializeAll,
- bool ShouldLazyLoadMetadata,
- bool IsImporting);
+ Expected<std::unique_ptr<Module>>
+ getModuleImpl(LLVMContext &Context, bool MaterializeAll,
+ bool ShouldLazyLoadMetadata, bool IsImporting,
+ DataLayoutCallbackTy DataLayoutCallback);
public:
StringRef getBuffer() const {
@@ -100,7 +103,9 @@ class Module;
bool IsImporting);
/// Read the entire bitcode module and return it.
- Expected<std::unique_ptr<Module>> parseModule(LLVMContext &Context);
+ Expected<std::unique_ptr<Module>> parseModule(
+ LLVMContext &Context, DataLayoutCallbackTy DataLayoutCallback =
+ [](StringRef) { return None; });
/// Returns information about the module to be used for LTO: whether to
/// compile with ThinLTO, and whether it has a summary.
@@ -163,8 +168,11 @@ class Module;
Expected<std::string> getBitcodeProducerString(MemoryBufferRef Buffer);
/// Read the specified bitcode file, returning the module.
- Expected<std::unique_ptr<Module>> parseBitcodeFile(MemoryBufferRef Buffer,
- LLVMContext &Context);
+ Expected<std::unique_ptr<Module>> parseBitcodeFile(
+ MemoryBufferRef Buffer, LLVMContext &Context,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) {
+ return None;
+ });
/// Returns LTO information for the specified bitcode file.
Expected<BitcodeLTOInfo> getBitcodeLTOInfo(MemoryBufferRef Buffer);
@@ -255,6 +263,8 @@ class Module;
return false;
}
+ APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits);
+
const std::error_category &BitcodeErrorCategory();
enum class BitcodeError { CorruptedBitcode = 1 };
inline std::error_code make_error_code(BitcodeError E) {
diff --git a/contrib/llvm-project/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/contrib/llvm-project/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 2cfd66b96502..de4fe6630324 100644
--- a/contrib/llvm-project/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -85,7 +85,7 @@ enum ModuleCodes {
MODULE_CODE_ASM = 4, // ASM: [strchr x N]
MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
- // FIXME: Remove DEPLIB in 4.0.
+ // Deprecated, but still needed to read old bitcode files.
MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N]
// GLOBALVAR: [pointer type, isconst, initid,
@@ -121,7 +121,7 @@ enum ModuleCodes {
/// PARAMATTR blocks have code for defining a parameter attribute set.
enum AttributeCodes {
- // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0
+ // Deprecated, but still needed to read old bitcode files.
PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0,
// paramidx1, attr1...]
PARAMATTR_CODE_ENTRY = 2, // ENTRY: [attrgrp0, attrgrp1, ...]
@@ -166,7 +166,9 @@ enum TypeCodes {
TYPE_CODE_FUNCTION = 21, // FUNCTION: [vararg, retty, paramty x N]
- TYPE_CODE_TOKEN = 22 // TOKEN
+ TYPE_CODE_TOKEN = 22, // TOKEN
+
+ TYPE_CODE_BFLOAT = 23 // BRAIN FLOATING POINT
};
enum OperandBundleTagCode {
@@ -288,6 +290,11 @@ enum GlobalValueSummarySymtabCodes {
// numrefs, numrefs x valueid,
// n x (valueid, offset)]
FS_PERMODULE_VTABLE_GLOBALVAR_INIT_REFS = 23,
+ // The total number of basic blocks in the module.
+ FS_BLOCK_COUNT = 24,
+ // Range information for accessed offsets for every argument.
+ // [n x (paramno, range, numcalls, numcalls x (callee_guid, paramno, range))]
+ FS_PARAM_ACCESS = 25,
};
enum MetadataCodes {
@@ -633,6 +640,10 @@ enum AttributeKindCodes {
ATTR_KIND_NOFREE = 62,
ATTR_KIND_NOSYNC = 63,
ATTR_KIND_SANITIZE_MEMTAG = 64,
+ ATTR_KIND_PREALLOCATED = 65,
+ ATTR_KIND_NO_MERGE = 66,
+ ATTR_KIND_NULL_POINTER_IS_VALID = 67,
+ ATTR_KIND_NOUNDEF = 68,
};
enum ComdatSelectionKindCodes {
diff --git a/contrib/llvm-project/llvm/include/llvm/Bitstream/BitstreamReader.h b/contrib/llvm-project/llvm/include/llvm/Bitstream/BitstreamReader.h
index c476f60420fa..0393d1a51866 100644
--- a/contrib/llvm-project/llvm/include/llvm/Bitstream/BitstreamReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/Bitstream/BitstreamReader.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Bitstream/BitCodes.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/Analysis.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/Analysis.h
index 0be0ac22a74d..fe610b5bdc8d 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/Analysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/Analysis.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Triple.h"
#include "llvm/CodeGen/ISDOpcodes.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Support/CodeGen.h"
@@ -31,9 +30,6 @@ class MachineFunction;
class TargetLoweringBase;
class TargetLowering;
class TargetMachine;
-class SDNode;
-class SDValue;
-class SelectionDAG;
struct EVT;
/// Compute the linearized index of a member in a nested
@@ -122,7 +118,7 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
/// between it and the return.
///
/// This function only tests target-independent requirements.
-bool isInTailCallPosition(ImmutableCallSite CS, const TargetMachine &TM);
+bool isInTailCallPosition(const CallBase &Call, const TargetMachine &TM);
/// Test if given that the input instruction is in the tail call position, if
/// there is an attribute mismatch between the caller and the callee that will
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/AntiDepBreaker.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/AntiDepBreaker.h
new file mode 100644
index 000000000000..d75c13e2dd75
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/AntiDepBreaker.h
@@ -0,0 +1,97 @@
+//===- llvm/CodeGen/AntiDepBreaker.h - Anti-Dependence Breaking -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AntiDepBreaker class, which implements
+// anti-dependence breaking heuristics for post-register-allocation scheduling.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
+#define LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/Support/Compiler.h"
+#include <cassert>
+#include <utility>
+#include <vector>
+
+namespace llvm {
+
+class RegisterClassInfo;
+
+/// This class works in conjunction with the post-RA scheduler to rename
+/// registers to break register anti-dependencies (WAR hazards).
+class AntiDepBreaker {
+public:
+ using DbgValueVector =
+ std::vector<std::pair<MachineInstr *, MachineInstr *>>;
+
+ virtual ~AntiDepBreaker();
+
+ /// Initialize anti-dep breaking for a new basic block.
+ virtual void StartBlock(MachineBasicBlock *BB) = 0;
+
+ /// Identifiy anti-dependencies within a basic-block region and break them by
+ /// renaming registers. Return the number of anti-dependencies broken.
+ virtual unsigned BreakAntiDependencies(const std::vector<SUnit> &SUnits,
+ MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ unsigned InsertPosIndex,
+ DbgValueVector &DbgValues) = 0;
+
+ /// Update liveness information to account for the current
+ /// instruction, which will not be scheduled.
+ virtual void Observe(MachineInstr &MI, unsigned Count,
+ unsigned InsertPosIndex) = 0;
+
+ /// Finish anti-dep breaking for a basic block.
+ virtual void FinishBlock() = 0;
+
+ /// Update DBG_VALUE if dependency breaker is updating
+ /// other machine instruction to use NewReg.
+ void UpdateDbgValue(MachineInstr &MI, unsigned OldReg, unsigned NewReg) {
+ assert(MI.isDebugValue() && "MI is not DBG_VALUE!");
+ if (MI.getDebugOperand(0).isReg() &&
+ MI.getDebugOperand(0).getReg() == OldReg)
+ MI.getDebugOperand(0).setReg(NewReg);
+ }
+
+ /// Update all DBG_VALUE instructions that may be affected by the dependency
+ /// breaker's update of ParentMI to use NewReg.
+ void UpdateDbgValues(const DbgValueVector &DbgValues, MachineInstr *ParentMI,
+ unsigned OldReg, unsigned NewReg) {
+ // The following code is dependent on the order in which the DbgValues are
+ // constructed in ScheduleDAGInstrs::buildSchedGraph.
+ MachineInstr *PrevDbgMI = nullptr;
+ for (const auto &DV : make_range(DbgValues.crbegin(), DbgValues.crend())) {
+ MachineInstr *PrevMI = DV.second;
+ if ((PrevMI == ParentMI) || (PrevMI == PrevDbgMI)) {
+ MachineInstr *DbgMI = DV.first;
+ UpdateDbgValue(*DbgMI, OldReg, NewReg);
+ PrevDbgMI = DbgMI;
+ } else if (PrevDbgMI) {
+ break; // If no match and already found a DBG_VALUE, we're done.
+ }
+ }
+ }
+};
+
+AntiDepBreaker *createAggressiveAntiDepBreaker(
+ MachineFunction &MFi, const RegisterClassInfo &RCI,
+ TargetSubtargetInfo::RegClassVector &CriticalPathRCs);
+
+AntiDepBreaker *createCriticalAntiDepBreaker(MachineFunction &MFi,
+ const RegisterClassInfo &RCI);
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ANTIDEPBREAKER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h
index c710c5d7055c..0eb950861af6 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -17,8 +17,6 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinterHandler.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -48,7 +46,6 @@ class GlobalObject;
class GlobalValue;
class GlobalVariable;
class MachineBasicBlock;
-class MachineBlockFrequencyInfo;
class MachineConstantPoolValue;
class MachineDominatorTree;
class MachineFunction;
@@ -69,12 +66,16 @@ class MCSymbol;
class MCTargetOptions;
class MDNode;
class Module;
-class ProfileSummaryInfo;
class raw_ostream;
-class RemarkStreamer;
class StackMaps;
+class StringRef;
class TargetLoweringObjectFile;
class TargetMachine;
+class Twine;
+
+namespace remarks {
+class RemarkStreamer;
+}
/// This class is intended to be used as a driving class for all asm writers.
class AsmPrinter : public MachineFunctionPass {
@@ -100,7 +101,7 @@ public:
/// This is a pointer to the current MachineModuleInfo.
MachineModuleInfo *MMI = nullptr;
- /// This is a pointer to the current MachineLoopInfo.
+ /// This is a pointer to the current MachineDominatorTree.
MachineDominatorTree *MDT = nullptr;
/// This is a pointer to the current MachineLoopInfo.
@@ -109,10 +110,6 @@ public:
/// Optimization remark emitter.
MachineOptimizationRemarkEmitter *ORE;
- MachineBlockFrequencyInfo *MBFI;
-
- ProfileSummaryInfo *PSI;
-
/// The symbol for the entry in __patchable_function_entires.
MCSymbol *CurrentPatchableFunctionEntrySym = nullptr;
@@ -129,6 +126,14 @@ public:
/// default, this is equal to CurrentFnSym.
MCSymbol *CurrentFnSymForSize = nullptr;
+ /// Map a basic block section ID to the begin and end symbols of that section
+ /// which determine the section's range.
+ struct MBBSectionRange {
+ MCSymbol *BeginLabel, *EndLabel;
+ };
+
+ MapVector<unsigned, MBBSectionRange> MBBSectionRanges;
+
/// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of
/// its number of uses by other globals.
using GOTEquivUsePair = std::pair<const GlobalVariable *, unsigned>;
@@ -138,6 +143,10 @@ private:
MCSymbol *CurrentFnEnd = nullptr;
MCSymbol *CurExceptionSym = nullptr;
+ // The symbol used to represent the start of the current BB section of the
+ // function. This is used to calculate the size of the BB section.
+ MCSymbol *CurrentSectionBeginSym = nullptr;
+
// The garbage collection metadata printer table.
void *GCMetadataPrinters = nullptr; // Really a DenseMap.
@@ -248,6 +257,11 @@ public:
MCSymbol *getSymbol(const GlobalValue *GV) const;
+ /// Similar to getSymbol() but preferred for references. On ELF, this uses a
+ /// local symbol if a reference to GV is guaranteed to be resolved to the
+ /// definition in the same module.
+ MCSymbol *getSymbolPreferLocal(const GlobalValue &GV) const;
+
//===------------------------------------------------------------------===//
// XRay instrumentation implementation.
//===------------------------------------------------------------------===//
@@ -274,15 +288,12 @@ public:
const class Function *Fn;
uint8_t Version;
- void emit(int, MCStreamer *, const MCSymbol *) const;
+ void emit(int, MCStreamer *) const;
};
// All the sleds to be emitted.
SmallVector<XRayFunctionEntry, 4> Sleds;
- // A unique ID used for ELF sections associated with a particular function.
- unsigned XRayFnUniqueID = 0;
-
// Helper function to record a given XRay sled.
void recordSled(MCSymbol *Sled, const MachineInstr &MI, SledKind Kind,
uint8_t Version = 0);
@@ -290,7 +301,6 @@ public:
/// Emit a table with all XRay instrumentation points.
void emitXRayTable();
- DenseMap<const MCSection *, unsigned> PatchableFunctionEntryID;
void emitPatchableFunctionEntries();
//===------------------------------------------------------------------===//
@@ -311,7 +321,7 @@ public:
/// Emit the specified function out to the OutStreamer.
bool runOnMachineFunction(MachineFunction &MF) override {
SetupMachineFunction(MF);
- EmitFunctionBody();
+ emitFunctionBody();
return false;
}
@@ -324,7 +334,7 @@ public:
virtual void SetupMachineFunction(MachineFunction &MF);
/// This method emits the body and trailer for a function.
- void EmitFunctionBody();
+ void emitFunctionBody();
void emitCFIInstruction(const MachineInstr &MI);
@@ -332,7 +342,7 @@ public:
void emitStackSizeSection(const MachineFunction &MF);
- void emitRemarksSection(RemarkStreamer &RS);
+ void emitRemarksSection(remarks::RemarkStreamer &RS);
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug };
CFIMoveType needsCFIMoves() const;
@@ -346,30 +356,30 @@ public:
/// Print to the current output stream assembly representations of the
/// constants in the constant pool MCP. This is used to print out constants
/// which have been "spilled to memory" by the code generator.
- virtual void EmitConstantPool();
+ virtual void emitConstantPool();
/// Print assembly representations of the jump tables used by the current
/// function to the current output stream.
- virtual void EmitJumpTableInfo();
+ virtual void emitJumpTableInfo();
/// Emit the specified global variable to the .s file.
- virtual void EmitGlobalVariable(const GlobalVariable *GV);
+ virtual void emitGlobalVariable(const GlobalVariable *GV);
/// Check to see if the specified global is a special global used by LLVM. If
/// so, emit it and return true, otherwise do nothing and return false.
- bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
+ bool emitSpecialLLVMGlobal(const GlobalVariable *GV);
/// Emit an alignment directive to the specified power of two boundary. If a
/// global value is specified, and if that global has an explicit alignment
/// requested, it will override the alignment request if required for
/// correctness.
- void EmitAlignment(Align Alignment, const GlobalObject *GV = nullptr) const;
+ void emitAlignment(Align Alignment, const GlobalObject *GV = nullptr) const;
/// Lower the specified LLVM Constant to an MCExpr.
virtual const MCExpr *lowerConstant(const Constant *CV);
/// Print a general LLVM constant to the .s file.
- void EmitGlobalConstant(const DataLayout &DL, const Constant *CV);
+ void emitGlobalConstant(const DataLayout &DL, const Constant *CV);
/// Unnamed constant global variables solely contaning a pointer to
/// another globals variable act like a global variable "proxy", or GOT
@@ -398,49 +408,49 @@ public:
/// This virtual method can be overridden by targets that want to emit
/// something at the start of their file.
- virtual void EmitStartOfAsmFile(Module &) {}
+ virtual void emitStartOfAsmFile(Module &) {}
/// This virtual method can be overridden by targets that want to emit
/// something at the end of their file.
- virtual void EmitEndOfAsmFile(Module &) {}
+ virtual void emitEndOfAsmFile(Module &) {}
/// Targets can override this to emit stuff before the first basic block in
/// the function.
- virtual void EmitFunctionBodyStart() {}
+ virtual void emitFunctionBodyStart() {}
/// Targets can override this to emit stuff after the last basic block in the
/// function.
- virtual void EmitFunctionBodyEnd() {}
+ virtual void emitFunctionBodyEnd() {}
/// Targets can override this to emit stuff at the start of a basic block.
/// By default, this method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing it
/// if appropriate.
- virtual void EmitBasicBlockStart(const MachineBasicBlock &MBB);
+ virtual void emitBasicBlockStart(const MachineBasicBlock &MBB);
/// Targets can override this to emit stuff at the end of a basic block.
- virtual void EmitBasicBlockEnd(const MachineBasicBlock &MBB);
+ virtual void emitBasicBlockEnd(const MachineBasicBlock &MBB);
/// Targets should implement this to emit instructions.
- virtual void EmitInstruction(const MachineInstr *) {
+ virtual void emitInstruction(const MachineInstr *) {
llvm_unreachable("EmitInstruction not implemented");
}
/// Return the symbol for the specified constant pool entry.
virtual MCSymbol *GetCPISymbol(unsigned CPID) const;
- virtual void EmitFunctionEntryLabel();
+ virtual void emitFunctionEntryLabel();
- virtual void EmitFunctionDescriptor() {
+ virtual void emitFunctionDescriptor() {
llvm_unreachable("Function descriptor is target-specific.");
}
- virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+ virtual void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
/// Targets can override this to change how global constants that are part of
/// a C++ static/global constructor list are emitted.
- virtual void EmitXXStructor(const DataLayout &DL, const Constant *CV) {
- EmitGlobalConstant(DL, CV);
+ virtual void emitXXStructor(const DataLayout &DL, const Constant *CV) {
+ emitGlobalConstant(DL, CV);
}
/// Return true if the basic block has exactly one predecessor and the control
@@ -504,49 +514,50 @@ public:
/// Emit something like ".long Hi-Lo" where the size in bytes of the directive
/// is specified by Size and Hi/Lo specify the labels. This implicitly uses
/// .set if it is available.
- void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
+ void emitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Size) const;
/// Emit something like ".uleb128 Hi-Lo".
- void EmitLabelDifferenceAsULEB128(const MCSymbol *Hi,
+ void emitLabelDifferenceAsULEB128(const MCSymbol *Hi,
const MCSymbol *Lo) const;
/// Emit something like ".long Label+Offset" where the size in bytes of the
/// directive is specified by Size and Label specifies the label. This
/// implicitly uses .set if it is available.
- void EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
+ void emitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
unsigned Size, bool IsSectionRelative = false) const;
/// Emit something like ".long Label" where the size in bytes of the directive
/// is specified by Size and Label specifies the label.
- void EmitLabelReference(const MCSymbol *Label, unsigned Size,
+ void emitLabelReference(const MCSymbol *Label, unsigned Size,
bool IsSectionRelative = false) const {
- EmitLabelPlusOffset(Label, 0, Size, IsSectionRelative);
+ emitLabelPlusOffset(Label, 0, Size, IsSectionRelative);
}
/// Emit something like ".long Label + Offset".
- void EmitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const;
+ void emitDwarfOffset(const MCSymbol *Label, uint64_t Offset) const;
//===------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===------------------------------------------------------------------===//
/// Emit the specified signed leb128 value.
- void EmitSLEB128(int64_t Value, const char *Desc = nullptr) const;
+ void emitSLEB128(int64_t Value, const char *Desc = nullptr) const;
/// Emit the specified unsigned leb128 value.
- void EmitULEB128(uint64_t Value, const char *Desc = nullptr, unsigned PadTo = 0) const;
+ void emitULEB128(uint64_t Value, const char *Desc = nullptr,
+ unsigned PadTo = 0) const;
/// Emit a .byte 42 directive that corresponds to an encoding. If verbose
/// assembly output is enabled, we output comments describing the encoding.
/// Desc is a string saying what the encoding is specifying (e.g. "LSDA").
- void EmitEncodingByte(unsigned Val, const char *Desc = nullptr) const;
+ void emitEncodingByte(unsigned Val, const char *Desc = nullptr) const;
/// Return the size of the encoding in bytes.
unsigned GetSizeOfEncodedValue(unsigned Encoding) const;
/// Emit reference to a ttype global with a specified encoding.
- void EmitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
+ void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) const;
/// Emit a reference to a symbol for use in dwarf. Different object formats
/// represent this in different ways. Some use a relocation others encode
@@ -567,10 +578,10 @@ public:
}
/// Emit reference to a call site with a specified encoding
- void EmitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
+ void emitCallSiteOffset(const MCSymbol *Hi, const MCSymbol *Lo,
unsigned Encoding) const;
/// Emit an integer value corresponding to the call site encoding
- void EmitCallSiteValue(uint64_t Value, unsigned Encoding) const;
+ void emitCallSiteValue(uint64_t Value, unsigned Encoding) const;
/// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
virtual unsigned getISAEncoding() { return 0; }
@@ -579,7 +590,7 @@ public:
///
/// \p Value - The value to emit.
/// \p Size - The size of the integer (in bytes) to emit.
- virtual void EmitDebugValue(const MCExpr *Value, unsigned Size) const;
+ virtual void emitDebugValue(const MCExpr *Value, unsigned Size) const;
//===------------------------------------------------------------------===//
// Dwarf Lowering Routines
@@ -595,7 +606,7 @@ public:
emitDwarfAbbrev(*Abbrev);
// Mark end of abbreviations.
- EmitULEB128(0, "EOM(3)");
+ emitULEB128(0, "EOM(3)");
}
void emitDwarfAbbrev(const DIEAbbrev &Abbrev) const;
@@ -651,16 +662,16 @@ public:
/// This emits visibility information about symbol, if this is supported by
/// the target.
- void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
+ void emitVisibility(MCSymbol *Sym, unsigned Visibility,
bool IsDefinition = true) const;
/// This emits linkage information about \p GVSym based on \p GV, if this is
/// supported by the target.
- void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
+ virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
/// Return the alignment for the specified \p GV.
- static Align getGVAlignment(const GlobalValue *GV, const DataLayout &DL,
- Align InAlign = Align::None());
+ static Align getGVAlignment(const GlobalObject *GV, const DataLayout &DL,
+ Align InAlign = Align(1));
private:
/// Private state for PrintSpecial()
@@ -670,18 +681,21 @@ private:
mutable unsigned Counter = ~0U;
/// This method emits the header for the current function.
- virtual void EmitFunctionHeader();
+ virtual void emitFunctionHeader();
+
+ /// This method emits a comment next to header for the current function.
+ virtual void emitFunctionHeaderComment();
/// Emit a blob of inline asm to the output streamer.
void
- EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
+ emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
const MCTargetOptions &MCOptions,
const MDNode *LocMDNode = nullptr,
InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
/// This method formats and emits the specified machine instruction that is an
/// inline asm.
- void EmitInlineAsm(const MachineInstr *MI) const;
+ void emitInlineAsm(const MachineInstr *MI) const;
/// Add inline assembly info to the diagnostics machinery, so we can
/// emit file and position info. Returns SrcMgr memory buffer position.
@@ -692,14 +706,14 @@ private:
// Internal Implementation Details
//===------------------------------------------------------------------===//
- void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
+ void emitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB, unsigned uid) const;
- void EmitLLVMUsedList(const ConstantArray *InitList);
+ void emitLLVMUsedList(const ConstantArray *InitList);
/// Emit llvm.ident metadata in an '.ident' directive.
- void EmitModuleIdents(Module &M);
+ void emitModuleIdents(Module &M);
/// Emit bytes for llvm.commandline metadata.
- void EmitModuleCommandLines(Module &M);
- void EmitXXStructorList(const DataLayout &DL, const Constant *List,
+ void emitModuleCommandLines(Module &M);
+ void emitXXStructorList(const DataLayout &DL, const Constant *List,
bool isCtor);
GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy &S);
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinterHandler.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
index affb558f2fa6..899d067d03f0 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinterHandler.h
@@ -67,6 +67,12 @@ public:
/// Process end of an instruction.
virtual void endInstruction() = 0;
+
+ /// Process beginning of a basic block during basic block sections.
+ virtual void beginBasicBlock(const MachineBasicBlock &MBB) {}
+
+ /// Process end of a basic block during basic block sections.
+ virtual void endBasicBlock(const MachineBasicBlock &MBB) {}
};
} // End of namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index 30533d90bbf7..407f09063dce 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -29,7 +29,6 @@
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -79,27 +78,26 @@ private:
using BaseT = TargetTransformInfoImplCRTPBase<T>;
using TTI = TargetTransformInfo;
+ /// Helper function to access this as a T.
+ T *thisT() { return static_cast<T *>(this); }
+
/// Estimate a cost of Broadcast as an extract and sequence of insert
/// operations.
- unsigned getBroadcastShuffleOverhead(Type *Ty) {
- assert(Ty->isVectorTy() && "Can only shuffle vectors");
+ unsigned getBroadcastShuffleOverhead(FixedVectorType *VTy) {
unsigned Cost = 0;
// Broadcast cost is equal to the cost of extracting the zero'th element
// plus the cost of inserting it into every element of the result vector.
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, Ty, 0);
+ Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy, 0);
- for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::InsertElement, Ty, i);
+ for (int i = 0, e = VTy->getNumElements(); i < e; ++i) {
+ Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, VTy, i);
}
return Cost;
}
/// Estimate a cost of shuffle as a sequence of extract and insert
/// operations.
- unsigned getPermuteShuffleOverhead(Type *Ty) {
- assert(Ty->isVectorTy() && "Can only shuffle vectors");
+ unsigned getPermuteShuffleOverhead(FixedVectorType *VTy) {
unsigned Cost = 0;
// Shuffle cost is equal to the cost of extracting element from its argument
// plus the cost of inserting them onto the result vector.
@@ -108,22 +106,21 @@ private:
// index 0 of first vector, index 1 of second vector,index 2 of first
// vector and finally index 3 of second vector and insert them at index
// <0,1,2,3> of result vector.
- for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::InsertElement, Ty, i);
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::ExtractElement, Ty, i);
+ for (int i = 0, e = VTy->getNumElements(); i < e; ++i) {
+ Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, VTy, i);
+ Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy, i);
}
return Cost;
}
/// Estimate a cost of subvector extraction as a sequence of extract and
/// insert operations.
- unsigned getExtractSubvectorOverhead(Type *Ty, int Index, Type *SubTy) {
- assert(Ty && Ty->isVectorTy() && SubTy && SubTy->isVectorTy() &&
+ unsigned getExtractSubvectorOverhead(FixedVectorType *VTy, int Index,
+ FixedVectorType *SubVTy) {
+ assert(VTy && SubVTy &&
"Can only extract subvectors from vectors");
- int NumSubElts = SubTy->getVectorNumElements();
- assert((Index + NumSubElts) <= (int)Ty->getVectorNumElements() &&
+ int NumSubElts = SubVTy->getNumElements();
+ assert((Index + NumSubElts) <= (int)VTy->getNumElements() &&
"SK_ExtractSubvector index out of range");
unsigned Cost = 0;
@@ -131,21 +128,22 @@ private:
// the source type plus the cost of inserting them into the result vector
// type.
for (int i = 0; i != NumSubElts; ++i) {
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, Ty, i + Index);
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::InsertElement, SubTy, i);
+ Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VTy,
+ i + Index);
+ Cost +=
+ thisT()->getVectorInstrCost(Instruction::InsertElement, SubVTy, i);
}
return Cost;
}
/// Estimate a cost of subvector insertion as a sequence of extract and
/// insert operations.
- unsigned getInsertSubvectorOverhead(Type *Ty, int Index, Type *SubTy) {
- assert(Ty && Ty->isVectorTy() && SubTy && SubTy->isVectorTy() &&
+ unsigned getInsertSubvectorOverhead(FixedVectorType *VTy, int Index,
+ FixedVectorType *SubVTy) {
+ assert(VTy && SubVTy &&
"Can only insert subvectors into vectors");
- int NumSubElts = SubTy->getVectorNumElements();
- assert((Index + NumSubElts) <= (int)Ty->getVectorNumElements() &&
+ int NumSubElts = SubVTy->getNumElements();
+ assert((Index + NumSubElts) <= (int)VTy->getNumElements() &&
"SK_InsertSubvector index out of range");
unsigned Cost = 0;
@@ -153,10 +151,10 @@ private:
// the source type plus the cost of inserting them into the result vector
// type.
for (int i = 0; i != NumSubElts; ++i) {
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, SubTy, i);
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::InsertElement, Ty, i + Index);
+ Cost +=
+ thisT()->getVectorInstrCost(Instruction::ExtractElement, SubVTy, i);
+ Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, VTy,
+ i + Index);
}
return Cost;
}
@@ -207,6 +205,8 @@ public:
bool hasBranchDivergence() { return false; }
+ bool useGPUDivergenceAnalysis() { return false; }
+
bool isSourceOfDivergence(const Value *V) { return false; }
bool isAlwaysUniform(const Value *V) { return false; }
@@ -221,9 +221,13 @@ public:
return false;
}
- bool rewriteIntrinsicWithAddressSpace(IntrinsicInst *II,
- Value *OldV, Value *NewV) const {
- return false;
+ bool isNoopAddrSpaceCast(unsigned FromAS, unsigned ToAS) const {
+ return getTLI()->isNoopAddrSpaceCast(FromAS, ToAS);
+ }
+
+ Value *rewriteIntrinsicWithAddressSpace(IntrinsicInst *II, Value *OldV,
+ Value *NewV) const {
+ return nullptr;
}
bool isLegalAddImmediate(int64_t imm) {
@@ -261,6 +265,10 @@ public:
return TargetTransformInfoImplBase::isLSRCostLess(C1, C2);
}
+ bool isProfitableLSRChainElement(Instruction *I) {
+ return TargetTransformInfoImplBase::isProfitableLSRChainElement(I);
+ }
+
int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset,
bool HasBaseReg, int64_t Scale, unsigned AddrSpace) {
TargetLoweringBase::AddrMode AM;
@@ -291,40 +299,6 @@ public:
return BaseT::getGEPCost(PointeeType, Ptr, Operands);
}
- int getExtCost(const Instruction *I, const Value *Src) {
- if (getTLI()->isExtFree(I))
- return TargetTransformInfo::TCC_Free;
-
- if (isa<ZExtInst>(I) || isa<SExtInst>(I))
- if (const LoadInst *LI = dyn_cast<LoadInst>(Src))
- if (getTLI()->isExtLoad(LI, I, DL))
- return TargetTransformInfo::TCC_Free;
-
- return TargetTransformInfo::TCC_Basic;
- }
-
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<const Value *> Arguments, const User *U) {
- return BaseT::getIntrinsicCost(IID, RetTy, Arguments, U);
- }
-
- unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Type *> ParamTys, const User *U) {
- if (IID == Intrinsic::cttz) {
- if (getTLI()->isCheapToSpeculateCttz())
- return TargetTransformInfo::TCC_Basic;
- return TargetTransformInfo::TCC_Expensive;
- }
-
- if (IID == Intrinsic::ctlz) {
- if (getTLI()->isCheapToSpeculateCtlz())
- return TargetTransformInfo::TCC_Basic;
- return TargetTransformInfo::TCC_Expensive;
- }
-
- return BaseT::getIntrinsicCost(IID, RetTy, ParamTys, U);
- }
-
unsigned getEstimatedNumberOfCaseClusters(const SwitchInst &SI,
unsigned &JumpTableSize,
ProfileSummaryInfo *PSI,
@@ -411,29 +385,6 @@ public:
return TargetTransformInfo::TCC_Expensive;
}
- unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) {
- const TargetLoweringBase *TLI = getTLI();
- switch (Opcode) {
- default: break;
- case Instruction::Trunc:
- if (TLI->isTruncateFree(OpTy, Ty))
- return TargetTransformInfo::TCC_Free;
- return TargetTransformInfo::TCC_Basic;
- case Instruction::ZExt:
- if (TLI->isZExtFree(OpTy, Ty))
- return TargetTransformInfo::TCC_Free;
- return TargetTransformInfo::TCC_Basic;
-
- case Instruction::AddrSpaceCast:
- if (TLI->isFreeAddrSpaceCast(OpTy->getPointerAddressSpace(),
- Ty->getPointerAddressSpace()))
- return TargetTransformInfo::TCC_Free;
- return TargetTransformInfo::TCC_Basic;
- }
-
- return BaseT::getOperationCost(Opcode, Ty, OpTy);
- }
-
unsigned getInliningThresholdMultiplier() { return 1; }
int getInlinerVectorBonusPercent() { return 150; }
@@ -473,20 +424,17 @@ public:
return;
// Scan the loop: don't unroll loops with calls.
- for (Loop::block_iterator I = L->block_begin(), E = L->block_end(); I != E;
- ++I) {
- BasicBlock *BB = *I;
-
- for (BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE; ++J)
- if (isa<CallInst>(J) || isa<InvokeInst>(J)) {
- ImmutableCallSite CS(&*J);
- if (const Function *F = CS.getCalledFunction()) {
- if (!static_cast<T *>(this)->isLoweredToCall(F))
+ for (BasicBlock *BB : L->blocks()) {
+ for (Instruction &I : *BB) {
+ if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
+ if (const Function *F = cast<CallBase>(I).getCalledFunction()) {
+ if (!thisT()->isLoweredToCall(F))
continue;
}
return;
}
+ }
}
// Enable runtime and partial unrolling up to the specified size.
@@ -503,6 +451,14 @@ public:
UP.BEInsns = 2;
}
+ void getPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ TTI::PeelingPreferences &PP) {
+ PP.PeelCount = 0;
+ PP.AllowPeeling = true;
+ PP.AllowLoopNestsPeeling = false;
+ PP.PeelProfiledIterations = true;
+ }
+
bool isHardwareLoopProfitable(Loop *L, ScalarEvolution &SE,
AssumptionCache &AC,
TargetLibraryInfo *LibInfo,
@@ -517,6 +473,10 @@ public:
return BaseT::preferPredicateOverEpilogue(L, LI, SE, AC, TLI, DT, LAI);
}
+ bool emitGetActiveLaneMask() {
+ return BaseT::emitGetActiveLaneMask();
+ }
+
int getInstructionLatency(const Instruction *I) {
if (isa<LoadInst>(I))
return getST()->getSchedModel().DefaultLoadLatency;
@@ -549,14 +509,22 @@ public:
return getST()->getPrefetchDistance();
}
- virtual unsigned getMinPrefetchStride() const {
- return getST()->getMinPrefetchStride();
+ virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches,
+ bool HasCall) const {
+ return getST()->getMinPrefetchStride(NumMemAccesses, NumStridedMemAccesses,
+ NumPrefetches, HasCall);
}
virtual unsigned getMaxPrefetchIterationsAhead() const {
return getST()->getMaxPrefetchIterationsAhead();
}
+ virtual bool enableWritePrefetching() const {
+ return getST()->enableWritePrefetching();
+ }
+
/// @}
/// \name Vector TTI Implementations
@@ -565,23 +533,40 @@ public:
unsigned getRegisterBitWidth(bool Vector) const { return 32; }
/// Estimate the overhead of scalarizing an instruction. Insert and Extract
- /// are set if the result needs to be inserted and/or extracted from vectors.
- unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract) {
- assert(Ty->isVectorTy() && "Can only scalarize vectors");
+ /// are set if the demanded result elements need to be inserted and/or
+ /// extracted from vectors.
+ unsigned getScalarizationOverhead(VectorType *InTy, const APInt &DemandedElts,
+ bool Insert, bool Extract) {
+ /// FIXME: a bitfield is not a reasonable abstraction for talking about
+ /// which elements are needed from a scalable vector
+ auto *Ty = cast<FixedVectorType>(InTy);
+
+ assert(DemandedElts.getBitWidth() == Ty->getNumElements() &&
+ "Vector size mismatch");
+
unsigned Cost = 0;
- for (int i = 0, e = Ty->getVectorNumElements(); i < e; ++i) {
+ for (int i = 0, e = Ty->getNumElements(); i < e; ++i) {
+ if (!DemandedElts[i])
+ continue;
if (Insert)
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::InsertElement, Ty, i);
+ Cost += thisT()->getVectorInstrCost(Instruction::InsertElement, Ty, i);
if (Extract)
- Cost += static_cast<T *>(this)
- ->getVectorInstrCost(Instruction::ExtractElement, Ty, i);
+ Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty, i);
}
return Cost;
}
+ /// Helper wrapper for the DemandedElts variant of getScalarizationOverhead.
+ unsigned getScalarizationOverhead(VectorType *InTy, bool Insert,
+ bool Extract) {
+ auto *Ty = cast<FixedVectorType>(InTy);
+
+ APInt DemandedElts = APInt::getAllOnesValue(Ty->getNumElements());
+ return thisT()->getScalarizationOverhead(Ty, DemandedElts, Insert, Extract);
+ }
+
/// Estimate the overhead of scalarizing an instructions unique
/// non-constant operands. The types of the arguments are ordinarily
/// scalar, in which case the costs are multiplied with VF.
@@ -591,15 +576,15 @@ public:
SmallPtrSet<const Value*, 4> UniqueOperands;
for (const Value *A : Args) {
if (!isa<Constant>(A) && UniqueOperands.insert(A).second) {
- Type *VecTy = nullptr;
- if (A->getType()->isVectorTy()) {
- VecTy = A->getType();
+ auto *VecTy = dyn_cast<VectorType>(A->getType());
+ if (VecTy) {
// If A is a vector operand, VF should be 1 or correspond to A.
- assert((VF == 1 || VF == VecTy->getVectorNumElements()) &&
+ assert((VF == 1 ||
+ VF == cast<FixedVectorType>(VecTy)->getNumElements()) &&
"Vector argument does not match VF");
}
else
- VecTy = VectorType::get(A->getType(), VF);
+ VecTy = FixedVectorType::get(A->getType(), VF);
Cost += getScalarizationOverhead(VecTy, false, true);
}
@@ -608,19 +593,19 @@ public:
return Cost;
}
- unsigned getScalarizationOverhead(Type *VecTy, ArrayRef<const Value *> Args) {
- assert(VecTy->isVectorTy());
+ unsigned getScalarizationOverhead(VectorType *InTy,
+ ArrayRef<const Value *> Args) {
+ auto *Ty = cast<FixedVectorType>(InTy);
unsigned Cost = 0;
- Cost += getScalarizationOverhead(VecTy, true, false);
+ Cost += getScalarizationOverhead(Ty, true, false);
if (!Args.empty())
- Cost += getOperandsScalarizationOverhead(Args,
- VecTy->getVectorNumElements());
+ Cost += getOperandsScalarizationOverhead(Args, Ty->getNumElements());
else
// When no information on arguments is provided, we add the cost
// associated with one argument as a heuristic.
- Cost += getScalarizationOverhead(VecTy, false, true);
+ Cost += getScalarizationOverhead(Ty, false, true);
return Cost;
}
@@ -629,6 +614,7 @@ public:
unsigned getArithmeticInstrCost(
unsigned Opcode, Type *Ty,
+ TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput,
TTI::OperandValueKind Opd1Info = TTI::OK_AnyValue,
TTI::OperandValueKind Opd2Info = TTI::OK_AnyValue,
TTI::OperandValueProperties Opd1PropInfo = TTI::OP_None,
@@ -640,6 +626,13 @@ public:
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
+ // TODO: Handle more cost kinds.
+ if (CostKind != TTI::TCK_RecipThroughput)
+ return BaseT::getArithmeticInstrCost(Opcode, Ty, CostKind,
+ Opd1Info, Opd2Info,
+ Opd1PropInfo, Opd2PropInfo,
+ Args, CxtI);
+
std::pair<unsigned, MVT> LT = TLI->getTypeLegalizationCost(DL, Ty);
bool IsFloat = Ty->isFPOrFPVectorTy();
@@ -662,91 +655,116 @@ public:
// Else, assume that we need to scalarize this op.
// TODO: If one of the types get legalized by splitting, handle this
// similarly to what getCastInstrCost() does.
- if (Ty->isVectorTy()) {
- unsigned Num = Ty->getVectorNumElements();
- unsigned Cost = static_cast<T *>(this)
- ->getArithmeticInstrCost(Opcode, Ty->getScalarType());
+ if (auto *VTy = dyn_cast<VectorType>(Ty)) {
+ unsigned Num = cast<FixedVectorType>(VTy)->getNumElements();
+ unsigned Cost = thisT()->getArithmeticInstrCost(
+ Opcode, VTy->getScalarType(), CostKind);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
- return getScalarizationOverhead(Ty, Args) + Num * Cost;
+ return getScalarizationOverhead(VTy, Args) + Num * Cost;
}
// We don't know anything about this scalar instruction.
return OpCost;
}
- unsigned getShuffleCost(TTI::ShuffleKind Kind, Type *Tp, int Index,
- Type *SubTp) {
+ unsigned getShuffleCost(TTI::ShuffleKind Kind, VectorType *Tp, int Index,
+ VectorType *SubTp) {
+
switch (Kind) {
case TTI::SK_Broadcast:
- return getBroadcastShuffleOverhead(Tp);
+ return getBroadcastShuffleOverhead(cast<FixedVectorType>(Tp));
case TTI::SK_Select:
case TTI::SK_Reverse:
case TTI::SK_Transpose:
case TTI::SK_PermuteSingleSrc:
case TTI::SK_PermuteTwoSrc:
- return getPermuteShuffleOverhead(Tp);
+ return getPermuteShuffleOverhead(cast<FixedVectorType>(Tp));
case TTI::SK_ExtractSubvector:
- return getExtractSubvectorOverhead(Tp, Index, SubTp);
+ return getExtractSubvectorOverhead(cast<FixedVectorType>(Tp), Index,
+ cast<FixedVectorType>(SubTp));
case TTI::SK_InsertSubvector:
- return getInsertSubvectorOverhead(Tp, Index, SubTp);
+ return getInsertSubvectorOverhead(cast<FixedVectorType>(Tp), Index,
+ cast<FixedVectorType>(SubTp));
}
llvm_unreachable("Unknown TTI::ShuffleKind");
}
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
+ TTI::TargetCostKind CostKind,
const Instruction *I = nullptr) {
+ if (BaseT::getCastInstrCost(Opcode, Dst, Src, CostKind, I) == 0)
+ return 0;
+
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
std::pair<unsigned, MVT> SrcLT = TLI->getTypeLegalizationCost(DL, Src);
std::pair<unsigned, MVT> DstLT = TLI->getTypeLegalizationCost(DL, Dst);
- // Check for NOOP conversions.
- if (SrcLT.first == DstLT.first &&
- SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) {
+ TypeSize SrcSize = SrcLT.second.getSizeInBits();
+ TypeSize DstSize = DstLT.second.getSizeInBits();
+ bool IntOrPtrSrc = Src->isIntegerTy() || Src->isPointerTy();
+ bool IntOrPtrDst = Dst->isIntegerTy() || Dst->isPointerTy();
- // Bitcast between types that are legalized to the same type are free.
- if (Opcode == Instruction::BitCast || Opcode == Instruction::Trunc)
+ switch (Opcode) {
+ default:
+ break;
+ case Instruction::Trunc:
+ // Check for NOOP conversions.
+ if (TLI->isTruncateFree(SrcLT.second, DstLT.second))
return 0;
- }
-
- if (Opcode == Instruction::Trunc &&
- TLI->isTruncateFree(SrcLT.second, DstLT.second))
- return 0;
-
- if (Opcode == Instruction::ZExt &&
- TLI->isZExtFree(SrcLT.second, DstLT.second))
- return 0;
+ LLVM_FALLTHROUGH;
+ case Instruction::BitCast:
+ // Bitcast between types that are legalized to the same type are free and
+ // assume int to/from ptr of the same size is also free.
+ if (SrcLT.first == DstLT.first && IntOrPtrSrc == IntOrPtrDst &&
+ SrcSize == DstSize)
+ return 0;
+ break;
+ case Instruction::FPExt:
+ if (I && getTLI()->isExtFree(I))
+ return 0;
+ break;
+ case Instruction::ZExt:
+ if (TLI->isZExtFree(SrcLT.second, DstLT.second))
+ return 0;
+ LLVM_FALLTHROUGH;
+ case Instruction::SExt:
+ if (!I)
+ break;
- if (Opcode == Instruction::AddrSpaceCast &&
- TLI->isFreeAddrSpaceCast(Src->getPointerAddressSpace(),
- Dst->getPointerAddressSpace()))
- return 0;
+ if (getTLI()->isExtFree(I))
+ return 0;
- // If this is a zext/sext of a load, return 0 if the corresponding
- // extending load exists on target.
- if ((Opcode == Instruction::ZExt || Opcode == Instruction::SExt) &&
- I && isa<LoadInst>(I->getOperand(0))) {
+ // If this is a zext/sext of a load, return 0 if the corresponding
+ // extending load exists on target.
+ if (I && isa<LoadInst>(I->getOperand(0))) {
EVT ExtVT = EVT::getEVT(Dst);
EVT LoadVT = EVT::getEVT(Src);
unsigned LType =
((Opcode == Instruction::ZExt) ? ISD::ZEXTLOAD : ISD::SEXTLOAD);
if (TLI->isLoadExtLegal(LType, ExtVT, LoadVT))
return 0;
+ }
+ break;
+ case Instruction::AddrSpaceCast:
+ if (TLI->isFreeAddrSpaceCast(Src->getPointerAddressSpace(),
+ Dst->getPointerAddressSpace()))
+ return 0;
+ break;
}
+ auto *SrcVTy = dyn_cast<VectorType>(Src);
+ auto *DstVTy = dyn_cast<VectorType>(Dst);
+
// If the cast is marked as legal (or promote) then assume low cost.
if (SrcLT.first == DstLT.first &&
TLI->isOperationLegalOrPromote(ISD, DstLT.second))
- return 1;
+ return SrcLT.first;
// Handle scalar conversions.
- if (!Src->isVectorTy() && !Dst->isVectorTy()) {
- // Scalar bitcasts are usually free.
- if (Opcode == Instruction::BitCast)
- return 0;
-
+ if (!SrcVTy && !DstVTy) {
// Just check the op cost. If the operation is legal then assume it costs
// 1.
if (!TLI->isOperationExpand(ISD, DstLT.second))
@@ -757,18 +775,17 @@ public:
}
// Check vector-to-vector casts.
- if (Dst->isVectorTy() && Src->isVectorTy()) {
+ if (DstVTy && SrcVTy) {
// If the cast is between same-sized registers, then the check is simple.
- if (SrcLT.first == DstLT.first &&
- SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) {
+ if (SrcLT.first == DstLT.first && SrcSize == DstSize) {
// Assume that Zext is done using AND.
if (Opcode == Instruction::ZExt)
- return 1;
+ return SrcLT.first;
// Assume that sext is done using SHL and SRA.
if (Opcode == Instruction::SExt)
- return 2;
+ return SrcLT.first * 2;
// Just check the op cost. If the operation is legal then assume it
// costs
@@ -781,64 +798,73 @@ public:
// of casting the original vector twice. We also need to factor in the
// cost of the split itself. Count that as 1, to be consistent with
// TLI->getTypeLegalizationCost().
- if ((TLI->getTypeAction(Src->getContext(), TLI->getValueType(DL, Src)) ==
- TargetLowering::TypeSplitVector ||
- TLI->getTypeAction(Dst->getContext(), TLI->getValueType(DL, Dst)) ==
- TargetLowering::TypeSplitVector) &&
- Src->getVectorNumElements() > 1 && Dst->getVectorNumElements() > 1) {
- Type *SplitDst = VectorType::get(Dst->getVectorElementType(),
- Dst->getVectorNumElements() / 2);
- Type *SplitSrc = VectorType::get(Src->getVectorElementType(),
- Src->getVectorNumElements() / 2);
+ bool SplitSrc =
+ TLI->getTypeAction(Src->getContext(), TLI->getValueType(DL, Src)) ==
+ TargetLowering::TypeSplitVector;
+ bool SplitDst =
+ TLI->getTypeAction(Dst->getContext(), TLI->getValueType(DL, Dst)) ==
+ TargetLowering::TypeSplitVector;
+ if ((SplitSrc || SplitDst) &&
+ cast<FixedVectorType>(SrcVTy)->getNumElements() > 1 &&
+ cast<FixedVectorType>(DstVTy)->getNumElements() > 1) {
+ Type *SplitDstTy = VectorType::getHalfElementsVectorType(DstVTy);
+ Type *SplitSrcTy = VectorType::getHalfElementsVectorType(SrcVTy);
T *TTI = static_cast<T *>(this);
- return TTI->getVectorSplitCost() +
- (2 * TTI->getCastInstrCost(Opcode, SplitDst, SplitSrc, I));
+ // If both types need to be split then the split is free.
+ unsigned SplitCost =
+ (!SplitSrc || !SplitDst) ? TTI->getVectorSplitCost() : 0;
+ return SplitCost +
+ (2 * TTI->getCastInstrCost(Opcode, SplitDstTy, SplitSrcTy,
+ CostKind, I));
}
// In other cases where the source or destination are illegal, assume
// the operation will get scalarized.
- unsigned Num = Dst->getVectorNumElements();
- unsigned Cost = static_cast<T *>(this)->getCastInstrCost(
- Opcode, Dst->getScalarType(), Src->getScalarType(), I);
+ unsigned Num = cast<FixedVectorType>(DstVTy)->getNumElements();
+ unsigned Cost = thisT()->getCastInstrCost(
+ Opcode, Dst->getScalarType(), Src->getScalarType(), CostKind, I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
- return getScalarizationOverhead(Dst, true, true) + Num * Cost;
+ return getScalarizationOverhead(DstVTy, true, true) + Num * Cost;
}
// We already handled vector-to-vector and scalar-to-scalar conversions.
// This
// is where we handle bitcast between vectors and scalars. We need to assume
// that the conversion is scalarized in one way or another.
- if (Opcode == Instruction::BitCast)
+ if (Opcode == Instruction::BitCast) {
// Illegal bitcasts are done by storing and loading from a stack slot.
- return (Src->isVectorTy() ? getScalarizationOverhead(Src, false, true)
- : 0) +
- (Dst->isVectorTy() ? getScalarizationOverhead(Dst, true, false)
- : 0);
+ return (SrcVTy ? getScalarizationOverhead(SrcVTy, false, true) : 0) +
+ (DstVTy ? getScalarizationOverhead(DstVTy, true, false) : 0);
+ }
llvm_unreachable("Unhandled cast");
}
unsigned getExtractWithExtendCost(unsigned Opcode, Type *Dst,
VectorType *VecTy, unsigned Index) {
- return static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, VecTy, Index) +
- static_cast<T *>(this)->getCastInstrCost(Opcode, Dst,
- VecTy->getElementType());
+ return thisT()->getVectorInstrCost(Instruction::ExtractElement, VecTy,
+ Index) +
+ thisT()->getCastInstrCost(Opcode, Dst, VecTy->getElementType(),
+ TTI::TCK_RecipThroughput);
}
- unsigned getCFInstrCost(unsigned Opcode) {
- // Branches are assumed to be predicted.
- return 0;
+ unsigned getCFInstrCost(unsigned Opcode, TTI::TargetCostKind CostKind) {
+ return BaseT::getCFInstrCost(Opcode, CostKind);
}
unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, Type *CondTy,
- const Instruction *I) {
+ TTI::TargetCostKind CostKind,
+ const Instruction *I = nullptr) {
const TargetLoweringBase *TLI = getTLI();
int ISD = TLI->InstructionOpcodeToISD(Opcode);
assert(ISD && "Invalid opcode");
+ // TODO: Handle other cost kinds.
+ if (CostKind != TTI::TCK_RecipThroughput)
+ return BaseT::getCmpSelInstrCost(Opcode, ValTy, CondTy, CostKind, I);
+
// Selects on vectors are actually vector selects.
if (ISD == ISD::SELECT) {
assert(CondTy && "CondTy must exist");
@@ -857,16 +883,16 @@ public:
// Otherwise, assume that the cast is scalarized.
// TODO: If one of the types get legalized by splitting, handle this
// similarly to what getCastInstrCost() does.
- if (ValTy->isVectorTy()) {
- unsigned Num = ValTy->getVectorNumElements();
+ if (auto *ValVTy = dyn_cast<VectorType>(ValTy)) {
+ unsigned Num = cast<FixedVectorType>(ValVTy)->getNumElements();
if (CondTy)
CondTy = CondTy->getScalarType();
- unsigned Cost = static_cast<T *>(this)->getCmpSelInstrCost(
- Opcode, ValTy->getScalarType(), CondTy, I);
+ unsigned Cost = thisT()->getCmpSelInstrCost(
+ Opcode, ValVTy->getScalarType(), CondTy, CostKind, I);
// Return the cost of multiple scalar invocation plus the cost of
// inserting and extracting the values.
- return getScalarizationOverhead(ValTy, true, false) + Num * Cost;
+ return getScalarizationOverhead(ValVTy, true, false) + Num * Cost;
}
// Unknown scalar opcode.
@@ -882,12 +908,18 @@ public:
unsigned getMemoryOpCost(unsigned Opcode, Type *Src, MaybeAlign Alignment,
unsigned AddressSpace,
+ TTI::TargetCostKind CostKind,
const Instruction *I = nullptr) {
assert(!Src->isVoidTy() && "Invalid type");
+ // Assume types, such as structs, are expensive.
+ if (getTLI()->getValueType(DL, Src, true) == MVT::Other)
+ return 4;
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(DL, Src);
// Assuming that all loads of legal types cost 1.
unsigned Cost = LT.first;
+ if (CostKind != TTI::TCK_RecipThroughput)
+ return Cost;
if (Src->isVectorTy() &&
Src->getPrimitiveSizeInBits() < LT.second.getSizeInBits()) {
@@ -904,7 +936,8 @@ public:
if (LA != TargetLowering::Legal && LA != TargetLowering::Custom) {
// This is a vector load/store for some illegal type that is scalarized.
// We must account for the cost of building or decomposing the vector.
- Cost += getScalarizationOverhead(Src, Opcode != Instruction::Store,
+ Cost += getScalarizationOverhead(cast<VectorType>(Src),
+ Opcode != Instruction::Store,
Opcode == Instruction::Store);
}
}
@@ -912,35 +945,31 @@ public:
return Cost;
}
- unsigned getInterleavedMemoryOpCost(unsigned Opcode, Type *VecTy,
- unsigned Factor,
- ArrayRef<unsigned> Indices,
- unsigned Alignment, unsigned AddressSpace,
- bool UseMaskForCond = false,
- bool UseMaskForGaps = false) {
- VectorType *VT = dyn_cast<VectorType>(VecTy);
- assert(VT && "Expect a vector type for interleaved memory op");
+ unsigned getInterleavedMemoryOpCost(
+ unsigned Opcode, Type *VecTy, unsigned Factor, ArrayRef<unsigned> Indices,
+ Align Alignment, unsigned AddressSpace, TTI::TargetCostKind CostKind,
+ bool UseMaskForCond = false, bool UseMaskForGaps = false) {
+ auto *VT = cast<FixedVectorType>(VecTy);
unsigned NumElts = VT->getNumElements();
assert(Factor > 1 && NumElts % Factor == 0 && "Invalid interleave factor");
unsigned NumSubElts = NumElts / Factor;
- VectorType *SubVT = VectorType::get(VT->getElementType(), NumSubElts);
+ auto *SubVT = FixedVectorType::get(VT->getElementType(), NumSubElts);
// Firstly, the cost of load/store operation.
unsigned Cost;
if (UseMaskForCond || UseMaskForGaps)
- Cost = static_cast<T *>(this)->getMaskedMemoryOpCost(
- Opcode, VecTy, Alignment, AddressSpace);
+ Cost = thisT()->getMaskedMemoryOpCost(Opcode, VecTy, Alignment,
+ AddressSpace, CostKind);
else
- Cost = static_cast<T *>(this)->getMemoryOpCost(
- Opcode, VecTy, MaybeAlign(Alignment), AddressSpace);
+ Cost = thisT()->getMemoryOpCost(Opcode, VecTy, Alignment, AddressSpace,
+ CostKind);
// Legalize the vector type, and get the legalized and unlegalized type
// sizes.
MVT VecTyLT = getTLI()->getTypeLegalizationCost(DL, VecTy).second;
- unsigned VecTySize =
- static_cast<T *>(this)->getDataLayout().getTypeStoreSize(VecTy);
+ unsigned VecTySize = thisT()->getDataLayout().getTypeStoreSize(VecTy);
unsigned VecTyLTSize = VecTyLT.getStoreSize();
// Return the ceiling of dividing A by B.
@@ -999,14 +1028,14 @@ public:
// Extract elements from loaded vector for each sub vector.
for (unsigned i = 0; i < NumSubElts; i++)
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, VT, Index + i * Factor);
+ Cost += thisT()->getVectorInstrCost(Instruction::ExtractElement, VT,
+ Index + i * Factor);
}
unsigned InsSubCost = 0;
for (unsigned i = 0; i < NumSubElts; i++)
- InsSubCost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::InsertElement, SubVT, i);
+ InsSubCost +=
+ thisT()->getVectorInstrCost(Instruction::InsertElement, SubVT, i);
Cost += Indices.size() * InsSubCost;
} else {
@@ -1021,8 +1050,8 @@ public:
unsigned ExtSubCost = 0;
for (unsigned i = 0; i < NumSubElts; i++)
- ExtSubCost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, SubVT, i);
+ ExtSubCost +=
+ thisT()->getVectorInstrCost(Instruction::ExtractElement, SubVT, i);
Cost += ExtSubCost * Factor;
for (unsigned i = 0; i < NumElts; i++)
@@ -1034,8 +1063,8 @@ public:
return Cost;
Type *I8Type = Type::getInt8Ty(VT->getContext());
- VectorType *MaskVT = VectorType::get(I8Type, NumElts);
- SubVT = VectorType::get(I8Type, NumSubElts);
+ auto *MaskVT = FixedVectorType::get(I8Type, NumElts);
+ SubVT = FixedVectorType::get(I8Type, NumSubElts);
// The Mask shuffling cost is extract all the elements of the Mask
// and insert each of them Factor times into the wide vector:
@@ -1048,12 +1077,12 @@ public:
// vector and insert them factor times into the <24xi1> shuffled mask
// vector.
for (unsigned i = 0; i < NumSubElts; i++)
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::ExtractElement, SubVT, i);
+ Cost +=
+ thisT()->getVectorInstrCost(Instruction::ExtractElement, SubVT, i);
for (unsigned i = 0; i < NumElts; i++)
- Cost += static_cast<T *>(this)->getVectorInstrCost(
- Instruction::InsertElement, MaskVT, i);
+ Cost +=
+ thisT()->getVectorInstrCost(Instruction::InsertElement, MaskVT, i);
// The Gaps mask is invariant and created outside the loop, therefore the
// cost of creating it is not accounted for here. However if we have both
@@ -1061,32 +1090,66 @@ public:
// memory access, we need to account for the cost of And-ing the two masks
// inside the loop.
if (UseMaskForGaps)
- Cost += static_cast<T *>(this)->getArithmeticInstrCost(
- BinaryOperator::And, MaskVT);
+ Cost += thisT()->getArithmeticInstrCost(BinaryOperator::And, MaskVT,
+ CostKind);
return Cost;
}
/// Get intrinsic cost based on arguments.
- unsigned getIntrinsicInstrCost(Intrinsic::ID IID, Type *RetTy,
- ArrayRef<Value *> Args, FastMathFlags FMF,
- unsigned VF = 1) {
- unsigned RetVF = (RetTy->isVectorTy() ? RetTy->getVectorNumElements() : 1);
+ unsigned getIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) {
+ Intrinsic::ID IID = ICA.getID();
+
+ // Special case some scalar intrinsics.
+ if (CostKind != TTI::TCK_RecipThroughput) {
+ switch (IID) {
+ default:
+ break;
+ case Intrinsic::cttz:
+ if (getTLI()->isCheapToSpeculateCttz())
+ return TargetTransformInfo::TCC_Basic;
+ break;
+ case Intrinsic::ctlz:
+ if (getTLI()->isCheapToSpeculateCtlz())
+ return TargetTransformInfo::TCC_Basic;
+ break;
+ case Intrinsic::memcpy:
+ return thisT()->getMemcpyCost(ICA.getInst());
+ // TODO: other libc intrinsics.
+ }
+ return BaseT::getIntrinsicInstrCost(ICA, CostKind);
+ }
+
+ if (BaseT::getIntrinsicInstrCost(ICA, CostKind) == 0)
+ return 0;
+
+ // TODO: Combine these two logic paths.
+ if (ICA.isTypeBasedOnly())
+ return getTypeBasedIntrinsicInstrCost(ICA, CostKind);
+
+ Type *RetTy = ICA.getReturnType();
+ unsigned VF = ICA.getVectorFactor();
+ unsigned RetVF =
+ (RetTy->isVectorTy() ? cast<FixedVectorType>(RetTy)->getNumElements()
+ : 1);
assert((RetVF == 1 || VF == 1) && "VF > 1 and RetVF is a vector type");
- auto *ConcreteTTI = static_cast<T *>(this);
+ const IntrinsicInst *I = ICA.getInst();
+ const SmallVectorImpl<const Value *> &Args = ICA.getArgs();
+ FastMathFlags FMF = ICA.getFlags();
switch (IID) {
default: {
// Assume that we need to scalarize this intrinsic.
SmallVector<Type *, 4> Types;
- for (Value *Op : Args) {
+ for (const Value *Op : Args) {
Type *OpTy = Op->getType();
assert(VF == 1 || !OpTy->isVectorTy());
- Types.push_back(VF == 1 ? OpTy : VectorType::get(OpTy, VF));
+ Types.push_back(VF == 1 ? OpTy : FixedVectorType::get(OpTy, VF));
}
if (VF > 1 && !RetTy->isVoidTy())
- RetTy = VectorType::get(RetTy, VF);
+ RetTy = FixedVectorType::get(RetTy, VF);
// Compute the scalarization overhead based on Args for a vector
// intrinsic. A vectorizer will pass a scalar RetTy and VF > 1, while
@@ -1095,28 +1158,31 @@ public:
if (RetVF > 1 || VF > 1) {
ScalarizationCost = 0;
if (!RetTy->isVoidTy())
- ScalarizationCost += getScalarizationOverhead(RetTy, true, false);
+ ScalarizationCost +=
+ getScalarizationOverhead(cast<VectorType>(RetTy), true, false);
ScalarizationCost += getOperandsScalarizationOverhead(Args, VF);
}
- return ConcreteTTI->getIntrinsicInstrCost(IID, RetTy, Types, FMF,
- ScalarizationCost);
+ IntrinsicCostAttributes Attrs(IID, RetTy, Types, FMF,
+ ScalarizationCost, I);
+ return thisT()->getIntrinsicInstrCost(Attrs, CostKind);
}
case Intrinsic::masked_scatter: {
assert(VF == 1 && "Can't vectorize types here.");
- Value *Mask = Args[3];
+ const Value *Mask = Args[3];
bool VarMask = !isa<Constant>(Mask);
- unsigned Alignment = cast<ConstantInt>(Args[2])->getZExtValue();
- return ConcreteTTI->getGatherScatterOpCost(
- Instruction::Store, Args[0]->getType(), Args[1], VarMask, Alignment);
+ Align Alignment = cast<ConstantInt>(Args[2])->getAlignValue();
+ return thisT()->getGatherScatterOpCost(Instruction::Store,
+ Args[0]->getType(), Args[1],
+ VarMask, Alignment, CostKind, I);
}
case Intrinsic::masked_gather: {
assert(VF == 1 && "Can't vectorize types here.");
- Value *Mask = Args[2];
+ const Value *Mask = Args[2];
bool VarMask = !isa<Constant>(Mask);
- unsigned Alignment = cast<ConstantInt>(Args[1])->getZExtValue();
- return ConcreteTTI->getGatherScatterOpCost(Instruction::Load, RetTy,
- Args[0], VarMask, Alignment);
+ Align Alignment = cast<ConstantInt>(Args[1])->getAlignValue();
+ return thisT()->getGatherScatterOpCost(Instruction::Load, RetTy, Args[0],
+ VarMask, Alignment, CostKind, I);
}
case Intrinsic::experimental_vector_reduce_add:
case Intrinsic::experimental_vector_reduce_mul:
@@ -1130,13 +1196,15 @@ public:
case Intrinsic::experimental_vector_reduce_fmax:
case Intrinsic::experimental_vector_reduce_fmin:
case Intrinsic::experimental_vector_reduce_umax:
- case Intrinsic::experimental_vector_reduce_umin:
- return getIntrinsicInstrCost(IID, RetTy, Args[0]->getType(), FMF);
+ case Intrinsic::experimental_vector_reduce_umin: {
+ IntrinsicCostAttributes Attrs(IID, RetTy, Args[0]->getType(), FMF, 1, I);
+ return getIntrinsicInstrCost(Attrs, CostKind);
+ }
case Intrinsic::fshl:
case Intrinsic::fshr: {
- Value *X = Args[0];
- Value *Y = Args[1];
- Value *Z = Args[2];
+ const Value *X = Args[0];
+ const Value *Y = Args[1];
+ const Value *Z = Args[2];
TTI::OperandValueProperties OpPropsX, OpPropsY, OpPropsZ, OpPropsBW;
TTI::OperandValueKind OpKindX = TTI::getOperandInfo(X, OpPropsX);
TTI::OperandValueKind OpKindY = TTI::getOperandInfo(Y, OpPropsY);
@@ -1147,25 +1215,27 @@ public:
// fshl: (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
// fshr: (X << (BW - (Z % BW))) | (Y >> (Z % BW))
unsigned Cost = 0;
- Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Or, RetTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Sub, RetTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::Shl, RetTy,
- OpKindX, OpKindZ, OpPropsX);
- Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::LShr, RetTy,
- OpKindY, OpKindZ, OpPropsY);
+ Cost +=
+ thisT()->getArithmeticInstrCost(BinaryOperator::Or, RetTy, CostKind);
+ Cost +=
+ thisT()->getArithmeticInstrCost(BinaryOperator::Sub, RetTy, CostKind);
+ Cost += thisT()->getArithmeticInstrCost(
+ BinaryOperator::Shl, RetTy, CostKind, OpKindX, OpKindZ, OpPropsX);
+ Cost += thisT()->getArithmeticInstrCost(
+ BinaryOperator::LShr, RetTy, CostKind, OpKindY, OpKindZ, OpPropsY);
// Non-constant shift amounts requires a modulo.
if (OpKindZ != TTI::OK_UniformConstantValue &&
OpKindZ != TTI::OK_NonUniformConstantValue)
- Cost += ConcreteTTI->getArithmeticInstrCost(BinaryOperator::URem, RetTy,
- OpKindZ, OpKindBW, OpPropsZ,
- OpPropsBW);
+ Cost += thisT()->getArithmeticInstrCost(BinaryOperator::URem, RetTy,
+ CostKind, OpKindZ, OpKindBW,
+ OpPropsZ, OpPropsBW);
// For non-rotates (X != Y) we must add shift-by-zero handling costs.
if (X != Y) {
Type *CondTy = RetTy->getWithNewBitWidth(1);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy,
- CondTy, nullptr);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
- CondTy, nullptr);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
+ CostKind);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
+ CondTy, CostKind);
}
return Cost;
}
@@ -1176,10 +1246,16 @@ public:
/// If ScalarizationCostPassed is std::numeric_limits<unsigned>::max(), the
/// cost of scalarizing the arguments and the return value will be computed
/// based on types.
- unsigned getIntrinsicInstrCost(
- Intrinsic::ID IID, Type *RetTy, ArrayRef<Type *> Tys, FastMathFlags FMF,
- unsigned ScalarizationCostPassed = std::numeric_limits<unsigned>::max()) {
- auto *ConcreteTTI = static_cast<T *>(this);
+ unsigned getTypeBasedIntrinsicInstrCost(const IntrinsicCostAttributes &ICA,
+ TTI::TargetCostKind CostKind) {
+ Intrinsic::ID IID = ICA.getID();
+ Type *RetTy = ICA.getReturnType();
+ const SmallVectorImpl<Type *> &Tys = ICA.getArgTypes();
+ FastMathFlags FMF = ICA.getFlags();
+ unsigned ScalarizationCostPassed = ICA.getScalarizationCost();
+ bool SkipScalarizationCost = ICA.skipScalarizationCost();
+
+ auto *VecOpTy = Tys.empty() ? nullptr : dyn_cast<VectorType>(Tys[0]);
SmallVector<unsigned, 2> ISDs;
unsigned SingleCallCost = 10; // Library call cost. Make it expensive.
@@ -1189,19 +1265,21 @@ public:
unsigned ScalarizationCost = ScalarizationCostPassed;
unsigned ScalarCalls = 1;
Type *ScalarRetTy = RetTy;
- if (RetTy->isVectorTy()) {
- if (ScalarizationCostPassed == std::numeric_limits<unsigned>::max())
- ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
- ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
+ if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
+ if (!SkipScalarizationCost)
+ ScalarizationCost = getScalarizationOverhead(RetVTy, true, false);
+ ScalarCalls = std::max(ScalarCalls,
+ cast<FixedVectorType>(RetVTy)->getNumElements());
ScalarRetTy = RetTy->getScalarType();
}
SmallVector<Type *, 4> ScalarTys;
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
Type *Ty = Tys[i];
- if (Ty->isVectorTy()) {
- if (ScalarizationCostPassed == std::numeric_limits<unsigned>::max())
- ScalarizationCost += getScalarizationOverhead(Ty, false, true);
- ScalarCalls = std::max(ScalarCalls, Ty->getVectorNumElements());
+ if (auto *VTy = dyn_cast<VectorType>(Ty)) {
+ if (!SkipScalarizationCost)
+ ScalarizationCost += getScalarizationOverhead(VTy, false, true);
+ ScalarCalls = std::max(ScalarCalls,
+ cast<FixedVectorType>(VTy)->getNumElements());
Ty = Ty->getScalarType();
}
ScalarTys.push_back(Ty);
@@ -1209,8 +1287,9 @@ public:
if (ScalarCalls == 1)
return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
+ IntrinsicCostAttributes ScalarAttrs(IID, ScalarRetTy, ScalarTys, FMF);
unsigned ScalarCost =
- ConcreteTTI->getIntrinsicInstrCost(IID, ScalarRetTy, ScalarTys, FMF);
+ thisT()->getIntrinsicInstrCost(ScalarAttrs, CostKind);
return ScalarCalls * ScalarCost + ScalarizationCost;
}
@@ -1277,6 +1356,9 @@ public:
case Intrinsic::round:
ISDs.push_back(ISD::FROUND);
break;
+ case Intrinsic::roundeven:
+ ISDs.push_back(ISD::FROUNDEVEN);
+ break;
case Intrinsic::pow:
ISDs.push_back(ISD::FPOW);
break;
@@ -1286,53 +1368,70 @@ public:
case Intrinsic::fmuladd:
ISDs.push_back(ISD::FMA);
break;
+ case Intrinsic::experimental_constrained_fmuladd:
+ ISDs.push_back(ISD::STRICT_FMA);
+ break;
// FIXME: We should return 0 whenever getIntrinsicCost == TCC_Free.
case Intrinsic::lifetime_start:
case Intrinsic::lifetime_end:
case Intrinsic::sideeffect:
return 0;
- case Intrinsic::masked_store:
- return ConcreteTTI->getMaskedMemoryOpCost(Instruction::Store, Tys[0], 0,
- 0);
- case Intrinsic::masked_load:
- return ConcreteTTI->getMaskedMemoryOpCost(Instruction::Load, RetTy, 0, 0);
+ case Intrinsic::masked_store: {
+ Type *Ty = Tys[0];
+ Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
+ return thisT()->getMaskedMemoryOpCost(Instruction::Store, Ty, TyAlign, 0,
+ CostKind);
+ }
+ case Intrinsic::masked_load: {
+ Type *Ty = RetTy;
+ Align TyAlign = thisT()->DL.getABITypeAlign(Ty);
+ return thisT()->getMaskedMemoryOpCost(Instruction::Load, Ty, TyAlign, 0,
+ CostKind);
+ }
case Intrinsic::experimental_vector_reduce_add:
- return ConcreteTTI->getArithmeticReductionCost(Instruction::Add, Tys[0],
- /*IsPairwiseForm=*/false);
+ return thisT()->getArithmeticReductionCost(Instruction::Add, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_mul:
- return ConcreteTTI->getArithmeticReductionCost(Instruction::Mul, Tys[0],
- /*IsPairwiseForm=*/false);
+ return thisT()->getArithmeticReductionCost(Instruction::Mul, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_and:
- return ConcreteTTI->getArithmeticReductionCost(Instruction::And, Tys[0],
- /*IsPairwiseForm=*/false);
+ return thisT()->getArithmeticReductionCost(Instruction::And, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_or:
- return ConcreteTTI->getArithmeticReductionCost(Instruction::Or, Tys[0],
- /*IsPairwiseForm=*/false);
+ return thisT()->getArithmeticReductionCost(Instruction::Or, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_xor:
- return ConcreteTTI->getArithmeticReductionCost(Instruction::Xor, Tys[0],
- /*IsPairwiseForm=*/false);
+ return thisT()->getArithmeticReductionCost(Instruction::Xor, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_v2_fadd:
- return ConcreteTTI->getArithmeticReductionCost(
- Instruction::FAdd, Tys[0],
- /*IsPairwiseForm=*/false); // FIXME: Add new flag for cost of strict
- // reductions.
+ // FIXME: Add new flag for cost of strict reductions.
+ return thisT()->getArithmeticReductionCost(Instruction::FAdd, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_v2_fmul:
- return ConcreteTTI->getArithmeticReductionCost(
- Instruction::FMul, Tys[0],
- /*IsPairwiseForm=*/false); // FIXME: Add new flag for cost of strict
- // reductions.
+ // FIXME: Add new flag for cost of strict reductions.
+ return thisT()->getArithmeticReductionCost(Instruction::FMul, VecOpTy,
+ /*IsPairwiseForm=*/false,
+ CostKind);
case Intrinsic::experimental_vector_reduce_smax:
case Intrinsic::experimental_vector_reduce_smin:
case Intrinsic::experimental_vector_reduce_fmax:
case Intrinsic::experimental_vector_reduce_fmin:
- return ConcreteTTI->getMinMaxReductionCost(
- Tys[0], CmpInst::makeCmpResultType(Tys[0]), /*IsPairwiseForm=*/false,
- /*IsUnsigned=*/true);
+ return thisT()->getMinMaxReductionCost(
+ VecOpTy, cast<VectorType>(CmpInst::makeCmpResultType(VecOpTy)),
+ /*IsPairwiseForm=*/false,
+ /*IsUnsigned=*/false, CostKind);
case Intrinsic::experimental_vector_reduce_umax:
case Intrinsic::experimental_vector_reduce_umin:
- return ConcreteTTI->getMinMaxReductionCost(
- Tys[0], CmpInst::makeCmpResultType(Tys[0]), /*IsPairwiseForm=*/false,
- /*IsUnsigned=*/false);
+ return thisT()->getMinMaxReductionCost(
+ VecOpTy, cast<VectorType>(CmpInst::makeCmpResultType(VecOpTy)),
+ /*IsPairwiseForm=*/false,
+ /*IsUnsigned=*/true, CostKind);
case Intrinsic::sadd_sat:
case Intrinsic::ssub_sat: {
Type *CondTy = RetTy->getWithNewBitWidth(1);
@@ -1345,12 +1444,13 @@ public:
// SatMax -> Overflow && SumDiff < 0
// SatMin -> Overflow && SumDiff >= 0
unsigned Cost = 0;
- Cost += ConcreteTTI->getIntrinsicInstrCost(
- OverflowOp, OpTy, {RetTy, RetTy}, FMF, ScalarizationCostPassed);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy,
- CondTy, nullptr);
- Cost += 2 * ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
- CondTy, nullptr);
+ IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
+ ScalarizationCostPassed);
+ Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, RetTy, CondTy,
+ CostKind);
+ Cost += 2 * thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
+ CondTy, CostKind);
return Cost;
}
case Intrinsic::uadd_sat:
@@ -1363,10 +1463,11 @@ public:
: Intrinsic::usub_with_overflow;
unsigned Cost = 0;
- Cost += ConcreteTTI->getIntrinsicInstrCost(
- OverflowOp, OpTy, {RetTy, RetTy}, FMF, ScalarizationCostPassed);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::Select, RetTy,
- CondTy, nullptr);
+ IntrinsicCostAttributes Attrs(OverflowOp, OpTy, {RetTy, RetTy}, FMF,
+ ScalarizationCostPassed);
+ Cost += thisT()->getIntrinsicInstrCost(Attrs, CostKind);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::Select, RetTy, CondTy,
+ CostKind);
return Cost;
}
case Intrinsic::smul_fix:
@@ -1378,17 +1479,18 @@ public:
IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
unsigned Cost = 0;
- Cost += 2 * ConcreteTTI->getCastInstrCost(ExtOp, ExtTy, RetTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Mul, ExtTy);
+ Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, RetTy, CostKind);
Cost +=
- 2 * ConcreteTTI->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::LShr, RetTy,
- TTI::OK_AnyValue,
- TTI::OK_UniformConstantValue);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Shl, RetTy,
- TTI::OK_AnyValue,
- TTI::OK_UniformConstantValue);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Or, RetTy);
+ thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
+ Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, RetTy, ExtTy,
+ CostKind);
+ Cost += thisT()->getArithmeticInstrCost(Instruction::LShr, RetTy,
+ CostKind, TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+ Cost += thisT()->getArithmeticInstrCost(Instruction::Shl, RetTy, CostKind,
+ TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
+ Cost += thisT()->getArithmeticInstrCost(Instruction::Or, RetTy, CostKind);
return Cost;
}
case Intrinsic::sadd_with_overflow:
@@ -1408,13 +1510,13 @@ public:
// Sub:
// Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign)
unsigned Cost = 0;
- Cost += ConcreteTTI->getArithmeticInstrCost(Opcode, SumTy);
- Cost += 3 * ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
- OverflowTy, nullptr);
- Cost += 2 * ConcreteTTI->getCmpSelInstrCost(
- BinaryOperator::ICmp, OverflowTy, OverflowTy, nullptr);
- Cost +=
- ConcreteTTI->getArithmeticInstrCost(BinaryOperator::And, OverflowTy);
+ Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
+ Cost += 3 * thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
+ OverflowTy, CostKind);
+ Cost += 2 * thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, OverflowTy,
+ OverflowTy, CostKind);
+ Cost += thisT()->getArithmeticInstrCost(BinaryOperator::And, OverflowTy,
+ CostKind);
return Cost;
}
case Intrinsic::uadd_with_overflow:
@@ -1426,9 +1528,9 @@ public:
: BinaryOperator::Sub;
unsigned Cost = 0;
- Cost += ConcreteTTI->getArithmeticInstrCost(Opcode, SumTy);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
- OverflowTy, nullptr);
+ Cost += thisT()->getArithmeticInstrCost(Opcode, SumTy, CostKind);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, SumTy,
+ OverflowTy, CostKind);
return Cost;
}
case Intrinsic::smul_with_overflow:
@@ -1442,21 +1544,22 @@ public:
IID == Intrinsic::smul_fix ? Instruction::SExt : Instruction::ZExt;
unsigned Cost = 0;
- Cost += 2 * ConcreteTTI->getCastInstrCost(ExtOp, ExtTy, MulTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::Mul, ExtTy);
+ Cost += 2 * thisT()->getCastInstrCost(ExtOp, ExtTy, MulTy, CostKind);
Cost +=
- 2 * ConcreteTTI->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy);
- Cost += ConcreteTTI->getArithmeticInstrCost(Instruction::LShr, MulTy,
- TTI::OK_AnyValue,
- TTI::OK_UniformConstantValue);
+ thisT()->getArithmeticInstrCost(Instruction::Mul, ExtTy, CostKind);
+ Cost += 2 * thisT()->getCastInstrCost(Instruction::Trunc, MulTy, ExtTy,
+ CostKind);
+ Cost += thisT()->getArithmeticInstrCost(Instruction::LShr, MulTy,
+ CostKind, TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
if (IID == Intrinsic::smul_with_overflow)
- Cost += ConcreteTTI->getArithmeticInstrCost(
- Instruction::AShr, MulTy, TTI::OK_AnyValue,
- TTI::OK_UniformConstantValue);
+ Cost += thisT()->getArithmeticInstrCost(Instruction::AShr, MulTy,
+ CostKind, TTI::OK_AnyValue,
+ TTI::OK_UniformConstantValue);
- Cost += ConcreteTTI->getCmpSelInstrCost(BinaryOperator::ICmp, MulTy,
- OverflowTy, nullptr);
+ Cost += thisT()->getCmpSelInstrCost(BinaryOperator::ICmp, MulTy,
+ OverflowTy, CostKind);
return Cost;
}
case Intrinsic::ctpop:
@@ -1466,6 +1569,12 @@ public:
SingleCallCost = TargetTransformInfo::TCC_Expensive;
break;
// FIXME: ctlz, cttz, ...
+ case Intrinsic::bswap:
+ ISDs.push_back(ISD::BSWAP);
+ break;
+ case Intrinsic::bitreverse:
+ ISDs.push_back(ISD::BITREVERSE);
+ break;
}
const TargetLoweringBase *TLI = getTLI();
@@ -1507,18 +1616,27 @@ public:
// If we can't lower fmuladd into an FMA estimate the cost as a floating
// point mul followed by an add.
if (IID == Intrinsic::fmuladd)
- return ConcreteTTI->getArithmeticInstrCost(BinaryOperator::FMul, RetTy) +
- ConcreteTTI->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy);
+ return thisT()->getArithmeticInstrCost(BinaryOperator::FMul, RetTy,
+ CostKind) +
+ thisT()->getArithmeticInstrCost(BinaryOperator::FAdd, RetTy,
+ CostKind);
+ if (IID == Intrinsic::experimental_constrained_fmuladd) {
+ IntrinsicCostAttributes FMulAttrs(
+ Intrinsic::experimental_constrained_fmul, RetTy, Tys);
+ IntrinsicCostAttributes FAddAttrs(
+ Intrinsic::experimental_constrained_fadd, RetTy, Tys);
+ return thisT()->getIntrinsicInstrCost(FMulAttrs, CostKind) +
+ thisT()->getIntrinsicInstrCost(FAddAttrs, CostKind);
+ }
// Else, assume that we need to scalarize this intrinsic. For math builtins
// this will emit a costly libcall, adding call overhead and spills. Make it
// very expensive.
- if (RetTy->isVectorTy()) {
- unsigned ScalarizationCost =
- ((ScalarizationCostPassed != std::numeric_limits<unsigned>::max())
- ? ScalarizationCostPassed
- : getScalarizationOverhead(RetTy, true, false));
- unsigned ScalarCalls = RetTy->getVectorNumElements();
+ if (auto *RetVTy = dyn_cast<VectorType>(RetTy)) {
+ unsigned ScalarizationCost = SkipScalarizationCost ?
+ ScalarizationCostPassed : getScalarizationOverhead(RetVTy, true, false);
+
+ unsigned ScalarCalls = cast<FixedVectorType>(RetVTy)->getNumElements();
SmallVector<Type *, 4> ScalarTys;
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
Type *Ty = Tys[i];
@@ -1526,16 +1644,16 @@ public:
Ty = Ty->getScalarType();
ScalarTys.push_back(Ty);
}
- unsigned ScalarCost = ConcreteTTI->getIntrinsicInstrCost(
- IID, RetTy->getScalarType(), ScalarTys, FMF);
+ IntrinsicCostAttributes Attrs(IID, RetTy->getScalarType(), ScalarTys, FMF);
+ unsigned ScalarCost = thisT()->getIntrinsicInstrCost(Attrs, CostKind);
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
- if (Tys[i]->isVectorTy()) {
- if (ScalarizationCostPassed == std::numeric_limits<unsigned>::max())
- ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
- ScalarCalls = std::max(ScalarCalls, Tys[i]->getVectorNumElements());
+ if (auto *VTy = dyn_cast<VectorType>(Tys[i])) {
+ if (!ICA.skipScalarizationCost())
+ ScalarizationCost += getScalarizationOverhead(VTy, false, true);
+ ScalarCalls = std::max(ScalarCalls,
+ cast<FixedVectorType>(VTy)->getNumElements());
}
}
-
return ScalarCalls * ScalarCost + ScalarizationCost;
}
@@ -1554,7 +1672,8 @@ public:
/// \param RetTy Return value types.
/// \param Tys Argument types.
/// \returns The cost of Call instruction.
- unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) {
+ unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys,
+ TTI::TargetCostKind CostKind = TTI::TCK_SizeAndLatency) {
return 10;
}
@@ -1603,28 +1722,27 @@ public:
///
/// The cost model should take into account that the actual length of the
/// vector is reduced on each iteration.
- unsigned getArithmeticReductionCost(unsigned Opcode, Type *Ty,
- bool IsPairwise) {
- assert(Ty->isVectorTy() && "Expect a vector type");
- Type *ScalarTy = Ty->getVectorElementType();
- unsigned NumVecElts = Ty->getVectorNumElements();
+ unsigned getArithmeticReductionCost(unsigned Opcode, VectorType *Ty,
+ bool IsPairwise,
+ TTI::TargetCostKind CostKind) {
+ Type *ScalarTy = Ty->getElementType();
+ unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
unsigned NumReduxLevels = Log2_32(NumVecElts);
unsigned ArithCost = 0;
unsigned ShuffleCost = 0;
- auto *ConcreteTTI = static_cast<T *>(this);
std::pair<unsigned, MVT> LT =
- ConcreteTTI->getTLI()->getTypeLegalizationCost(DL, Ty);
+ thisT()->getTLI()->getTypeLegalizationCost(DL, Ty);
unsigned LongVectorCount = 0;
unsigned MVTLen =
LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
while (NumVecElts > MVTLen) {
NumVecElts /= 2;
- Type *SubTy = VectorType::get(ScalarTy, NumVecElts);
+ VectorType *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
// Assume the pairwise shuffles add a cost.
- ShuffleCost += (IsPairwise + 1) *
- ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, SubTy);
- ArithCost += ConcreteTTI->getArithmeticInstrCost(Opcode, SubTy);
+ ShuffleCost +=
+ (IsPairwise + 1) * thisT()->getShuffleCost(TTI::SK_ExtractSubvector,
+ Ty, NumVecElts, SubTy);
+ ArithCost += thisT()->getArithmeticInstrCost(Opcode, SubTy, CostKind);
Ty = SubTy;
++LongVectorCount;
}
@@ -1643,22 +1761,20 @@ public:
if (IsPairwise && NumReduxLevels >= 1)
NumShuffles += NumReduxLevels - 1;
ShuffleCost += NumShuffles *
- ConcreteTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
- 0, Ty);
- ArithCost += NumReduxLevels *
- ConcreteTTI->getArithmeticInstrCost(Opcode, Ty);
+ thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty, 0, Ty);
+ ArithCost += NumReduxLevels * thisT()->getArithmeticInstrCost(Opcode, Ty);
return ShuffleCost + ArithCost +
- ConcreteTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
+ thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
}
/// Try to calculate op costs for min/max reduction operations.
/// \param CondTy Conditional type for the Select instruction.
- unsigned getMinMaxReductionCost(Type *Ty, Type *CondTy, bool IsPairwise,
- bool) {
- assert(Ty->isVectorTy() && "Expect a vector type");
- Type *ScalarTy = Ty->getVectorElementType();
- Type *ScalarCondTy = CondTy->getVectorElementType();
- unsigned NumVecElts = Ty->getVectorNumElements();
+ unsigned getMinMaxReductionCost(VectorType *Ty, VectorType *CondTy,
+ bool IsPairwise, bool IsUnsigned,
+ TTI::TargetCostKind CostKind) {
+ Type *ScalarTy = Ty->getElementType();
+ Type *ScalarCondTy = CondTy->getElementType();
+ unsigned NumVecElts = cast<FixedVectorType>(Ty)->getNumElements();
unsigned NumReduxLevels = Log2_32(NumVecElts);
unsigned CmpOpcode;
if (Ty->isFPOrFPVectorTy()) {
@@ -1670,25 +1786,24 @@ public:
}
unsigned MinMaxCost = 0;
unsigned ShuffleCost = 0;
- auto *ConcreteTTI = static_cast<T *>(this);
std::pair<unsigned, MVT> LT =
- ConcreteTTI->getTLI()->getTypeLegalizationCost(DL, Ty);
+ thisT()->getTLI()->getTypeLegalizationCost(DL, Ty);
unsigned LongVectorCount = 0;
unsigned MVTLen =
LT.second.isVector() ? LT.second.getVectorNumElements() : 1;
while (NumVecElts > MVTLen) {
NumVecElts /= 2;
- Type *SubTy = VectorType::get(ScalarTy, NumVecElts);
- CondTy = VectorType::get(ScalarCondTy, NumVecElts);
+ auto *SubTy = FixedVectorType::get(ScalarTy, NumVecElts);
+ CondTy = FixedVectorType::get(ScalarCondTy, NumVecElts);
// Assume the pairwise shuffles add a cost.
- ShuffleCost += (IsPairwise + 1) *
- ConcreteTTI->getShuffleCost(TTI::SK_ExtractSubvector, Ty,
- NumVecElts, SubTy);
+ ShuffleCost +=
+ (IsPairwise + 1) * thisT()->getShuffleCost(TTI::SK_ExtractSubvector,
+ Ty, NumVecElts, SubTy);
MinMaxCost +=
- ConcreteTTI->getCmpSelInstrCost(CmpOpcode, SubTy, CondTy, nullptr) +
- ConcreteTTI->getCmpSelInstrCost(Instruction::Select, SubTy, CondTy,
- nullptr);
+ thisT()->getCmpSelInstrCost(CmpOpcode, SubTy, CondTy, CostKind) +
+ thisT()->getCmpSelInstrCost(Instruction::Select, SubTy, CondTy,
+ CostKind);
Ty = SubTy;
++LongVectorCount;
}
@@ -1707,17 +1822,16 @@ public:
if (IsPairwise && NumReduxLevels >= 1)
NumShuffles += NumReduxLevels - 1;
ShuffleCost += NumShuffles *
- ConcreteTTI->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty,
- 0, Ty);
+ thisT()->getShuffleCost(TTI::SK_PermuteSingleSrc, Ty, 0, Ty);
MinMaxCost +=
NumReduxLevels *
- (ConcreteTTI->getCmpSelInstrCost(CmpOpcode, Ty, CondTy, nullptr) +
- ConcreteTTI->getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
- nullptr));
+ (thisT()->getCmpSelInstrCost(CmpOpcode, Ty, CondTy, CostKind) +
+ thisT()->getCmpSelInstrCost(Instruction::Select, Ty, CondTy,
+ CostKind));
// The last min/max should be in vector registers and we counted it above.
// So just need a single extractelement.
return ShuffleCost + MinMaxCost +
- ConcreteTTI->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
+ thisT()->getVectorInstrCost(Instruction::ExtractElement, Ty, 0);
}
unsigned getVectorSplitCost() { return 1; }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/CallingConvLower.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/CallingConvLower.h
index a30ca638ee6d..8ebe788ac360 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/CallingConvLower.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/CallingConvLower.h
@@ -26,7 +26,6 @@ namespace llvm {
class CCState;
class MVT;
-class TargetMachine;
class TargetRegisterInfo;
/// CCValAssign - Represent assignment of one arg/retval to a location.
@@ -165,9 +164,9 @@ public:
/// Describes a register that needs to be forwarded from the prologue to a
/// musttail call.
struct ForwardedRegister {
- ForwardedRegister(unsigned VReg, MCPhysReg PReg, MVT VT)
+ ForwardedRegister(Register VReg, MCPhysReg PReg, MVT VT)
: VReg(VReg), PReg(PReg), VT(VT) {}
- unsigned VReg;
+ Register VReg;
MCPhysReg PReg;
MVT VT;
};
@@ -222,9 +221,7 @@ private:
// ByValRegs[1] describes how "%t" is stored (Begin == r3, End == r4).
//
// In case of 8 bytes stack alignment,
- // ByValRegs may also contain information about wasted registers.
// In function shown above, r3 would be wasted according to AAPCS rules.
- // And in that case ByValRegs[1].Waste would be "true".
// ByValRegs vector size still would be 2,
// while "%t" goes to the stack: it wouldn't be described in ByValRegs.
//
@@ -234,19 +231,13 @@ private:
// 3. Argument analysis (LowerFormatArguments, for example). After
// some byval argument was analyzed, InRegsParamsProcessed is increased.
struct ByValInfo {
- ByValInfo(unsigned B, unsigned E, bool IsWaste = false) :
- Begin(B), End(E), Waste(IsWaste) {}
+ ByValInfo(unsigned B, unsigned E) : Begin(B), End(E) {}
+
// First register allocated for current parameter.
unsigned Begin;
// First after last register allocated for current parameter.
unsigned End;
-
- // Means that current range of registers doesn't belong to any
- // parameters. It was wasted due to stack alignment rules.
- // For more information see:
- // AAPCS, 5.5 Parameter Passing, Stage C, C.3.
- bool Waste;
};
SmallVector<ByValInfo, 4 > ByValRegs;
@@ -282,8 +273,8 @@ public:
/// isAllocated - Return true if the specified register (or an alias) is
/// allocated.
- bool isAllocated(unsigned Reg) const {
- return UsedRegs[Reg/32] & (1 << (Reg&31));
+ bool isAllocated(MCRegister Reg) const {
+ return UsedRegs[Reg / 32] & (1 << (Reg & 31));
}
/// AnalyzeFormalArguments - Analyze an array of argument values,
@@ -333,7 +324,7 @@ public:
/// A shadow allocated register is a register that was allocated
/// but wasn't added to the location list (Locs).
/// \returns true if the register was allocated as shadow or false otherwise.
- bool IsShadowAllocatedReg(unsigned Reg) const;
+ bool IsShadowAllocatedReg(MCRegister Reg) const;
/// AnalyzeCallResult - Same as above except it's specialized for calls which
/// produce a single value.
@@ -351,15 +342,17 @@ public:
/// AllocateReg - Attempt to allocate one register. If it is not available,
/// return zero. Otherwise, return the register, marking it and any aliases
/// as allocated.
- unsigned AllocateReg(unsigned Reg) {
- if (isAllocated(Reg)) return 0;
+ MCRegister AllocateReg(MCPhysReg Reg) {
+ if (isAllocated(Reg))
+ return MCRegister();
MarkAllocated(Reg);
return Reg;
}
/// Version of AllocateReg with extra register to be shadowed.
- unsigned AllocateReg(unsigned Reg, unsigned ShadowReg) {
- if (isAllocated(Reg)) return 0;
+ MCRegister AllocateReg(MCPhysReg Reg, MCPhysReg ShadowReg) {
+ if (isAllocated(Reg))
+ return MCRegister();
MarkAllocated(Reg);
MarkAllocated(ShadowReg);
return Reg;
@@ -368,13 +361,13 @@ public:
/// AllocateReg - Attempt to allocate one of the specified registers. If none
/// are available, return zero. Otherwise, return the first one available,
/// marking it and any aliases as allocated.
- unsigned AllocateReg(ArrayRef<MCPhysReg> Regs) {
+ MCPhysReg AllocateReg(ArrayRef<MCPhysReg> Regs) {
unsigned FirstUnalloc = getFirstUnallocated(Regs);
if (FirstUnalloc == Regs.size())
- return 0; // Didn't find the reg.
+ return MCRegister(); // Didn't find the reg.
// Mark the register and any aliases as allocated.
- unsigned Reg = Regs[FirstUnalloc];
+ MCPhysReg Reg = Regs[FirstUnalloc];
MarkAllocated(Reg);
return Reg;
}
@@ -382,7 +375,7 @@ public:
/// AllocateRegBlock - Attempt to allocate a block of RegsRequired consecutive
/// registers. If this is not possible, return zero. Otherwise, return the first
/// register of the block that were allocated, marking the entire block as allocated.
- unsigned AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) {
+ MCPhysReg AllocateRegBlock(ArrayRef<MCPhysReg> Regs, unsigned RegsRequired) {
if (RegsRequired > Regs.size())
return 0;
@@ -409,13 +402,13 @@ public:
}
/// Version of AllocateReg with list of registers to be shadowed.
- unsigned AllocateReg(ArrayRef<MCPhysReg> Regs, const MCPhysReg *ShadowRegs) {
+ MCRegister AllocateReg(ArrayRef<MCPhysReg> Regs, const MCPhysReg *ShadowRegs) {
unsigned FirstUnalloc = getFirstUnallocated(Regs);
if (FirstUnalloc == Regs.size())
- return 0; // Didn't find the reg.
+ return MCRegister(); // Didn't find the reg.
// Mark the register and any aliases as allocated.
- unsigned Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
+ MCRegister Reg = Regs[FirstUnalloc], ShadowReg = ShadowRegs[FirstUnalloc];
MarkAllocated(Reg);
MarkAllocated(ShadowReg);
return Reg;
@@ -423,42 +416,51 @@ public:
/// AllocateStack - Allocate a chunk of stack space with the specified size
/// and alignment.
- unsigned AllocateStack(unsigned Size, unsigned Alignment) {
- const Align CheckedAlignment(Alignment);
- StackOffset = alignTo(StackOffset, CheckedAlignment);
+ unsigned AllocateStack(unsigned Size, Align Alignment) {
+ StackOffset = alignTo(StackOffset, Alignment);
unsigned Result = StackOffset;
StackOffset += Size;
- MaxStackArgAlign = std::max(CheckedAlignment, MaxStackArgAlign);
- ensureMaxAlignment(CheckedAlignment);
+ MaxStackArgAlign = std::max(Alignment, MaxStackArgAlign);
+ ensureMaxAlignment(Alignment);
return Result;
}
+ // FIXME: Deprecate this function when transition to Align is over.
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned AllocateStack(unsigned Size,
+ unsigned Alignment),
+ "Use the version that takes Align instead.") {
+ return AllocateStack(Size, Align(Alignment));
+ }
+
void ensureMaxAlignment(Align Alignment) {
if (!AnalyzingMustTailForwardedRegs)
- MF.getFrameInfo().ensureMaxAlignment(Alignment.value());
+ MF.getFrameInfo().ensureMaxAlignment(Alignment);
}
/// Version of AllocateStack with extra register to be shadowed.
- unsigned AllocateStack(unsigned Size, unsigned Align, unsigned ShadowReg) {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned AllocateStack(unsigned Size,
+ unsigned Alignment,
+ unsigned ShadowReg),
+ "Use the version that takes Align instead.") {
MarkAllocated(ShadowReg);
- return AllocateStack(Size, Align);
+ return AllocateStack(Size, Align(Alignment));
}
/// Version of AllocateStack with list of extra registers to be shadowed.
/// Note that, unlike AllocateReg, this shadows ALL of the shadow registers.
- unsigned AllocateStack(unsigned Size, unsigned Align,
+ unsigned AllocateStack(unsigned Size, Align Alignment,
ArrayRef<MCPhysReg> ShadowRegs) {
for (unsigned i = 0; i < ShadowRegs.size(); ++i)
MarkAllocated(ShadowRegs[i]);
- return AllocateStack(Size, Align);
+ return AllocateStack(Size, Alignment);
}
// HandleByVal - Allocate a stack slot large enough to pass an argument by
// value. The size and alignment information of the argument is encoded in its
// parameter attribute.
- void HandleByVal(unsigned ValNo, MVT ValVT,
- MVT LocVT, CCValAssign::LocInfo LocInfo,
- int MinSize, int MinAlign, ISD::ArgFlagsTy ArgFlags);
+ void HandleByVal(unsigned ValNo, MVT ValVT, MVT LocVT,
+ CCValAssign::LocInfo LocInfo, int MinSize, Align MinAlign,
+ ISD::ArgFlagsTy ArgFlags);
// Returns count of byval arguments that are to be stored (even partly)
// in registers.
@@ -569,7 +571,7 @@ public:
private:
/// MarkAllocated - Mark a register and all of its aliases as allocated.
- void MarkAllocated(unsigned Reg);
+ void MarkAllocated(MCPhysReg Reg);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.h
new file mode 100644
index 000000000000..1b77556dcbb1
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -0,0 +1,151 @@
+//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains codegen-specific flags that are shared between different
+// command line tools. The tools "llc" and "opt" both use this file to prevent
+// flag duplication.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
+#include "llvm/Support/CodeGen.h"
+#include "llvm/Target/TargetOptions.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class Module;
+
+namespace codegen {
+
+std::string getMArch();
+
+std::string getMCPU();
+
+std::vector<std::string> getMAttrs();
+
+Reloc::Model getRelocModel();
+Optional<Reloc::Model> getExplicitRelocModel();
+
+ThreadModel::Model getThreadModel();
+
+CodeModel::Model getCodeModel();
+Optional<CodeModel::Model> getExplicitCodeModel();
+
+llvm::ExceptionHandling getExceptionModel();
+
+CodeGenFileType getFileType();
+Optional<CodeGenFileType> getExplicitFileType();
+
+CodeGenFileType getFileType();
+
+llvm::FramePointer::FP getFramePointerUsage();
+
+bool getEnableUnsafeFPMath();
+
+bool getEnableNoInfsFPMath();
+
+bool getEnableNoNaNsFPMath();
+
+bool getEnableNoSignedZerosFPMath();
+
+bool getEnableNoTrappingFPMath();
+
+DenormalMode::DenormalModeKind getDenormalFPMath();
+DenormalMode::DenormalModeKind getDenormalFP32Math();
+
+bool getEnableHonorSignDependentRoundingFPMath();
+
+llvm::FloatABI::ABIType getFloatABIForCalls();
+
+llvm::FPOpFusion::FPOpFusionMode getFuseFPOps();
+
+bool getDontPlaceZerosInBSS();
+
+bool getEnableGuaranteedTailCallOpt();
+
+bool getDisableTailCalls();
+
+bool getStackSymbolOrdering();
+
+unsigned getOverrideStackAlignment();
+
+bool getStackRealign();
+
+std::string getTrapFuncName();
+
+bool getUseCtors();
+
+bool getRelaxELFRelocations();
+
+bool getDataSections();
+Optional<bool> getExplicitDataSections();
+
+bool getFunctionSections();
+Optional<bool> getExplicitFunctionSections();
+
+std::string getBBSections();
+
+unsigned getTLSSize();
+
+bool getEmulatedTLS();
+
+bool getUniqueSectionNames();
+
+bool getUniqueBasicBlockSectionNames();
+
+llvm::EABI getEABIVersion();
+
+llvm::DebuggerKind getDebuggerTuningOpt();
+
+bool getEnableStackSizeSection();
+
+bool getEnableAddrsig();
+
+bool getEmitCallSiteInfo();
+
+bool getEnableDebugEntryValues();
+
+bool getForceDwarfFrameSection();
+
+bool getXRayOmitFunctionIndex();
+
+/// Create this object with static storage to register codegen-related command
+/// line options.
+struct RegisterCodeGenFlags {
+ RegisterCodeGenFlags();
+};
+
+llvm::BasicBlockSection getBBSectionsMode(llvm::TargetOptions &Options);
+
+// Common utility function tightly tied to the options listed here. Initializes
+// a TargetOptions object with CodeGen flags and returns it.
+TargetOptions InitTargetOptionsFromCodeGenFlags();
+
+std::string getCPUStr();
+
+std::string getFeaturesStr();
+
+std::vector<std::string> getFeatureList();
+
+void renderBoolStringAttr(AttrBuilder &B, StringRef Name, bool Val);
+
+/// Set function attributes of function \p F based on CPU, Features, and command
+/// line flags.
+void setFunctionAttributes(StringRef CPU, StringRef Features, Function &F);
+
+/// Set function attributes of functions in Module M based on CPU,
+/// Features, and command line flags.
+void setFunctionAttributes(StringRef CPU, StringRef Features, Module &M);
+} // namespace codegen
+} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.inc b/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.inc
deleted file mode 100644
index 8739b644873d..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/CommandFlags.inc
+++ /dev/null
@@ -1,428 +0,0 @@
-//===-- CommandFlags.h - Command Line Flags Interface -----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains codegen-specific flags that are shared between different
-// command line tools. The tools "llc" and "opt" both use this file to prevent
-// flag duplication.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
-#include "llvm/MC/MCTargetOptionsCommandFlags.inc"
-#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Support/CodeGen.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Host.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetOptions.h"
-#include <string>
-using namespace llvm;
-
-static cl::opt<std::string>
- MArch("march",
- cl::desc("Architecture to generate code for (see --version)"));
-
-static cl::opt<std::string>
- MCPU("mcpu",
- cl::desc("Target a specific cpu type (-mcpu=help for details)"),
- cl::value_desc("cpu-name"), cl::init(""));
-
-static cl::list<std::string>
- MAttrs("mattr", cl::CommaSeparated,
- cl::desc("Target specific attributes (-mattr=help for details)"),
- cl::value_desc("a1,+a2,-a3,..."));
-
-static cl::opt<Reloc::Model> RelocModel(
- "relocation-model", cl::desc("Choose relocation model"),
- cl::values(
- clEnumValN(Reloc::Static, "static", "Non-relocatable code"),
- clEnumValN(Reloc::PIC_, "pic",
- "Fully relocatable, position independent code"),
- clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
- "Relocatable external references, non-relocatable code"),
- clEnumValN(Reloc::ROPI, "ropi",
- "Code and read-only data relocatable, accessed PC-relative"),
- clEnumValN(
- Reloc::RWPI, "rwpi",
- "Read-write data relocatable, accessed relative to static base"),
- clEnumValN(Reloc::ROPI_RWPI, "ropi-rwpi",
- "Combination of ropi and rwpi")));
-
-LLVM_ATTRIBUTE_UNUSED static Optional<Reloc::Model> getRelocModel() {
- if (RelocModel.getNumOccurrences()) {
- Reloc::Model R = RelocModel;
- return R;
- }
- return None;
-}
-
-static cl::opt<ThreadModel::Model> TMModel(
- "thread-model", cl::desc("Choose threading model"),
- cl::init(ThreadModel::POSIX),
- cl::values(clEnumValN(ThreadModel::POSIX, "posix", "POSIX thread model"),
- clEnumValN(ThreadModel::Single, "single",
- "Single thread model")));
-
-static cl::opt<llvm::CodeModel::Model> CMModel(
- "code-model", cl::desc("Choose code model"),
- cl::values(clEnumValN(CodeModel::Tiny, "tiny", "Tiny code model"),
- clEnumValN(CodeModel::Small, "small", "Small code model"),
- clEnumValN(CodeModel::Kernel, "kernel", "Kernel code model"),
- clEnumValN(CodeModel::Medium, "medium", "Medium code model"),
- clEnumValN(CodeModel::Large, "large", "Large code model")));
-
-LLVM_ATTRIBUTE_UNUSED static Optional<CodeModel::Model> getCodeModel() {
- if (CMModel.getNumOccurrences()) {
- CodeModel::Model M = CMModel;
- return M;
- }
- return None;
-}
-
-static cl::opt<llvm::ExceptionHandling> ExceptionModel(
- "exception-model", cl::desc("exception model"),
- cl::init(ExceptionHandling::None),
- cl::values(
- clEnumValN(ExceptionHandling::None, "default",
- "default exception handling model"),
- clEnumValN(ExceptionHandling::DwarfCFI, "dwarf",
- "DWARF-like CFI based exception handling"),
- clEnumValN(ExceptionHandling::SjLj, "sjlj", "SjLj exception handling"),
- clEnumValN(ExceptionHandling::ARM, "arm", "ARM EHABI exceptions"),
- clEnumValN(ExceptionHandling::WinEH, "wineh",
- "Windows exception model"),
- clEnumValN(ExceptionHandling::Wasm, "wasm",
- "WebAssembly exception handling")));
-
-static cl::opt<CodeGenFileType> FileType(
- "filetype", cl::init(CGFT_AssemblyFile),
- cl::desc(
- "Choose a file type (not all types are supported by all targets):"),
- cl::values(clEnumValN(CGFT_AssemblyFile, "asm",
- "Emit an assembly ('.s') file"),
- clEnumValN(CGFT_ObjectFile, "obj",
- "Emit a native object ('.o') file"),
- clEnumValN(CGFT_Null, "null",
- "Emit nothing, for performance testing")));
-
-static cl::opt<llvm::FramePointer::FP> FramePointerUsage(
- "frame-pointer", cl::desc("Specify frame pointer elimination optimization"),
- cl::init(llvm::FramePointer::None),
- cl::values(
- clEnumValN(llvm::FramePointer::All, "all",
- "Disable frame pointer elimination"),
- clEnumValN(llvm::FramePointer::NonLeaf, "non-leaf",
- "Disable frame pointer elimination for non-leaf frame"),
- clEnumValN(llvm::FramePointer::None, "none",
- "Enable frame pointer elimination")));
-
-static cl::opt<bool> EnableUnsafeFPMath(
- "enable-unsafe-fp-math",
- cl::desc("Enable optimizations that may decrease FP precision"),
- cl::init(false));
-
-static cl::opt<bool> EnableNoInfsFPMath(
- "enable-no-infs-fp-math",
- cl::desc("Enable FP math optimizations that assume no +-Infs"),
- cl::init(false));
-
-static cl::opt<bool> EnableNoNaNsFPMath(
- "enable-no-nans-fp-math",
- cl::desc("Enable FP math optimizations that assume no NaNs"),
- cl::init(false));
-
-static cl::opt<bool> EnableNoSignedZerosFPMath(
- "enable-no-signed-zeros-fp-math",
- cl::desc("Enable FP math optimizations that assume "
- "the sign of 0 is insignificant"),
- cl::init(false));
-
-static cl::opt<bool>
- EnableNoTrappingFPMath("enable-no-trapping-fp-math",
- cl::desc("Enable setting the FP exceptions build "
- "attribute not to use exceptions"),
- cl::init(false));
-
-static cl::opt<llvm::FPDenormal::DenormalMode> DenormalFPMath(
- "denormal-fp-math",
- cl::desc("Select which denormal numbers the code is permitted to require"),
- cl::init(FPDenormal::IEEE),
- cl::values(clEnumValN(FPDenormal::IEEE, "ieee",
- "IEEE 754 denormal numbers"),
- clEnumValN(FPDenormal::PreserveSign, "preserve-sign",
- "the sign of a flushed-to-zero number is preserved "
- "in the sign of 0"),
- clEnumValN(FPDenormal::PositiveZero, "positive-zero",
- "denormals are flushed to positive zero")));
-
-static cl::opt<bool> EnableHonorSignDependentRoundingFPMath(
- "enable-sign-dependent-rounding-fp-math", cl::Hidden,
- cl::desc("Force codegen to assume rounding mode can change dynamically"),
- cl::init(false));
-
-static cl::opt<llvm::FloatABI::ABIType> FloatABIForCalls(
- "float-abi", cl::desc("Choose float ABI type"), cl::init(FloatABI::Default),
- cl::values(clEnumValN(FloatABI::Default, "default",
- "Target default float ABI type"),
- clEnumValN(FloatABI::Soft, "soft",
- "Soft float ABI (implied by -soft-float)"),
- clEnumValN(FloatABI::Hard, "hard",
- "Hard float ABI (uses FP registers)")));
-
-static cl::opt<llvm::FPOpFusion::FPOpFusionMode> FuseFPOps(
- "fp-contract", cl::desc("Enable aggressive formation of fused FP ops"),
- cl::init(FPOpFusion::Standard),
- cl::values(
- clEnumValN(FPOpFusion::Fast, "fast", "Fuse FP ops whenever profitable"),
- clEnumValN(FPOpFusion::Standard, "on", "Only fuse 'blessed' FP ops."),
- clEnumValN(FPOpFusion::Strict, "off",
- "Only fuse FP ops when the result won't be affected.")));
-
-static cl::opt<bool> DontPlaceZerosInBSS(
- "nozero-initialized-in-bss",
- cl::desc("Don't place zero-initialized symbols into bss section"),
- cl::init(false));
-
-static cl::opt<bool> EnableGuaranteedTailCallOpt(
- "tailcallopt",
- cl::desc(
- "Turn fastcc calls into tail calls by (potentially) changing ABI."),
- cl::init(false));
-
-static cl::opt<bool> DisableTailCalls("disable-tail-calls",
- cl::desc("Never emit tail calls"),
- cl::init(false));
-
-static cl::opt<bool> StackSymbolOrdering("stack-symbol-ordering",
- cl::desc("Order local stack symbols."),
- cl::init(true));
-
-static cl::opt<unsigned>
- OverrideStackAlignment("stack-alignment",
- cl::desc("Override default stack alignment"),
- cl::init(0));
-
-static cl::opt<bool>
- StackRealign("stackrealign",
- cl::desc("Force align the stack to the minimum alignment"),
- cl::init(false));
-
-static cl::opt<std::string> TrapFuncName(
- "trap-func", cl::Hidden,
- cl::desc("Emit a call to trap function rather than a trap instruction"),
- cl::init(""));
-
-static cl::opt<bool> UseCtors("use-ctors",
- cl::desc("Use .ctors instead of .init_array."),
- cl::init(false));
-
-static cl::opt<bool> RelaxELFRelocations(
- "relax-elf-relocations",
- cl::desc("Emit GOTPCRELX/REX_GOTPCRELX instead of GOTPCREL on x86-64 ELF"),
- cl::init(false));
-
-static cl::opt<bool> DataSections("data-sections",
- cl::desc("Emit data into separate sections"),
- cl::init(false));
-
-static cl::opt<bool>
- FunctionSections("function-sections",
- cl::desc("Emit functions into separate sections"),
- cl::init(false));
-
-static cl::opt<unsigned> TLSSize("tls-size",
- cl::desc("Bit size of immediate TLS offsets"),
- cl::init(0));
-
-static cl::opt<bool> EmulatedTLS("emulated-tls",
- cl::desc("Use emulated TLS model"),
- cl::init(false));
-
-static cl::opt<bool>
- UniqueSectionNames("unique-section-names",
- cl::desc("Give unique names to every section"),
- cl::init(true));
-
-static cl::opt<llvm::EABI>
- EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
- cl::init(EABI::Default),
- cl::values(clEnumValN(EABI::Default, "default",
- "Triple default EABI version"),
- clEnumValN(EABI::EABI4, "4", "EABI version 4"),
- clEnumValN(EABI::EABI5, "5", "EABI version 5"),
- clEnumValN(EABI::GNU, "gnu", "EABI GNU")));
-
-static cl::opt<DebuggerKind> DebuggerTuningOpt(
- "debugger-tune", cl::desc("Tune debug info for a particular debugger"),
- cl::init(DebuggerKind::Default),
- cl::values(clEnumValN(DebuggerKind::GDB, "gdb", "gdb"),
- clEnumValN(DebuggerKind::LLDB, "lldb", "lldb"),
- clEnumValN(DebuggerKind::SCE, "sce", "SCE targets (e.g. PS4)")));
-
-static cl::opt<bool> EnableStackSizeSection(
- "stack-size-section",
- cl::desc("Emit a section containing stack size metadata"), cl::init(false));
-
-static cl::opt<bool>
- EnableAddrsig("addrsig", cl::desc("Emit an address-significance table"),
- cl::init(false));
-
-static cl::opt<bool>
- EnableDebugEntryValues("debug-entry-values",
- cl::desc("Emit debug info about parameter's entry values"),
- cl::init(false));
-
-static cl::opt<bool>
- ForceDwarfFrameSection("force-dwarf-frame-section",
- cl::desc("Always emit a debug frame section."),
- cl::init(false));
-
-// Common utility function tightly tied to the options listed here. Initializes
-// a TargetOptions object with CodeGen flags and returns it.
-static TargetOptions InitTargetOptionsFromCodeGenFlags() {
- TargetOptions Options;
- Options.AllowFPOpFusion = FuseFPOps;
- Options.UnsafeFPMath = EnableUnsafeFPMath;
- Options.NoInfsFPMath = EnableNoInfsFPMath;
- Options.NoNaNsFPMath = EnableNoNaNsFPMath;
- Options.NoSignedZerosFPMath = EnableNoSignedZerosFPMath;
- Options.NoTrappingFPMath = EnableNoTrappingFPMath;
- Options.FPDenormalMode = DenormalFPMath;
- Options.HonorSignDependentRoundingFPMathOption =
- EnableHonorSignDependentRoundingFPMath;
- if (FloatABIForCalls != FloatABI::Default)
- Options.FloatABIType = FloatABIForCalls;
- Options.NoZerosInBSS = DontPlaceZerosInBSS;
- Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
- Options.StackAlignmentOverride = OverrideStackAlignment;
- Options.StackSymbolOrdering = StackSymbolOrdering;
- Options.UseInitArray = !UseCtors;
- Options.RelaxELFRelocations = RelaxELFRelocations;
- Options.DataSections = DataSections;
- Options.FunctionSections = FunctionSections;
- Options.UniqueSectionNames = UniqueSectionNames;
- Options.TLSSize = TLSSize;
- Options.EmulatedTLS = EmulatedTLS;
- Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0;
- Options.ExceptionModel = ExceptionModel;
- Options.EmitStackSizeSection = EnableStackSizeSection;
- Options.EmitAddrsig = EnableAddrsig;
- Options.EnableDebugEntryValues = EnableDebugEntryValues;
- Options.ForceDwarfFrameSection = ForceDwarfFrameSection;
-
- Options.MCOptions = InitMCTargetOptionsFromFlags();
-
- Options.ThreadModel = TMModel;
- Options.EABIVersion = EABIVersion;
- Options.DebuggerTuning = DebuggerTuningOpt;
-
- return Options;
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::string getCPUStr() {
- // If user asked for the 'native' CPU, autodetect here. If autodection fails,
- // this will set the CPU to an empty string which tells the target to
- // pick a basic default.
- if (MCPU == "native")
- return sys::getHostCPUName();
-
- return MCPU;
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::string getFeaturesStr() {
- SubtargetFeatures Features;
-
- // If user asked for the 'native' CPU, we need to autodetect features.
- // This is necessary for x86 where the CPU might not support all the
- // features the autodetected CPU name lists in the target. For example,
- // not all Sandybridge processors support AVX.
- if (MCPU == "native") {
- StringMap<bool> HostFeatures;
- if (sys::getHostCPUFeatures(HostFeatures))
- for (auto &F : HostFeatures)
- Features.AddFeature(F.first(), F.second);
- }
-
- for (unsigned i = 0; i != MAttrs.size(); ++i)
- Features.AddFeature(MAttrs[i]);
-
- return Features.getString();
-}
-
-LLVM_ATTRIBUTE_UNUSED static std::vector<std::string> getFeatureList() {
- SubtargetFeatures Features;
-
- // If user asked for the 'native' CPU, we need to autodetect features.
- // This is necessary for x86 where the CPU might not support all the
- // features the autodetected CPU name lists in the target. For example,
- // not all Sandybridge processors support AVX.
- if (MCPU == "native") {
- StringMap<bool> HostFeatures;
- if (sys::getHostCPUFeatures(HostFeatures))
- for (auto &F : HostFeatures)
- Features.AddFeature(F.first(), F.second);
- }
-
- for (unsigned i = 0; i != MAttrs.size(); ++i)
- Features.AddFeature(MAttrs[i]);
-
- return Features.getFeatures();
-}
-
-/// Set function attributes of function \p F based on CPU, Features, and command
-/// line flags.
-LLVM_ATTRIBUTE_UNUSED static void
-setFunctionAttributes(StringRef CPU, StringRef Features, Function &F) {
- auto &Ctx = F.getContext();
- AttributeList Attrs = F.getAttributes();
- AttrBuilder NewAttrs;
-
- if (!CPU.empty() && !F.hasFnAttribute("target-cpu"))
- NewAttrs.addAttribute("target-cpu", CPU);
- if (!Features.empty())
- NewAttrs.addAttribute("target-features", Features);
- if (FramePointerUsage.getNumOccurrences() > 0) {
- if (FramePointerUsage == llvm::FramePointer::All)
- NewAttrs.addAttribute("frame-pointer", "all");
- else if (FramePointerUsage == llvm::FramePointer::NonLeaf)
- NewAttrs.addAttribute("frame-pointer", "non-leaf");
- else if (FramePointerUsage == llvm::FramePointer::None)
- NewAttrs.addAttribute("frame-pointer", "none");
- }
- if (DisableTailCalls.getNumOccurrences() > 0)
- NewAttrs.addAttribute("disable-tail-calls",
- toStringRef(DisableTailCalls));
- if (StackRealign)
- NewAttrs.addAttribute("stackrealign");
-
- if (TrapFuncName.getNumOccurrences() > 0)
- for (auto &B : F)
- for (auto &I : B)
- if (auto *Call = dyn_cast<CallInst>(&I))
- if (const auto *F = Call->getCalledFunction())
- if (F->getIntrinsicID() == Intrinsic::debugtrap ||
- F->getIntrinsicID() == Intrinsic::trap)
- Call->addAttribute(
- llvm::AttributeList::FunctionIndex,
- Attribute::get(Ctx, "trap-func-name", TrapFuncName));
-
- // Let NewAttrs override Attrs.
- F.setAttributes(
- Attrs.addAttributes(Ctx, AttributeList::FunctionIndex, NewAttrs));
-}
-
-/// Set function attributes of functions in Module M based on CPU,
-/// Features, and command line flags.
-LLVM_ATTRIBUTE_UNUSED static void
-setFunctionAttributes(StringRef CPU, StringRef Features, Module &M) {
- for (Function &F : M)
- setFunctionAttributes(CPU, Features, F);
-}
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/DIE.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/DIE.h
index 40f6b041e9b3..c7baaf6aef3d 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/DIE.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/DIE.h
@@ -190,7 +190,7 @@ public:
uint64_t getValue() const { return Integer; }
void setValue(uint64_t Val) { Integer = Val; }
- void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -207,7 +207,7 @@ public:
/// Get MCExpr.
const MCExpr *getValue() const { return Expr; }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -224,7 +224,7 @@ public:
/// Get MCSymbol.
const MCSymbol *getValue() const { return Label; }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -242,7 +242,7 @@ public:
: CU(TheCU), Index(Idx) {}
/// EmitValue - Emit base type reference.
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
/// SizeOf - Determine size of the base type reference in bytes.
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
@@ -259,7 +259,7 @@ class DIEDelta {
public:
DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -278,7 +278,7 @@ public:
/// Grab the string out of the object.
StringRef getString() const { return S.getString(); }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -300,7 +300,7 @@ public:
/// Grab the string out of the object.
StringRef getString() const { return S; }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -319,7 +319,7 @@ public:
DIE &getEntry() const { return *Entry; }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -338,7 +338,7 @@ public:
/// Grab the current index out.
size_t getValue() const { return Index; }
- void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -485,7 +485,7 @@ public:
#include "llvm/CodeGen/DIEValue.def"
/// Emit value via the Dwarf writer.
- void EmitValue(const AsmPrinter *AP) const;
+ void emitValue(const AsmPrinter *AP) const;
/// Return the size of a value in bytes.
unsigned SizeOf(const AsmPrinter *AP) const;
@@ -551,10 +551,21 @@ public:
}
void takeNodes(IntrusiveBackList<T> &Other) {
- for (auto &N : Other) {
- N.Next.setPointerAndInt(&N, true);
- push_back(N);
- }
+ if (Other.empty())
+ return;
+
+ T *FirstNode = static_cast<T *>(Other.Last->Next.getPointer());
+ T *IterNode = FirstNode;
+ do {
+ // Keep a pointer to the node and increment the iterator.
+ T *TmpNode = IterNode;
+ IterNode = static_cast<T *>(IterNode->Next.getPointer());
+
+ // Unlink the node and push it back to this list.
+ TmpNode->Next.setPointerAndInt(TmpNode, true);
+ push_back(*TmpNode);
+ } while (IterNode != FirstNode);
+
Other.Last = nullptr;
}
@@ -910,6 +921,9 @@ public:
///
unsigned ComputeSize(const AsmPrinter *AP) const;
+ // TODO: move setSize() and Size to DIEValueList.
+ void setSize(unsigned size) { Size = size; }
+
/// BestForm - Choose the best form for data.
///
dwarf::Form BestForm(unsigned DwarfVersion) const {
@@ -925,7 +939,7 @@ public:
return dwarf::DW_FORM_block;
}
- void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
@@ -944,6 +958,9 @@ public:
///
unsigned ComputeSize(const AsmPrinter *AP) const;
+ // TODO: move setSize() and Size to DIEValueList.
+ void setSize(unsigned size) { Size = size; }
+
/// BestForm - Choose the best form for data.
///
dwarf::Form BestForm() const {
@@ -956,7 +973,7 @@ public:
return dwarf::DW_FORM_block;
}
- void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
+ void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const;
void print(raw_ostream &O) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/DbgEntityHistoryCalculator.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
index 7eec75bc81bf..f7fc74a27fca 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/DbgEntityHistoryCalculator.h
@@ -12,12 +12,13 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/DebugInfoMetadata.h"
#include <utility>
namespace llvm {
class DILocalVariable;
+class DILocation;
+class DINode;
class MachineFunction;
class MachineInstr;
class TargetRegisterInfo;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h
index 4008d597395e..4ff0fdea36ae 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/DebugHandlerBase.h
@@ -18,8 +18,8 @@
#include "llvm/CodeGen/AsmPrinterHandler.h"
#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
#include "llvm/CodeGen/LexicalScopes.h"
-#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
namespace llvm {
@@ -118,16 +118,15 @@ public:
void beginFunction(const MachineFunction *MF) override;
void endFunction(const MachineFunction *MF) override;
+ void beginBasicBlock(const MachineBasicBlock &MBB) override;
+ void endBasicBlock(const MachineBasicBlock &MBB) override;
+
/// Return Label preceding the instruction.
MCSymbol *getLabelBeforeInsn(const MachineInstr *MI);
/// Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
- /// Return the function-local offset of an instruction. A label for the
- /// instruction \p MI should exist (\ref getLabelAfterInsn).
- const MCExpr *getFunctionLocalOffsetAfterInsn(const MachineInstr *MI);
-
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(const DIType *Ty);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/EdgeBundles.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/EdgeBundles.h
index 28cdf54e0575..b26956023971 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/EdgeBundles.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/EdgeBundles.h
@@ -17,7 +17,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IntEqClasses.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ExecutionDomainFix.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
index 6836678e2101..c87d4f993e77 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ExecutionDomainFix.h
@@ -30,7 +30,6 @@
namespace llvm {
-class MachineBasicBlock;
class MachineInstr;
class TargetInstrInfo;
@@ -81,10 +80,20 @@ struct DomainValue {
}
/// Mark domain as available.
- void addDomain(unsigned domain) { AvailableDomains |= 1u << domain; }
+ void addDomain(unsigned domain) {
+ assert(domain <
+ static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
+ "undefined behavior");
+ AvailableDomains |= 1u << domain;
+ }
// Restrict to a single domain available.
- void setSingleDomain(unsigned domain) { AvailableDomains = 1u << domain; }
+ void setSingleDomain(unsigned domain) {
+ assert(domain <
+ static_cast<unsigned>(std::numeric_limits<unsigned>::digits) &&
+ "undefined behavior");
+ AvailableDomains = 1u << domain;
+ }
/// Return bitmask of domains that are available and in mask.
unsigned getCommonDomains(unsigned mask) const {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/FastISel.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/FastISel.h
index d9c680392e50..7662179db44d 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/FastISel.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/FastISel.h
@@ -20,7 +20,6 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DerivedTypes.h"
@@ -86,9 +85,9 @@ public:
const Value *Callee = nullptr;
MCSymbol *Symbol = nullptr;
ArgListTy Args;
- ImmutableCallSite *CS = nullptr;
+ const CallBase *CB = nullptr;
MachineInstr *Call = nullptr;
- unsigned ResultReg = 0;
+ Register ResultReg;
unsigned NumResultRegs = 0;
SmallVector<Value *, 16> OutVals;
@@ -103,14 +102,14 @@ public:
CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
const Value *Target, ArgListTy &&ArgsList,
- ImmutableCallSite &Call) {
+ const CallBase &Call) {
RetTy = ResultTy;
Callee = Target;
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
- IsReturnValueUsed = !Call.getInstruction()->use_empty();
+ IsReturnValueUsed = !Call.use_empty();
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
@@ -118,23 +117,23 @@ public:
Args = std::move(ArgsList);
NumFixedArgs = FuncTy->getNumParams();
- CS = &Call;
+ CB = &Call;
return *this;
}
CallLoweringInfo &setCallee(Type *ResultTy, FunctionType *FuncTy,
MCSymbol *Target, ArgListTy &&ArgsList,
- ImmutableCallSite &Call,
+ const CallBase &Call,
unsigned FixedArgs = ~0U) {
RetTy = ResultTy;
- Callee = Call.getCalledValue();
+ Callee = Call.getCalledOperand();
Symbol = Target;
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn = Call.doesNotReturn();
IsVarArg = FuncTy->isVarArg();
- IsReturnValueUsed = !Call.getInstruction()->use_empty();
+ IsReturnValueUsed = !Call.use_empty();
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
@@ -142,7 +141,7 @@ public:
Args = std::move(ArgsList);
NumFixedArgs = (FixedArgs == ~0U) ? FuncTy->getNumParams() : FixedArgs;
- CS = &Call;
+ CB = &Call;
return *this;
}
@@ -199,7 +198,7 @@ public:
};
protected:
- DenseMap<const Value *, unsigned> LocalValueMap;
+ DenseMap<const Value *, Register> LocalValueMap;
FunctionLoweringInfo &FuncInfo;
MachineFunction *MF;
MachineRegisterInfo &MRI;
@@ -270,16 +269,16 @@ public:
/// Create a virtual register and arrange for it to be assigned the
/// value for the given LLVM value.
- unsigned getRegForValue(const Value *V);
+ Register getRegForValue(const Value *V);
/// Look up the value to see if its value is already cached in a
/// register. It may be defined by instructions across blocks or defined
/// locally.
- unsigned lookUpRegForValue(const Value *V);
+ Register lookUpRegForValue(const Value *V);
/// This is a wrapper around getRegForValue that also takes care of
/// truncating or sign-extending the given getelementptr index value.
- std::pair<unsigned, bool> getRegForGEPIndex(const Value *Idx);
+ std::pair<Register, bool> getRegForGEPIndex(const Value *Idx);
/// We're checking to see if we can fold \p LI into \p FoldInst. Note
/// that we could have a sequence where multiple LLVM IR instructions are
@@ -374,7 +373,7 @@ protected:
/// It first tries to emit an instruction with an immediate operand using
/// fastEmit_ri. If that fails, it materializes the immediate into a register
/// and try fastEmit_rr instead.
- unsigned fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, bool Op0IsKill,
+ Register fastEmit_ri_(MVT VT, unsigned Opcode, unsigned Op0, bool Op0IsKill,
uint64_t Imm, MVT ImmType);
/// This method is called by target-independent code to request that an
@@ -389,66 +388,66 @@ protected:
/// Emit a MachineInstr with no operands and a result register in the
/// given register class.
- unsigned fastEmitInst_(unsigned MachineInstOpcode,
+ Register fastEmitInst_(unsigned MachineInstOpcode,
const TargetRegisterClass *RC);
/// Emit a MachineInstr with one register operand and a result register
/// in the given register class.
- unsigned fastEmitInst_r(unsigned MachineInstOpcode,
+ Register fastEmitInst_r(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill);
/// Emit a MachineInstr with two register operands and a result
/// register in the given register class.
- unsigned fastEmitInst_rr(unsigned MachineInstOpcode,
+ Register fastEmitInst_rr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill);
/// Emit a MachineInstr with three register operands and a result
/// register in the given register class.
- unsigned fastEmitInst_rrr(unsigned MachineInstOpcode,
+ Register fastEmitInst_rrr(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill,
unsigned Op2, bool Op2IsKill);
/// Emit a MachineInstr with a register operand, an immediate, and a
/// result register in the given register class.
- unsigned fastEmitInst_ri(unsigned MachineInstOpcode,
+ Register fastEmitInst_ri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, uint64_t Imm);
/// Emit a MachineInstr with one register operand and two immediate
/// operands.
- unsigned fastEmitInst_rii(unsigned MachineInstOpcode,
+ Register fastEmitInst_rii(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, uint64_t Imm1, uint64_t Imm2);
/// Emit a MachineInstr with a floating point immediate, and a result
/// register in the given register class.
- unsigned fastEmitInst_f(unsigned MachineInstOpcode,
+ Register fastEmitInst_f(unsigned MachineInstOpcode,
const TargetRegisterClass *RC,
const ConstantFP *FPImm);
/// Emit a MachineInstr with two register operands, an immediate, and a
/// result register in the given register class.
- unsigned fastEmitInst_rri(unsigned MachineInstOpcode,
+ Register fastEmitInst_rri(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, unsigned Op0,
bool Op0IsKill, unsigned Op1, bool Op1IsKill,
uint64_t Imm);
/// Emit a MachineInstr with a single immediate operand, and a result
/// register in the given register class.
- unsigned fastEmitInst_i(unsigned MachineInstOpcode,
+ Register fastEmitInst_i(unsigned MachineInstOpcode,
const TargetRegisterClass *RC, uint64_t Imm);
/// Emit a MachineInstr for an extract_subreg from a specified index of
/// a superregister to a specified type.
- unsigned fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill,
+ Register fastEmitInst_extractsubreg(MVT RetVT, unsigned Op0, bool Op0IsKill,
uint32_t Idx);
/// Emit MachineInstrs to compute the value of Op with all but the
/// least significant bit set to zero.
- unsigned fastEmitZExtFromI1(MVT VT, unsigned Op0, bool Op0IsKill);
+ Register fastEmitZExtFromI1(MVT VT, unsigned Op0, bool Op0IsKill);
/// Emit an unconditional branch to the given block, unless it is the
/// immediate (fall-through) successor, and update the CFG.
@@ -466,14 +465,14 @@ protected:
/// NOTE: This is only necessary because we might select a block that uses a
/// value before we select the block that defines the value. It might be
/// possible to fix this by selecting blocks in reverse postorder.
- void updateValueMap(const Value *I, unsigned Reg, unsigned NumRegs = 1);
+ void updateValueMap(const Value *I, Register Reg, unsigned NumRegs = 1);
- unsigned createResultReg(const TargetRegisterClass *RC);
+ Register createResultReg(const TargetRegisterClass *RC);
/// Try to constrain Op so that it is usable by argument OpNum of the
/// provided MCInstrDesc. If this fails, create a new virtual register in the
/// correct class and COPY the value there.
- unsigned constrainOperandRegClass(const MCInstrDesc &II, unsigned Op,
+ Register constrainOperandRegClass(const MCInstrDesc &II, Register Op,
unsigned OpNum);
/// Emit a constant in a register using target-specific logic, such as
@@ -534,6 +533,7 @@ protected:
bool selectCall(const User *I);
bool selectIntrinsicCall(const IntrinsicInst *II);
bool selectBitCast(const User *I);
+ bool selectFreeze(const User *I);
bool selectCast(const User *I, unsigned Opcode);
bool selectExtractValue(const User *U);
bool selectInsertValue(const User *I);
@@ -557,12 +557,12 @@ private:
/// Helper for materializeRegForValue to materialize a constant in a
/// target-independent way.
- unsigned materializeConstant(const Value *V, MVT VT);
+ Register materializeConstant(const Value *V, MVT VT);
/// Helper for getRegForVale. This function is called when the value
/// isn't already available in a register and must be materialized with new
/// instructions.
- unsigned materializeRegForValue(const Value *V, MVT VT);
+ Register materializeRegForValue(const Value *V, MVT VT);
/// Clears LocalValueMap and moves the area for the new local variables
/// to the beginning of the block. It helps to avoid spilling cached variables
@@ -583,7 +583,7 @@ private:
/// Sinks the local value materialization instruction LocalMI to its first use
/// in the basic block, or deletes it if it is not used.
- void sinkLocalValueMaterialization(MachineInstr &LocalMI, unsigned DefReg,
+ void sinkLocalValueMaterialization(MachineInstr &LocalMI, Register DefReg,
InstOrderMap &OrderMap);
/// Insertion point before trying to select the current instruction.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
index 2d41f90fe053..c99ca00eac29 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -13,7 +13,7 @@
#ifndef LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
#define LLVM_CODEGEN_FUNCTIONLOWERINGINFO_H
-#include "llvm/ADT/APInt.h"
+
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
@@ -67,7 +67,7 @@ public:
/// DemoteRegister - if CanLowerReturn is false, DemoteRegister is a vreg
/// allocated to hold a pointer to the hidden sret parameter.
- unsigned DemoteRegister;
+ Register DemoteRegister;
/// MBBMap - A mapping from LLVM basic blocks to their machine code entry.
DenseMap<const BasicBlock*, MachineBasicBlock *> MBBMap;
@@ -75,52 +75,29 @@ public:
/// ValueMap - Since we emit code for the function a basic block at a time,
/// we must remember which virtual registers hold the values for
/// cross-basic-block values.
- DenseMap<const Value *, unsigned> ValueMap;
+ DenseMap<const Value *, Register> ValueMap;
/// VirtReg2Value map is needed by the Divergence Analysis driven
/// instruction selection. It is reverted ValueMap. It is computed
/// in lazy style - on demand. It is used to get the Value corresponding
/// to the live in virtual register and is called from the
/// TargetLowerinInfo::isSDNodeSourceOfDivergence.
- DenseMap<unsigned, const Value*> VirtReg2Value;
+ DenseMap<Register, const Value*> VirtReg2Value;
/// This method is called from TargetLowerinInfo::isSDNodeSourceOfDivergence
/// to get the Value corresponding to the live-in virtual register.
- const Value * getValueFromVirtualReg(unsigned Vreg);
+ const Value *getValueFromVirtualReg(Register Vreg);
/// Track virtual registers created for exception pointers.
- DenseMap<const Value *, unsigned> CatchPadExceptionPointers;
+ DenseMap<const Value *, Register> CatchPadExceptionPointers;
/// Keep track of frame indices allocated for statepoints as they could be
- /// used across basic block boundaries. This struct is more complex than a
- /// simple map because the stateopint lowering code de-duplicates gc pointers
- /// based on their SDValue (so %p and (bitcast %p to T) will get the same
- /// slot), and we track that here.
-
- struct StatepointSpillMap {
- using SlotMapTy = DenseMap<const Value *, Optional<int>>;
-
- /// Maps uniqued llvm IR values to the slots they were spilled in. If a
- /// value is mapped to None it means we visited the value but didn't spill
- /// it (because it was a constant, for instance).
- SlotMapTy SlotMap;
-
- /// Maps llvm IR values to the values they were de-duplicated to.
- DenseMap<const Value *, const Value *> DuplicateMap;
-
- SlotMapTy::const_iterator find(const Value *V) const {
- auto DuplIt = DuplicateMap.find(V);
- if (DuplIt != DuplicateMap.end())
- V = DuplIt->second;
- return SlotMap.find(V);
- }
-
- SlotMapTy::const_iterator end() const { return SlotMap.end(); }
- };
-
- /// Maps gc.statepoint instructions to their corresponding StatepointSpillMap
- /// instances.
- DenseMap<const Instruction *, StatepointSpillMap> StatepointSpillMaps;
+ /// used across basic block boundaries (e.g. for an invoke). For each
+ /// gc.statepoint instruction, maps uniqued llvm IR values to the slots they
+ /// were spilled in. If a value is mapped to None it means we visited the
+ /// value but didn't spill it (because it was a constant, for instance).
+ using StatepointSpillMapTy = DenseMap<const Value *, Optional<int>>;
+ DenseMap<const Instruction *, StatepointSpillMapTy> StatepointSpillMaps;
/// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
/// the entry block. This allows the allocas to be efficiently referenced
@@ -139,9 +116,9 @@ public:
BitVector DescribedArgs;
/// RegFixups - Registers which need to be replaced after isel is done.
- DenseMap<unsigned, unsigned> RegFixups;
+ DenseMap<Register, Register> RegFixups;
- DenseSet<unsigned> RegsWithFixups;
+ DenseSet<Register> RegsWithFixups;
/// StatepointStackSlots - A list of temporary stack slots (frame indices)
/// used to spill values at a statepoint. We store them here to enable
@@ -199,17 +176,17 @@ public:
return ValueMap.count(V);
}
- unsigned CreateReg(MVT VT, bool isDivergent = false);
+ Register CreateReg(MVT VT, bool isDivergent = false);
- unsigned CreateRegs(const Value *V);
+ Register CreateRegs(const Value *V);
- unsigned CreateRegs(Type *Ty, bool isDivergent = false);
+ Register CreateRegs(Type *Ty, bool isDivergent = false);
- unsigned InitializeRegForValue(const Value *V) {
+ Register InitializeRegForValue(const Value *V) {
// Tokens never live in vregs.
if (V->getType()->isTokenTy())
return 0;
- unsigned &R = ValueMap[V];
+ Register &R = ValueMap[V];
assert(R == 0 && "Already initialized this value register!");
assert(VirtReg2Value.empty());
return R = CreateRegs(V);
@@ -217,7 +194,7 @@ public:
/// GetLiveOutRegInfo - Gets LiveOutInfo for a register, returning NULL if the
/// register is a PHI destination and the PHI's LiveOutInfo is not valid.
- const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg) {
+ const LiveOutInfo *GetLiveOutRegInfo(Register Reg) {
if (!LiveOutRegInfo.inBounds(Reg))
return nullptr;
@@ -233,10 +210,10 @@ public:
/// the register's LiveOutInfo is for a smaller bit width, it is extended to
/// the larger bit width by zero extension. The bit width must be no smaller
/// than the LiveOutInfo's existing bit width.
- const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg, unsigned BitWidth);
+ const LiveOutInfo *GetLiveOutRegInfo(Register Reg, unsigned BitWidth);
/// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
- void AddLiveOutRegInfo(unsigned Reg, unsigned NumSignBits,
+ void AddLiveOutRegInfo(Register Reg, unsigned NumSignBits,
const KnownBits &Known) {
// Only install this information if it tells us something.
if (NumSignBits == 1 && Known.isUnknown())
@@ -257,11 +234,11 @@ public:
/// called when a block is visited before all of its predecessors.
void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
// PHIs with no uses have no ValueMap entry.
- DenseMap<const Value*, unsigned>::const_iterator It = ValueMap.find(PN);
+ DenseMap<const Value*, Register>::const_iterator It = ValueMap.find(PN);
if (It == ValueMap.end())
return;
- unsigned Reg = It->second;
+ Register Reg = It->second;
if (Reg == 0)
return;
@@ -276,12 +253,10 @@ public:
/// getArgumentFrameIndex - Get frame index for the byval argument.
int getArgumentFrameIndex(const Argument *A);
- unsigned getCatchPadExceptionPointerVReg(const Value *CPI,
+ Register getCatchPadExceptionPointerVReg(const Value *CPI,
const TargetRegisterClass *RC);
private:
- void addSEHHandlersForLPads(ArrayRef<const LandingPadInst *> LPads);
-
/// LiveOutRegInfo - Information about live out vregs.
IndexedMap<LiveOutInfo, VirtReg2IndexFunctor> LiveOutRegInfo;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
index e56177939f46..8bd9e9443552 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CSEInfo.h
@@ -120,6 +120,8 @@ public:
void setMF(MachineFunction &MF);
+ Error verify();
+
/// Records a newly created inst in a list and lazily insert it to the CSEMap.
/// Sometimes, this method might be called with a partially constructed
/// MachineInstr,
@@ -173,14 +175,14 @@ public:
: ID(ID), MRI(MRI) {}
// Profiling methods.
const GISelInstProfileBuilder &addNodeIDOpcode(unsigned Opc) const;
- const GISelInstProfileBuilder &addNodeIDRegType(const LLT &Ty) const;
- const GISelInstProfileBuilder &addNodeIDRegType(const unsigned) const;
+ const GISelInstProfileBuilder &addNodeIDRegType(const LLT Ty) const;
+ const GISelInstProfileBuilder &addNodeIDRegType(const Register) const;
const GISelInstProfileBuilder &
addNodeIDRegType(const TargetRegisterClass *RC) const;
const GISelInstProfileBuilder &addNodeIDRegType(const RegisterBank *RB) const;
- const GISelInstProfileBuilder &addNodeIDRegNum(unsigned Reg) const;
+ const GISelInstProfileBuilder &addNodeIDRegNum(Register Reg) const;
const GISelInstProfileBuilder &addNodeIDImmediate(int64_t Imm) const;
const GISelInstProfileBuilder &
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
index bc9774e09acf..4d60dffb91db 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CallLowering.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/CallingConvLower.h"
#include "llvm/CodeGen/TargetCallingConv.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachineValueType.h"
@@ -28,6 +27,7 @@
namespace llvm {
class CCState;
+class CallBase;
class DataLayout;
class Function;
class MachineIRBuilder;
@@ -61,7 +61,8 @@ public:
if (!Regs.empty() && Flags.empty())
this->Flags.push_back(ISD::ArgFlagsTy());
// FIXME: We should have just one way of saying "no register".
- assert((Ty->isVoidTy() == (Regs.empty() || Regs[0] == 0)) &&
+ assert(((Ty->isVoidTy() || Ty->isEmptyTy()) ==
+ (Regs.empty() || Regs[0] == 0)) &&
"only void types should have no register");
}
@@ -84,7 +85,7 @@ public:
/// Valid if the call has a swifterror inout parameter, and contains the
/// vreg that the swifterror should be copied into after the call.
- Register SwiftErrorVReg = 0;
+ Register SwiftErrorVReg;
MDNode *KnownCallees = nullptr;
@@ -141,6 +142,14 @@ public:
uint64_t Size, MachinePointerInfo &MPO,
CCValAssign &VA) = 0;
+ /// An overload which takes an ArgInfo if additional information about
+ /// the arg is needed.
+ virtual void assignValueToAddress(const ArgInfo &Arg, Register Addr,
+ uint64_t Size, MachinePointerInfo &MPO,
+ CCValAssign &VA) {
+ assignValueToAddress(Arg.Regs[0], Addr, Size, MPO, VA);
+ }
+
/// Handle custom values, which may be passed into one or more of \p VAs.
/// \return The number of \p VAs that have been assigned after the first
/// one, and which should therefore be skipped from further
@@ -152,7 +161,10 @@ public:
llvm_unreachable("Custom values not supported");
}
- Register extendRegister(Register ValReg, CCValAssign &VA);
+ /// Extend a register to the location type given in VA, capped at extending
+ /// to at most MaxSize bits. If MaxSizeBits is 0 then no maximum is set.
+ Register extendRegister(Register ValReg, CCValAssign &VA,
+ unsigned MaxSizeBits = 0);
virtual bool assignArg(unsigned ValNo, MVT ValVT, MVT LocVT,
CCValAssign::LocInfo LocInfo, const ArgInfo &Info,
@@ -278,6 +290,8 @@ public:
return false;
}
+ virtual bool fallBackToDAGISel(const Function &F) const { return false; }
+
/// This hook must be implemented to lower the incoming (formal)
/// arguments, described by \p VRegs, for GlobalISel. Each argument
/// must end up in the related virtual registers described by \p VRegs.
@@ -328,7 +342,7 @@ public:
/// range of an immediate jump.
///
/// \return true if the lowering succeeded, false otherwise.
- bool lowerCall(MachineIRBuilder &MIRBuilder, ImmutableCallSite CS,
+ bool lowerCall(MachineIRBuilder &MIRBuilder, const CallBase &Call,
ArrayRef<Register> ResRegs,
ArrayRef<ArrayRef<Register>> ArgRegs, Register SwiftErrorVReg,
std::function<unsigned()> GetCalleeReg) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index e5ee21941e23..c317b7ed4c54 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/Register.h"
+#include "llvm/Support/Alignment.h"
namespace llvm {
@@ -29,6 +30,7 @@ class MachineInstr;
class MachineOperand;
class GISelKnownBits;
class MachineDominatorTree;
+class LegalizerInfo;
struct PreferredTuple {
LLT Ty; // The result type of the extend.
@@ -55,11 +57,17 @@ protected:
GISelChangeObserver &Observer;
GISelKnownBits *KB;
MachineDominatorTree *MDT;
+ const LegalizerInfo *LI;
public:
CombinerHelper(GISelChangeObserver &Observer, MachineIRBuilder &B,
GISelKnownBits *KB = nullptr,
- MachineDominatorTree *MDT = nullptr);
+ MachineDominatorTree *MDT = nullptr,
+ const LegalizerInfo *LI = nullptr);
+
+ GISelKnownBits *getKnownBits() const {
+ return KB;
+ }
/// MachineRegisterInfo::replaceRegWith() and inform the observer of the changes
void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const;
@@ -77,7 +85,7 @@ public:
/// Returns true if \p DefMI precedes \p UseMI or they are the same
/// instruction. Both must be in the same basic block.
- bool isPredecessor(MachineInstr &DefMI, MachineInstr &UseMI);
+ bool isPredecessor(const MachineInstr &DefMI, const MachineInstr &UseMI);
/// Returns true if \p DefMI dominates \p UseMI. By definition an
/// instruction dominates itself.
@@ -85,7 +93,7 @@ public:
/// If we haven't been provided with a MachineDominatorTree during
/// construction, this function returns a conservative result that tracks just
/// a single basic block.
- bool dominates(MachineInstr &DefMI, MachineInstr &UseMI);
+ bool dominates(const MachineInstr &DefMI, const MachineInstr &UseMI);
/// If \p MI is extend that consumes the result of a load, try to combine it.
/// Returns true if MI changed.
@@ -99,6 +107,9 @@ public:
bool matchCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
void applyCombineIndexedLoadStore(MachineInstr &MI, IndexedLoadStoreMatchInfo &MatchInfo);
+ bool matchSextAlreadyExtended(MachineInstr &MI);
+ bool applySextAlreadyExtended(MachineInstr &MI);
+
bool matchElideBrByInvertingCond(MachineInstr &MI);
void applyElideBrByInvertingCond(MachineInstr &MI);
bool tryElideBrByInvertingCond(MachineInstr &MI);
@@ -178,6 +189,69 @@ public:
bool matchPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
bool applyPtrAddImmedChain(MachineInstr &MI, PtrAddChain &MatchInfo);
+ /// Transform a multiply by a power-of-2 value to a left shift.
+ bool matchCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
+ bool applyCombineMulToShl(MachineInstr &MI, unsigned &ShiftVal);
+
+ /// Reduce a shift by a constant to an unmerge and a shift on a half sized
+ /// type. This will not produce a shift smaller than \p TargetShiftSize.
+ bool matchCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftSize,
+ unsigned &ShiftVal);
+ bool applyCombineShiftToUnmerge(MachineInstr &MI, const unsigned &ShiftVal);
+ bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount);
+
+ /// Return true if any explicit use operand on \p MI is defined by a
+ /// G_IMPLICIT_DEF.
+ bool matchAnyExplicitUseIsUndef(MachineInstr &MI);
+
+ /// Return true if all register explicit use operands on \p MI are defined by
+ /// a G_IMPLICIT_DEF.
+ bool matchAllExplicitUsesAreUndef(MachineInstr &MI);
+
+ /// Return true if a G_SHUFFLE_VECTOR instruction \p MI has an undef mask.
+ bool matchUndefShuffleVectorMask(MachineInstr &MI);
+
+ /// Return true if a G_STORE instruction \p MI is storing an undef value.
+ bool matchUndefStore(MachineInstr &MI);
+
+ /// Replace an instruction with a G_FCONSTANT with value \p C.
+ bool replaceInstWithFConstant(MachineInstr &MI, double C);
+
+ /// Replace an instruction with a G_CONSTANT with value \p C.
+ bool replaceInstWithConstant(MachineInstr &MI, int64_t C);
+
+ /// Replace an instruction with a G_IMPLICIT_DEF.
+ bool replaceInstWithUndef(MachineInstr &MI);
+
+ /// Delete \p MI and replace all of its uses with its \p OpIdx-th operand.
+ bool replaceSingleDefInstWithOperand(MachineInstr &MI, unsigned OpIdx);
+
+ /// Return true if \p MOP1 and \p MOP2 are register operands are defined by
+ /// equivalent instructions.
+ bool matchEqualDefs(const MachineOperand &MOP1, const MachineOperand &MOP2);
+
+ /// Return true if \p MOP is defined by a G_CONSTANT with a value equal to
+ /// \p C.
+ bool matchConstantOp(const MachineOperand &MOP, int64_t C);
+
+ /// Optimize (cond ? x : x) -> x
+ bool matchSelectSameVal(MachineInstr &MI);
+
+ /// Optimize (x op x) -> x
+ bool matchBinOpSameVal(MachineInstr &MI);
+
+ /// Check if operand \p OpIdx is zero.
+ bool matchOperandIsZero(MachineInstr &MI, unsigned OpIdx);
+
+ /// Erase \p MI
+ bool eraseInst(MachineInstr &MI);
+
+ /// Return true if MI is a G_ADD which can be simplified to a G_SUB.
+ bool matchSimplifyAddToSub(MachineInstr &MI,
+ std::tuple<Register, Register> &MatchInfo);
+ bool applySimplifyAddToSub(MachineInstr &MI,
+ std::tuple<Register, Register> &MatchInfo);
+
/// Try to transform \p MI by using all of the above
/// combine functions. Returns true if changed.
bool tryCombine(MachineInstr &MI);
@@ -185,13 +259,13 @@ public:
private:
// Memcpy family optimization helpers.
bool optimizeMemcpy(MachineInstr &MI, Register Dst, Register Src,
- unsigned KnownLen, unsigned DstAlign, unsigned SrcAlign,
+ unsigned KnownLen, Align DstAlign, Align SrcAlign,
bool IsVolatile);
bool optimizeMemmove(MachineInstr &MI, Register Dst, Register Src,
- unsigned KnownLen, unsigned DstAlign, unsigned SrcAlign,
- bool IsVolatile);
+ unsigned KnownLen, Align DstAlign, Align SrcAlign,
+ bool IsVolatile);
bool optimizeMemset(MachineInstr &MI, Register Dst, Register Val,
- unsigned KnownLen, unsigned DstAlign, bool IsVolatile);
+ unsigned KnownLen, Align DstAlign, bool IsVolatile);
/// Given a non-indexed load or store instruction \p MI, find an offset that
/// can be usefully and legally folded into it as a post-indexing operation.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
index ad645a46bbe6..e95a5e21f832 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/CombinerInfo.h
@@ -27,7 +27,7 @@ class MachineRegisterInfo;
class CombinerInfo {
public:
CombinerInfo(bool AllowIllegalOps, bool ShouldLegalizeIllegal,
- LegalizerInfo *LInfo, bool OptEnabled, bool OptSize,
+ const LegalizerInfo *LInfo, bool OptEnabled, bool OptSize,
bool MinSize)
: IllegalOpsAllowed(AllowIllegalOps),
LegalizeIllegalOps(ShouldLegalizeIllegal), LInfo(LInfo),
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
index e5691cb35174..d8fe4b3103db 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelChangeObserver.h
@@ -101,7 +101,7 @@ public:
void MF_HandleRemoval(MachineInstr &MI) override { erasingInstr(MI); }
};
-/// A simple RAII based CSEInfo installer.
+/// A simple RAII based Delegate installer.
/// Use this in a scope to install a delegate to the MachineFunction and reset
/// it at the end of the scope.
class RAIIDelegateInstaller {
@@ -113,5 +113,27 @@ public:
~RAIIDelegateInstaller();
};
+/// A simple RAII based Observer installer.
+/// Use this in a scope to install the Observer to the MachineFunction and reset
+/// it at the end of the scope.
+class RAIIMFObserverInstaller {
+ MachineFunction &MF;
+
+public:
+ RAIIMFObserverInstaller(MachineFunction &MF, GISelChangeObserver &Observer);
+ ~RAIIMFObserverInstaller();
+};
+
+/// Class to install both of the above.
+class RAIIMFObsDelInstaller {
+ RAIIDelegateInstaller DelI;
+ RAIIMFObserverInstaller ObsI;
+
+public:
+ RAIIMFObsDelInstaller(MachineFunction &MF, GISelObserverWrapper &Wrapper)
+ : DelI(MF, &Wrapper), ObsI(MF, Wrapper) {}
+ ~RAIIMFObsDelInstaller() = default;
+};
+
} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
index d44612f54ae5..55cf54d6e946 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/GISelKnownBits.h
@@ -13,6 +13,7 @@
#ifndef LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
#define LLVM_CODEGEN_GLOBALISEL_KNOWNBITSINFO_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Register.h"
@@ -31,11 +32,23 @@ class GISelKnownBits : public GISelChangeObserver {
MachineRegisterInfo &MRI;
const TargetLowering &TL;
const DataLayout &DL;
+ unsigned MaxDepth;
+ /// Cache maintained during a computeKnownBits request.
+ SmallDenseMap<Register, KnownBits, 16> ComputeKnownBitsCache;
public:
- GISelKnownBits(MachineFunction &MF);
+ GISelKnownBits(MachineFunction &MF, unsigned MaxDepth = 6);
virtual ~GISelKnownBits() = default;
void setMF(MachineFunction &MF);
+
+ const MachineFunction &getMachineFunction() const {
+ return MF;
+ }
+
+ const DataLayout &getDataLayout() const {
+ return DL;
+ }
+
virtual void computeKnownBitsImpl(Register R, KnownBits &Known,
const APInt &DemandedElts,
unsigned Depth = 0);
@@ -46,6 +59,9 @@ public:
// KnownBitsAPI
KnownBits getKnownBits(Register R);
+ KnownBits getKnownBits(Register R, const APInt &DemandedElts,
+ unsigned Depth = 0);
+
// Calls getKnownBits for first operand def of MI.
KnownBits getKnownBits(MachineInstr &MI);
APInt getKnownZeroes(Register R);
@@ -62,18 +78,14 @@ public:
/// predicate to simplify operations downstream.
bool signBitIsZero(Register Op);
- // FIXME: Is this the right place for G_FRAME_INDEX? Should it be in
- // TargetLowering?
- void computeKnownBitsForFrameIndex(Register R, KnownBits &Known,
- const APInt &DemandedElts,
- unsigned Depth = 0);
- static Align inferAlignmentForFrameIdx(int FrameIdx, int Offset,
- const MachineFunction &MF);
static void computeKnownBitsForAlignment(KnownBits &Known,
- MaybeAlign Alignment);
+ Align Alignment) {
+ // The low bits are known zero if the pointer is aligned.
+ Known.Zero.setLowBits(Log2(Alignment));
+ }
- // Try to infer alignment for MI.
- static MaybeAlign inferPtrAlignment(const MachineInstr &MI);
+ /// \return The known alignment for the pointer-like value \p R.
+ Align computeKnownAlignment(Register R, unsigned Depth = 0);
// Observer API. No-op for non-caching implementation.
void erasingInstr(MachineInstr &MI) override{};
@@ -82,7 +94,7 @@ public:
void changedInstr(MachineInstr &MI) override{};
protected:
- unsigned getMaxDepth() const { return 6; }
+ unsigned getMaxDepth() const { return MaxDepth; }
};
/// To use KnownBitsInfo analysis in a pass,
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
index 6a2ea05f1b08..751ab67c4e97 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/IRTranslator.h
@@ -21,7 +21,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/GlobalISel/CSEMIRBuilder.h"
-#include "llvm/CodeGen/GlobalISel/Types.h"
#include "llvm/CodeGen/SwiftErrorValueTracking.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SwitchLoweringUtils.h"
@@ -202,6 +201,10 @@ private:
/// \return true if the materialization succeeded.
bool translate(const Constant &C, Register Reg);
+ // Translate U as a copy of V.
+ bool translateCopy(const User &U, const Value &V,
+ MachineIRBuilder &MIRBuilder);
+
/// Translate an LLVM bitcast into generic IR. Either a COPY or a G_BITCAST is
/// emitted.
bool translateBitCast(const User &U, MachineIRBuilder &MIRBuilder);
@@ -232,10 +235,13 @@ private:
bool translateSimpleIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder);
+ bool translateConstrainedFPIntrinsic(const ConstrainedFPIntrinsic &FPI,
+ MachineIRBuilder &MIRBuilder);
+
bool translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
MachineIRBuilder &MIRBuilder);
- bool translateInlineAsm(const CallInst &CI, MachineIRBuilder &MIRBuilder);
+ bool translateInlineAsm(const CallBase &CB, MachineIRBuilder &MIRBuilder);
/// Returns true if the value should be split into multiple LLTs.
/// If \p Offsets is given then the split type's offsets will be stored in it.
@@ -244,8 +250,7 @@ private:
SmallVectorImpl<uint64_t> *Offsets = nullptr);
/// Common code for translating normal calls or invokes.
- bool translateCallSite(const ImmutableCallSite &CS,
- MachineIRBuilder &MIRBuilder);
+ bool translateCallBase(const CallBase &CB, MachineIRBuilder &MIRBuilder);
/// Translate call instruction.
/// \pre \p U is a call instruction.
@@ -453,6 +458,7 @@ private:
bool translateAtomicCmpXchg(const User &U, MachineIRBuilder &MIRBuilder);
bool translateAtomicRMW(const User &U, MachineIRBuilder &MIRBuilder);
bool translateFence(const User &U, MachineIRBuilder &MIRBuilder);
+ bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder);
// Stubs to keep the compiler happy while we implement the rest of the
// translation.
@@ -483,9 +489,6 @@ private:
bool translateUserOp2(const User &U, MachineIRBuilder &MIRBuilder) {
return false;
}
- bool translateFreeze(const User &U, MachineIRBuilder &MIRBuilder) {
- return false;
- }
/// @}
@@ -582,7 +585,7 @@ private:
/// Get the alignment of the given memory operation instruction. This will
/// either be the explicitly specified value or the ABI-required alignment for
/// the type being accessed (according to the Module's DataLayout).
- unsigned getMemOpAlignment(const Instruction &I);
+ Align getMemOpAlign(const Instruction &I);
/// Get the MachineBasicBlock that represents \p BB. Specifically, the block
/// returned will be the head of the translated block (suitable for branch
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InlineAsmLowering.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InlineAsmLowering.h
new file mode 100644
index 000000000000..ac6184877b93
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InlineAsmLowering.h
@@ -0,0 +1,67 @@
+//===- llvm/CodeGen/GlobalISel/InlineAsmLowering.h --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file describes how to lower LLVM inline asm to machine code INLINEASM.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
+#define LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include <functional>
+
+namespace llvm {
+class CallBase;
+class MachineIRBuilder;
+class MachineOperand;
+class Register;
+class TargetLowering;
+class Value;
+
+class InlineAsmLowering {
+ const TargetLowering *TLI;
+
+ virtual void anchor();
+
+public:
+ /// Lower the given inline asm call instruction
+ /// \p GetOrCreateVRegs is a callback to materialize a register for the
+ /// input and output operands of the inline asm
+ /// \return True if the lowering succeeds, false otherwise.
+ bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB,
+ std::function<ArrayRef<Register>(const Value &Val)>
+ GetOrCreateVRegs) const;
+
+ /// Lower the specified operand into the Ops vector.
+ /// \p Val is the IR input value to be lowered
+ /// \p Constraint is the user supplied constraint string
+ /// \p Ops is the vector to be filled with the lowered operands
+ /// \return True if the lowering succeeds, false otherwise.
+ virtual bool lowerAsmOperandForConstraint(Value *Val, StringRef Constraint,
+ std::vector<MachineOperand> &Ops,
+ MachineIRBuilder &MIRBuilder) const;
+
+protected:
+ /// Getter for generic TargetLowering class.
+ const TargetLowering *getTLI() const { return TLI; }
+
+ /// Getter for target specific TargetLowering class.
+ template <class XXXTargetLowering> const XXXTargetLowering *getTLI() const {
+ return static_cast<const XXXTargetLowering *>(TLI);
+ }
+
+public:
+ InlineAsmLowering(const TargetLowering *TLI) : TLI(TLI) {}
+ virtual ~InlineAsmLowering() = default;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_GLOBALISEL_INLINEASMLOWERING_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 59d2540dd14e..1af96cb4a9ee 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -293,6 +293,13 @@ enum {
/// - TempRegFlags - The register flags to set
GIR_AddTempRegister,
+ /// Add a temporary register to the specified instruction
+ /// - InsnID - Instruction ID to modify
+ /// - TempRegID - The temporary register ID to add
+ /// - TempRegFlags - The register flags to set
+ /// - SubRegIndex - The subregister index to set
+ GIR_AddTempSubRegister,
+
/// Add an immediate to the specified instruction
/// - InsnID - Instruction ID to modify
/// - Imm - The immediate to add
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index f866f42344f6..73ac578d61be 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -58,6 +58,11 @@ bool InstructionSelector::executeMatchTable(
uint64_t CurrentIdx = 0;
SmallVector<uint64_t, 4> OnFailResumeAt;
+ // Bypass the flag check on the instruction, and only look at the MCInstrDesc.
+ bool NoFPException = !State.MIs[0]->getDesc().mayRaiseFPException();
+
+ const uint16_t Flags = State.MIs[0]->getFlags();
+
enum RejectAction { RejectAndGiveUp, RejectAndResume };
auto handleReject = [&]() -> RejectAction {
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
@@ -71,6 +76,19 @@ bool InstructionSelector::executeMatchTable(
return RejectAndResume;
};
+ auto propagateFlags = [=](NewMIVector &OutMIs) {
+ for (auto MIB : OutMIs) {
+ // Set the NoFPExcept flag when no original matched instruction could
+ // raise an FP exception, but the new instruction potentially might.
+ uint16_t MIBFlags = Flags;
+ if (NoFPException && MIB->mayRaiseFPException())
+ MIBFlags |= MachineInstr::NoFPExcept;
+ MIB.setMIFlags(MIBFlags);
+ }
+
+ return true;
+ };
+
while (true) {
assert(CurrentIdx != ~0u && "Invalid MatchTable index");
int64_t MatcherOpcode = MatchTable[CurrentIdx++];
@@ -429,7 +447,7 @@ bool InstructionSelector::executeMatchTable(
dbgs() << CurrentIdx << ": GIM_CheckMemoryAlignment"
<< "(MIs[" << InsnID << "]->memoperands() + " << MMOIdx
<< ")->getAlignment() >= " << MinAlign << ")\n");
- if (MMO->getAlignment() < MinAlign && handleReject() == RejectAndGiveUp)
+ if (MMO->getAlign() < MinAlign && handleReject() == RejectAndGiveUp)
return false;
break;
@@ -859,16 +877,25 @@ bool InstructionSelector::executeMatchTable(
break;
}
- case GIR_AddTempRegister: {
+ case GIR_AddTempRegister:
+ case GIR_AddTempSubRegister: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t TempRegID = MatchTable[CurrentIdx++];
uint64_t TempRegFlags = MatchTable[CurrentIdx++];
+ unsigned SubReg = 0;
+ if (MatcherOpcode == GIR_AddTempSubRegister)
+ SubReg = MatchTable[CurrentIdx++];
+
assert(OutMIs[InsnID] && "Attempted to add to undefined instruction");
- OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags);
+
+ OutMIs[InsnID].addReg(State.TempRegisters[TempRegID], TempRegFlags, SubReg);
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
dbgs() << CurrentIdx << ": GIR_AddTempRegister(OutMIs["
<< InsnID << "], TempRegisters[" << TempRegID
- << "], " << TempRegFlags << ")\n");
+ << "]";
+ if (SubReg)
+ dbgs() << '.' << TRI.getSubRegIndexName(SubReg);
+ dbgs() << ", " << TempRegFlags << ")\n");
break;
}
@@ -1056,6 +1083,7 @@ bool InstructionSelector::executeMatchTable(
case GIR_Done:
DEBUG_WITH_TYPE(TgtInstructionSelector::getName(),
dbgs() << CurrentIdx << ": GIR_Done\n");
+ propagateFlags(OutMIs);
return true;
default:
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
index dd32a3b9e38e..016b0bacab85 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h
@@ -50,7 +50,7 @@ public:
SmallVectorImpl<Register> &UpdatedDefs) {
assert(MI.getOpcode() == TargetOpcode::G_ANYEXT);
- Builder.setInstr(MI);
+ Builder.setInstrAndDebugLoc(MI);
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
@@ -81,7 +81,7 @@ public:
// Can't use MIPattern because we don't have a specific constant in mind.
auto *SrcMI = MRI.getVRegDef(SrcReg);
if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
- const LLT &DstTy = MRI.getType(DstReg);
+ const LLT DstTy = MRI.getType(DstReg);
if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
auto &CstVal = SrcMI->getOperand(1);
Builder.buildConstant(
@@ -96,10 +96,11 @@ public:
bool tryCombineZExt(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts,
- SmallVectorImpl<Register> &UpdatedDefs) {
+ SmallVectorImpl<Register> &UpdatedDefs,
+ GISelObserverWrapper &Observer) {
assert(MI.getOpcode() == TargetOpcode::G_ZEXT);
- Builder.setInstr(MI);
+ Builder.setInstrAndDebugLoc(MI);
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
@@ -121,11 +122,23 @@ public:
return true;
}
+ // zext(zext x) -> (zext x)
+ Register ZextSrc;
+ if (mi_match(SrcReg, MRI, m_GZExt(m_Reg(ZextSrc)))) {
+ LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
+ Observer.changingInstr(MI);
+ MI.getOperand(1).setReg(ZextSrc);
+ Observer.changedInstr(MI);
+ UpdatedDefs.push_back(DstReg);
+ markDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
+ return true;
+ }
+
// Try to fold zext(g_constant) when the larger constant type is legal.
// Can't use MIPattern because we don't have a specific constant in mind.
auto *SrcMI = MRI.getVRegDef(SrcReg);
if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
- const LLT &DstTy = MRI.getType(DstReg);
+ const LLT DstTy = MRI.getType(DstReg);
if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
auto &CstVal = SrcMI->getOperand(1);
Builder.buildConstant(
@@ -143,7 +156,7 @@ public:
SmallVectorImpl<Register> &UpdatedDefs) {
assert(MI.getOpcode() == TargetOpcode::G_SEXT);
- Builder.setInstr(MI);
+ Builder.setInstrAndDebugLoc(MI);
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = lookThroughCopyInstrs(MI.getOperand(1).getReg());
@@ -162,12 +175,28 @@ public:
markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
return true;
}
+
+ // sext(zext x) -> (zext x)
+ // sext(sext x) -> (sext x)
+ Register ExtSrc;
+ MachineInstr *ExtMI;
+ if (mi_match(SrcReg, MRI,
+ m_all_of(m_MInstr(ExtMI), m_any_of(m_GZExt(m_Reg(ExtSrc)),
+ m_GSExt(m_Reg(ExtSrc)))))) {
+ LLVM_DEBUG(dbgs() << ".. Combine MI: " << MI);
+ Builder.buildInstr(ExtMI->getOpcode(), {DstReg}, {ExtSrc});
+ UpdatedDefs.push_back(DstReg);
+ markInstAndDefDead(MI, *MRI.getVRegDef(SrcReg), DeadInsts);
+ return true;
+ }
+
return tryFoldImplicitDef(MI, DeadInsts, UpdatedDefs);
}
bool tryCombineTrunc(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts,
- SmallVectorImpl<Register> &UpdatedDefs) {
+ SmallVectorImpl<Register> &UpdatedDefs,
+ GISelObserverWrapper &Observer) {
assert(MI.getOpcode() == TargetOpcode::G_TRUNC);
Builder.setInstr(MI);
@@ -178,7 +207,7 @@ public:
// Can't use MIPattern because we don't have a specific constant in mind.
auto *SrcMI = MRI.getVRegDef(SrcReg);
if (SrcMI->getOpcode() == TargetOpcode::G_CONSTANT) {
- const LLT &DstTy = MRI.getType(DstReg);
+ const LLT DstTy = MRI.getType(DstReg);
if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
auto &CstVal = SrcMI->getOperand(1);
Builder.buildConstant(
@@ -189,6 +218,80 @@ public:
}
}
+ // Try to fold trunc(merge) to directly use the source of the merge.
+ // This gets rid of large, difficult to legalize, merges
+ if (SrcMI->getOpcode() == TargetOpcode::G_MERGE_VALUES) {
+ const Register MergeSrcReg = SrcMI->getOperand(1).getReg();
+ const LLT MergeSrcTy = MRI.getType(MergeSrcReg);
+ const LLT DstTy = MRI.getType(DstReg);
+
+ // We can only fold if the types are scalar
+ const unsigned DstSize = DstTy.getSizeInBits();
+ const unsigned MergeSrcSize = MergeSrcTy.getSizeInBits();
+ if (!DstTy.isScalar() || !MergeSrcTy.isScalar())
+ return false;
+
+ if (DstSize < MergeSrcSize) {
+ // When the merge source is larger than the destination, we can just
+ // truncate the merge source directly
+ if (isInstUnsupported({TargetOpcode::G_TRUNC, {DstTy, MergeSrcTy}}))
+ return false;
+
+ LLVM_DEBUG(dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_TRUNC: "
+ << MI);
+
+ Builder.buildTrunc(DstReg, MergeSrcReg);
+ UpdatedDefs.push_back(DstReg);
+ } else if (DstSize == MergeSrcSize) {
+ // If the sizes match we can simply try to replace the register
+ LLVM_DEBUG(
+ dbgs() << "Replacing G_TRUNC(G_MERGE_VALUES) with merge input: "
+ << MI);
+ replaceRegOrBuildCopy(DstReg, MergeSrcReg, MRI, Builder, UpdatedDefs,
+ Observer);
+ } else if (DstSize % MergeSrcSize == 0) {
+ // If the trunc size is a multiple of the merge source size we can use
+ // a smaller merge instead
+ if (isInstUnsupported(
+ {TargetOpcode::G_MERGE_VALUES, {DstTy, MergeSrcTy}}))
+ return false;
+
+ LLVM_DEBUG(
+ dbgs() << "Combining G_TRUNC(G_MERGE_VALUES) to G_MERGE_VALUES: "
+ << MI);
+
+ const unsigned NumSrcs = DstSize / MergeSrcSize;
+ assert(NumSrcs < SrcMI->getNumOperands() - 1 &&
+ "trunc(merge) should require less inputs than merge");
+ SmallVector<Register, 8> SrcRegs(NumSrcs);
+ for (unsigned i = 0; i < NumSrcs; ++i)
+ SrcRegs[i] = SrcMI->getOperand(i + 1).getReg();
+
+ Builder.buildMerge(DstReg, SrcRegs);
+ UpdatedDefs.push_back(DstReg);
+ } else {
+ // Unable to combine
+ return false;
+ }
+
+ markInstAndDefDead(MI, *SrcMI, DeadInsts);
+ return true;
+ }
+
+ // trunc(trunc) -> trunc
+ Register TruncSrc;
+ if (mi_match(SrcReg, MRI, m_GTrunc(m_Reg(TruncSrc)))) {
+ // Always combine trunc(trunc) since the eventual resulting trunc must be
+ // legal anyway as it must be legal for all outputs of the consumer type
+ // set.
+ LLVM_DEBUG(dbgs() << ".. Combine G_TRUNC(G_TRUNC): " << MI);
+
+ Builder.buildTrunc(DstReg, TruncSrc);
+ UpdatedDefs.push_back(DstReg);
+ markInstAndDefDead(MI, *MRI.getVRegDef(TruncSrc), DeadInsts);
+ return true;
+ }
+
return false;
}
@@ -208,7 +311,7 @@ public:
if (Opcode == TargetOpcode::G_ANYEXT) {
// G_ANYEXT (G_IMPLICIT_DEF) -> G_IMPLICIT_DEF
- if (isInstUnsupported({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
+ if (!isInstLegal({TargetOpcode::G_IMPLICIT_DEF, {DstTy}}))
return false;
LLVM_DEBUG(dbgs() << ".. Combine G_ANYEXT(G_IMPLICIT_DEF): " << MI;);
Builder.buildInstr(TargetOpcode::G_IMPLICIT_DEF, {DstReg}, {});
@@ -229,6 +332,99 @@ public:
return false;
}
+ bool tryFoldUnmergeCast(MachineInstr &MI, MachineInstr &CastMI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts,
+ SmallVectorImpl<Register> &UpdatedDefs) {
+
+ assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
+
+ const unsigned CastOpc = CastMI.getOpcode();
+
+ if (!isArtifactCast(CastOpc))
+ return false;
+
+ const unsigned NumDefs = MI.getNumOperands() - 1;
+
+ const Register CastSrcReg = CastMI.getOperand(1).getReg();
+ const LLT CastSrcTy = MRI.getType(CastSrcReg);
+ const LLT DestTy = MRI.getType(MI.getOperand(0).getReg());
+ const LLT SrcTy = MRI.getType(MI.getOperand(NumDefs).getReg());
+
+ const unsigned CastSrcSize = CastSrcTy.getSizeInBits();
+ const unsigned DestSize = DestTy.getSizeInBits();
+
+ if (CastOpc == TargetOpcode::G_TRUNC) {
+ if (SrcTy.isVector() && SrcTy.getScalarType() == DestTy.getScalarType()) {
+ // %1:_(<4 x s8>) = G_TRUNC %0(<4 x s32>)
+ // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %1
+ // =>
+ // %6:_(s32), %7:_(s32), %8:_(s32), %9:_(s32) = G_UNMERGE_VALUES %0
+ // %2:_(s8) = G_TRUNC %6
+ // %3:_(s8) = G_TRUNC %7
+ // %4:_(s8) = G_TRUNC %8
+ // %5:_(s8) = G_TRUNC %9
+
+ unsigned UnmergeNumElts =
+ DestTy.isVector() ? CastSrcTy.getNumElements() / NumDefs : 1;
+ LLT UnmergeTy = CastSrcTy.changeNumElements(UnmergeNumElts);
+
+ if (isInstUnsupported(
+ {TargetOpcode::G_UNMERGE_VALUES, {UnmergeTy, CastSrcTy}}))
+ return false;
+
+ Builder.setInstr(MI);
+ auto NewUnmerge = Builder.buildUnmerge(UnmergeTy, CastSrcReg);
+
+ for (unsigned I = 0; I != NumDefs; ++I) {
+ Register DefReg = MI.getOperand(I).getReg();
+ UpdatedDefs.push_back(DefReg);
+ Builder.buildTrunc(DefReg, NewUnmerge.getReg(I));
+ }
+
+ markInstAndDefDead(MI, CastMI, DeadInsts);
+ return true;
+ }
+
+ if (CastSrcTy.isScalar() && SrcTy.isScalar() && !DestTy.isVector()) {
+ // %1:_(s16) = G_TRUNC %0(s32)
+ // %2:_(s8), %3:_(s8) = G_UNMERGE_VALUES %1
+ // =>
+ // %2:_(s8), %3:_(s8), %4:_(s8), %5:_(s8) = G_UNMERGE_VALUES %0
+
+ // Unmerge(trunc) can be combined if the trunc source size is a multiple
+ // of the unmerge destination size
+ if (CastSrcSize % DestSize != 0)
+ return false;
+
+ // Check if the new unmerge is supported
+ if (isInstUnsupported(
+ {TargetOpcode::G_UNMERGE_VALUES, {DestTy, CastSrcTy}}))
+ return false;
+
+ // Gather the original destination registers and create new ones for the
+ // unused bits
+ const unsigned NewNumDefs = CastSrcSize / DestSize;
+ SmallVector<Register, 8> DstRegs(NewNumDefs);
+ for (unsigned Idx = 0; Idx < NewNumDefs; ++Idx) {
+ if (Idx < NumDefs)
+ DstRegs[Idx] = MI.getOperand(Idx).getReg();
+ else
+ DstRegs[Idx] = MRI.createGenericVirtualRegister(DestTy);
+ }
+
+ // Build new unmerge
+ Builder.setInstr(MI);
+ Builder.buildUnmerge(DstRegs, CastSrcReg);
+ UpdatedDefs.append(DstRegs.begin(), DstRegs.begin() + NewNumDefs);
+ markInstAndDefDead(MI, CastMI, DeadInsts);
+ return true;
+ }
+ }
+
+ // TODO: support combines with other casts as well
+ return false;
+ }
+
static bool canFoldMergeOpcode(unsigned MergeOp, unsigned ConvertOp,
LLT OpTy, LLT DestTy) {
// Check if we found a definition that is like G_MERGE_VALUES.
@@ -261,7 +457,7 @@ public:
// That is not done yet.
if (ConvertOp == 0)
return true;
- return !DestTy.isVector();
+ return !DestTy.isVector() && OpTy.isVector();
case TargetOpcode::G_CONCAT_VECTORS: {
if (ConvertOp == 0)
return true;
@@ -280,9 +476,36 @@ public:
}
}
+ /// Try to replace DstReg with SrcReg or build a COPY instruction
+ /// depending on the register constraints.
+ static void replaceRegOrBuildCopy(Register DstReg, Register SrcReg,
+ MachineRegisterInfo &MRI,
+ MachineIRBuilder &Builder,
+ SmallVectorImpl<Register> &UpdatedDefs,
+ GISelObserverWrapper &Observer) {
+ if (!llvm::canReplaceReg(DstReg, SrcReg, MRI)) {
+ Builder.buildCopy(DstReg, SrcReg);
+ UpdatedDefs.push_back(DstReg);
+ return;
+ }
+ SmallVector<MachineInstr *, 4> UseMIs;
+ // Get the users and notify the observer before replacing.
+ for (auto &UseMI : MRI.use_instructions(DstReg)) {
+ UseMIs.push_back(&UseMI);
+ Observer.changingInstr(UseMI);
+ }
+ // Replace the registers.
+ MRI.replaceRegWith(DstReg, SrcReg);
+ UpdatedDefs.push_back(SrcReg);
+ // Notify the observer that we changed the instructions.
+ for (auto *UseMI : UseMIs)
+ Observer.changedInstr(*UseMI);
+ }
+
bool tryCombineMerges(MachineInstr &MI,
SmallVectorImpl<MachineInstr *> &DeadInsts,
- SmallVectorImpl<Register> &UpdatedDefs) {
+ SmallVectorImpl<Register> &UpdatedDefs,
+ GISelObserverWrapper &Observer) {
assert(MI.getOpcode() == TargetOpcode::G_UNMERGE_VALUES);
unsigned NumDefs = MI.getNumOperands() - 1;
@@ -304,8 +527,11 @@ public:
}
if (!MergeI || !canFoldMergeOpcode(MergeI->getOpcode(),
- ConvertOp, OpTy, DestTy))
- return false;
+ ConvertOp, OpTy, DestTy)) {
+ // We might have a chance to combine later by trying to combine
+ // unmerge(cast) first
+ return tryFoldUnmergeCast(MI, *SrcDef, DeadInsts, UpdatedDefs);
+ }
const unsigned NumMergeRegs = MergeI->getNumOperands() - 1;
@@ -323,24 +549,41 @@ public:
const unsigned NewNumDefs = NumDefs / NumMergeRegs;
for (unsigned Idx = 0; Idx < NumMergeRegs; ++Idx) {
- SmallVector<Register, 2> DstRegs;
+ SmallVector<Register, 8> DstRegs;
for (unsigned j = 0, DefIdx = Idx * NewNumDefs; j < NewNumDefs;
++j, ++DefIdx)
DstRegs.push_back(MI.getOperand(DefIdx).getReg());
if (ConvertOp) {
- SmallVector<Register, 2> TmpRegs;
- // This is a vector that is being scalarized and casted. Extract to
- // the element type, and do the conversion on the scalars.
- LLT MergeEltTy =
- MRI.getType(MergeI->getOperand(0).getReg()).getElementType();
- for (unsigned j = 0; j < NumMergeRegs; ++j)
- TmpRegs.push_back(MRI.createGenericVirtualRegister(MergeEltTy));
+ LLT MergeSrcTy = MRI.getType(MergeI->getOperand(1).getReg());
+
+ // This is a vector that is being split and casted. Extract to the
+ // element type, and do the conversion on the scalars (or smaller
+ // vectors).
+ LLT MergeEltTy = MergeSrcTy.divide(NewNumDefs);
+
+ // Handle split to smaller vectors, with conversions.
+ // %2(<8 x s8>) = G_CONCAT_VECTORS %0(<4 x s8>), %1(<4 x s8>)
+ // %3(<8 x s16>) = G_SEXT %2
+ // %4(<2 x s16>), %5(<2 x s16>), %6(<2 x s16>), %7(<2 x s16>) = G_UNMERGE_VALUES %3
+ //
+ // =>
+ //
+ // %8(<2 x s8>), %9(<2 x s8>) = G_UNMERGE_VALUES %0
+ // %10(<2 x s8>), %11(<2 x s8>) = G_UNMERGE_VALUES %1
+ // %4(<2 x s16>) = G_SEXT %8
+ // %5(<2 x s16>) = G_SEXT %9
+ // %6(<2 x s16>) = G_SEXT %10
+ // %7(<2 x s16>)= G_SEXT %11
+
+ SmallVector<Register, 4> TmpRegs(NewNumDefs);
+ for (unsigned k = 0; k < NewNumDefs; ++k)
+ TmpRegs[k] = MRI.createGenericVirtualRegister(MergeEltTy);
Builder.buildUnmerge(TmpRegs, MergeI->getOperand(Idx + 1).getReg());
- for (unsigned j = 0; j < NumMergeRegs; ++j)
- Builder.buildInstr(ConvertOp, {DstRegs[j]}, {TmpRegs[j]});
+ for (unsigned k = 0; k < NewNumDefs; ++k)
+ Builder.buildInstr(ConvertOp, {DstRegs[k]}, {TmpRegs[k]});
} else {
Builder.buildUnmerge(DstRegs, MergeI->getOperand(Idx + 1).getReg());
}
@@ -361,7 +604,7 @@ public:
const unsigned NumRegs = NumMergeRegs / NumDefs;
for (unsigned DefIdx = 0; DefIdx < NumDefs; ++DefIdx) {
- SmallVector<Register, 2> Regs;
+ SmallVector<Register, 8> Regs;
for (unsigned j = 0, Idx = NumRegs * DefIdx + 1; j < NumRegs;
++j, ++Idx)
Regs.push_back(MergeI->getOperand(Idx).getReg());
@@ -395,10 +638,12 @@ public:
"Bitcast and the other kinds of conversions should "
"have happened earlier");
+ Builder.setInstr(MI);
for (unsigned Idx = 0; Idx < NumDefs; ++Idx) {
- Register NewDef = MergeI->getOperand(Idx + 1).getReg();
- MRI.replaceRegWith(MI.getOperand(Idx).getReg(), NewDef);
- UpdatedDefs.push_back(NewDef);
+ Register DstReg = MI.getOperand(Idx).getReg();
+ Register SrcReg = MergeI->getOperand(Idx + 1).getReg();
+ replaceRegOrBuildCopy(DstReg, SrcReg, MRI, Builder, UpdatedDefs,
+ Observer);
}
}
@@ -492,19 +737,30 @@ public:
Changed = tryCombineAnyExt(MI, DeadInsts, UpdatedDefs);
break;
case TargetOpcode::G_ZEXT:
- Changed = tryCombineZExt(MI, DeadInsts, UpdatedDefs);
+ Changed = tryCombineZExt(MI, DeadInsts, UpdatedDefs, WrapperObserver);
break;
case TargetOpcode::G_SEXT:
Changed = tryCombineSExt(MI, DeadInsts, UpdatedDefs);
break;
case TargetOpcode::G_UNMERGE_VALUES:
- Changed = tryCombineMerges(MI, DeadInsts, UpdatedDefs);
+ Changed = tryCombineMerges(MI, DeadInsts, UpdatedDefs, WrapperObserver);
+ break;
+ case TargetOpcode::G_MERGE_VALUES:
+ // If any of the users of this merge are an unmerge, then add them to the
+ // artifact worklist in case there's folding that can be done looking up.
+ for (MachineInstr &U : MRI.use_instructions(MI.getOperand(0).getReg())) {
+ if (U.getOpcode() == TargetOpcode::G_UNMERGE_VALUES ||
+ U.getOpcode() == TargetOpcode::G_TRUNC) {
+ UpdatedDefs.push_back(MI.getOperand(0).getReg());
+ break;
+ }
+ }
break;
case TargetOpcode::G_EXTRACT:
Changed = tryCombineExtract(MI, DeadInsts, UpdatedDefs);
break;
case TargetOpcode::G_TRUNC:
- Changed = tryCombineTrunc(MI, DeadInsts, UpdatedDefs);
+ Changed = tryCombineTrunc(MI, DeadInsts, UpdatedDefs, WrapperObserver);
if (!Changed) {
// Try to combine truncates away even if they are legal. As all artifact
// combines at the moment look only "up" the def-use chains, we achieve
@@ -551,31 +807,29 @@ public:
}
private:
- static unsigned getArtifactSrcReg(const MachineInstr &MI) {
+ static Register getArtifactSrcReg(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case TargetOpcode::COPY:
case TargetOpcode::G_TRUNC:
case TargetOpcode::G_ZEXT:
case TargetOpcode::G_ANYEXT:
case TargetOpcode::G_SEXT:
- case TargetOpcode::G_UNMERGE_VALUES:
- return MI.getOperand(MI.getNumOperands() - 1).getReg();
case TargetOpcode::G_EXTRACT:
return MI.getOperand(1).getReg();
+ case TargetOpcode::G_UNMERGE_VALUES:
+ return MI.getOperand(MI.getNumOperands() - 1).getReg();
default:
llvm_unreachable("Not a legalization artifact happen");
}
}
- /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
- /// dead due to MI being killed, then mark DefMI as dead too.
- /// Some of the combines (extends(trunc)), try to walk through redundant
- /// copies in between the extends and the truncs, and this attempts to collect
- /// the in between copies if they're dead.
- void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
- SmallVectorImpl<MachineInstr *> &DeadInsts) {
- DeadInsts.push_back(&MI);
-
+ /// Mark a def of one of MI's original operands, DefMI, as dead if changing MI
+ /// (either by killing it or changing operands) results in DefMI being dead
+ /// too. In-between COPYs or artifact-casts are also collected if they are
+ /// dead.
+ /// MI is not marked dead.
+ void markDefDead(MachineInstr &MI, MachineInstr &DefMI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts) {
// Collect all the copy instructions that are made dead, due to deleting
// this instruction. Collect all of them until the Trunc(DefMI).
// Eg,
@@ -587,7 +841,7 @@ private:
// and as a result, %3, %2, %1 are dead.
MachineInstr *PrevMI = &MI;
while (PrevMI != &DefMI) {
- unsigned PrevRegSrc = getArtifactSrcReg(*PrevMI);
+ Register PrevRegSrc = getArtifactSrcReg(*PrevMI);
MachineInstr *TmpDef = MRI.getVRegDef(PrevRegSrc);
if (MRI.hasOneUse(PrevRegSrc)) {
@@ -606,6 +860,17 @@ private:
DeadInsts.push_back(&DefMI);
}
+ /// Mark MI as dead. If a def of one of MI's operands, DefMI, would also be
+ /// dead due to MI being killed, then mark DefMI as dead too.
+ /// Some of the combines (extends(trunc)), try to walk through redundant
+ /// copies in between the extends and the truncs, and this attempts to collect
+ /// the in between copies if they're dead.
+ void markInstAndDefDead(MachineInstr &MI, MachineInstr &DefMI,
+ SmallVectorImpl<MachineInstr *> &DeadInsts) {
+ DeadInsts.push_back(&MI);
+ markDefDead(MI, DefMI, DeadInsts);
+ }
+
/// Erase the dead instructions in the list and call the observer hooks.
/// Normally the Legalizer will deal with erasing instructions that have been
/// marked dead. However, for the trunc(ext(x)) cases we can end up trying to
@@ -645,7 +910,7 @@ private:
/// Looks through copy instructions and returns the actual
/// source register.
- unsigned lookThroughCopyInstrs(Register Reg) {
+ Register lookThroughCopyInstrs(Register Reg) {
Register TmpReg;
while (mi_match(Reg, MRI, m_Copy(m_Reg(TmpReg)))) {
if (MRI.getType(TmpReg).isValid())
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
index 07173b9719bd..e59bf1b91262 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Legalizer.h
@@ -26,6 +26,7 @@
namespace llvm {
class MachineRegisterInfo;
+class LostDebugLocObserver;
class Legalizer : public MachineFunctionPass {
public:
@@ -71,6 +72,7 @@ public:
static MFResult
legalizeMachineFunction(MachineFunction &MF, const LegalizerInfo &LI,
ArrayRef<GISelChangeObserver *> AuxObservers,
+ LostDebugLocObserver &LocObserver,
MachineIRBuilder &MIRBuilder);
};
} // End namespace llvm.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
index ac7e5cbbdaa9..058aacf38634 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerHelper.h
@@ -35,6 +35,18 @@ class GISelChangeObserver;
class LegalizerHelper {
public:
+ /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
+ /// functions
+ MachineIRBuilder &MIRBuilder;
+
+ /// To keep track of changes made by the LegalizerHelper.
+ GISelChangeObserver &Observer;
+
+private:
+ MachineRegisterInfo &MRI;
+ const LegalizerInfo &LI;
+
+public:
enum LegalizeResult {
/// Instruction was already legal and no change was made to the
/// MachineFunction.
@@ -48,6 +60,9 @@ public:
UnableToLegalize,
};
+ /// Expose LegalizerInfo so the clients can re-use.
+ const LegalizerInfo &getLegalizerInfo() const { return LI; }
+
LegalizerHelper(MachineFunction &MF, GISelChangeObserver &Observer,
MachineIRBuilder &B);
LegalizerHelper(MachineFunction &MF, const LegalizerInfo &LI,
@@ -74,6 +89,9 @@ public:
/// precision, ignoring the unused bits).
LegalizeResult widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ /// Legalize an instruction by replacing the value type
+ LegalizeResult bitcast(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
/// Legalize an instruction by splitting it into simpler parts, hopefully
/// understood by the target.
LegalizeResult lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
@@ -88,14 +106,13 @@ public:
LegalizeResult moreElementsVector(MachineInstr &MI, unsigned TypeIdx,
LLT MoreTy);
- /// Expose MIRBuilder so clients can set their own RecordInsertInstruction
- /// functions
- MachineIRBuilder &MIRBuilder;
-
- /// Expose LegalizerInfo so the clients can re-use.
- const LegalizerInfo &getLegalizerInfo() const { return LI; }
+ /// Cast the given value to an LLT::scalar with an equivalent size. Returns
+ /// the register to use if an instruction was inserted. Returns the original
+ /// register if no coercion was necessary.
+ //
+ // This may also fail and return Register() if there is no legal way to cast.
+ Register coerceToScalar(Register Val);
-private:
/// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
/// Use by extending the operand's type to \p WideTy using the specified \p
/// ExtOpcode for the extension instruction, and replacing the vreg of the
@@ -129,6 +146,15 @@ private:
/// original vector type, and replacing the vreg of the operand in place.
void moreElementsVectorSrc(MachineInstr &MI, LLT MoreTy, unsigned OpIdx);
+ /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ /// use by inserting a G_BITCAST to \p CastTy
+ void bitcastSrc(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
+
+ /// Legalize a single operand \p OpIdx of the machine instruction \p MI as a
+ /// def by inserting a G_BITCAST from \p CastTy
+ void bitcastDst(MachineInstr &MI, LLT CastTy, unsigned OpIdx);
+
+private:
LegalizeResult
widenScalarMergeValues(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
LegalizeResult
@@ -137,6 +163,8 @@ private:
widenScalarExtract(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
LegalizeResult
widenScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT WideTy);
+ LegalizeResult widenScalarAddSubSat(MachineInstr &MI, unsigned TypeIdx,
+ LLT WideTy);
/// Helper function to split a wide generic register into bitwise blocks with
/// the given Type (which implies the number of blocks needed). The generic
@@ -163,6 +191,36 @@ private:
LLT PartTy, ArrayRef<Register> PartRegs,
LLT LeftoverTy = LLT(), ArrayRef<Register> LeftoverRegs = {});
+ /// Unmerge \p SrcReg into \p Parts with the greatest common divisor type with
+ /// \p DstTy and \p NarrowTy. Returns the GCD type.
+ LLT extractGCDType(SmallVectorImpl<Register> &Parts, LLT DstTy,
+ LLT NarrowTy, Register SrcReg);
+
+ /// Produce a merge of values in \p VRegs to define \p DstReg. Perform a merge
+ /// from the least common multiple type, and convert as appropriate to \p
+ /// DstReg.
+ ///
+ /// \p VRegs should each have type \p GCDTy. This type should be greatest
+ /// common divisor type of \p DstReg, \p NarrowTy, and an undetermined source
+ /// type.
+ ///
+ /// \p NarrowTy is the desired result merge source type. If the source value
+ /// needs to be widened to evenly cover \p DstReg, inserts high bits
+ /// corresponding to the extension opcode \p PadStrategy.
+ ///
+ /// \p VRegs will be cleared, and the the result \p NarrowTy register pieces
+ /// will replace it. Returns The complete LCMTy that \p VRegs will cover when
+ /// merged.
+ LLT buildLCMMergePieces(LLT DstTy, LLT NarrowTy, LLT GCDTy,
+ SmallVectorImpl<Register> &VRegs,
+ unsigned PadStrategy = TargetOpcode::G_ANYEXT);
+
+ /// Merge the values in \p RemergeRegs to an \p LCMTy typed value. Extract the
+ /// low bits into \p DstReg. This is intended to use the outputs from
+ /// buildLCMMergePieces after processing.
+ void buildWidenedRemergeToDst(Register DstReg, LLT LCMTy,
+ ArrayRef<Register> RemergeRegs);
+
/// Perform generic multiplication of values held in multiple registers.
/// Generated instructions use only types NarrowTy and i1.
/// Destination can be same or two times size of the source.
@@ -174,11 +232,6 @@ public:
LegalizeResult fewerElementsVectorImplicitDef(MachineInstr &MI,
unsigned TypeIdx, LLT NarrowTy);
- /// Legalize a simple vector instruction where all operands are the same type
- /// by splitting into multiple components.
- LegalizeResult fewerElementsVectorBasic(MachineInstr &MI, unsigned TypeIdx,
- LLT NarrowTy);
-
/// Legalize a instruction with a vector type where each operand may have a
/// different element type. All type indexes must have the same number of
/// elements.
@@ -210,6 +263,19 @@ public:
LegalizeResult
reduceLoadStoreWidth(MachineInstr &MI, unsigned TypeIdx, LLT NarrowTy);
+ /// Legalize an instruction by reducing the operation width, either by
+ /// narrowing the type of the operation or by reducing the number of elements
+ /// of a vector.
+ /// The used strategy (narrow vs. fewerElements) is decided by \p NarrowTy.
+ /// Narrow is used if the scalar type of \p NarrowTy and \p DstTy differ,
+ /// fewerElements is used when the scalar type is the same but the number of
+ /// elements between \p NarrowTy and \p DstTy differ.
+ LegalizeResult reduceOperationWidth(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
+
+ LegalizeResult fewerElementsVectorSextInReg(MachineInstr &MI, unsigned TypeIdx,
+ LLT NarrowTy);
+
LegalizeResult narrowScalarShiftByConstant(MachineInstr &MI, const APInt &Amt,
LLT HalfTy, LLT ShiftAmtTy);
@@ -219,19 +285,31 @@ public:
LegalizeResult narrowScalarInsert(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarBasic(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarExt(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult narrowScalarSelect(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarCTLZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarCTTZ(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult narrowScalarCTPOP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerBitcast(MachineInstr &MI);
LegalizeResult lowerBitCount(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerU64ToF32BitOps(MachineInstr &MI);
LegalizeResult lowerUITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerSITOFP(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerFPTOUI(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+ LegalizeResult lowerFPTOSI(MachineInstr &MI);
+
+ LegalizeResult lowerFPTRUNC_F64_TO_F16(MachineInstr &MI);
+ LegalizeResult lowerFPTRUNC(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
+
LegalizeResult lowerMinMax(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerFCopySign(MachineInstr &MI, unsigned TypeIdx, LLT Ty);
LegalizeResult lowerFMinNumMaxNum(MachineInstr &MI);
LegalizeResult lowerFMad(MachineInstr &MI);
LegalizeResult lowerIntrinsicRound(MachineInstr &MI);
+ LegalizeResult lowerFFloor(MachineInstr &MI);
+ LegalizeResult lowerMergeValues(MachineInstr &MI);
LegalizeResult lowerUnmergeValues(MachineInstr &MI);
LegalizeResult lowerShuffleVector(MachineInstr &MI);
LegalizeResult lowerDynStackAlloc(MachineInstr &MI);
@@ -240,15 +318,16 @@ public:
LegalizeResult lowerSADDO_SSUBO(MachineInstr &MI);
LegalizeResult lowerBswap(MachineInstr &MI);
LegalizeResult lowerBitreverse(MachineInstr &MI);
- LegalizeResult lowerReadRegister(MachineInstr &MI);
-
-private:
- MachineRegisterInfo &MRI;
- const LegalizerInfo &LI;
- /// To keep track of changes made by the LegalizerHelper.
- GISelChangeObserver &Observer;
+ LegalizeResult lowerReadWriteRegister(MachineInstr &MI);
};
+/// Helper function that creates a libcall to the given \p Name using the given
+/// calling convention \p CC.
+LegalizerHelper::LegalizeResult
+createLibcall(MachineIRBuilder &MIRBuilder, const char *Name,
+ const CallLowering::ArgInfo &Result,
+ ArrayRef<CallLowering::ArgInfo> Args, CallingConv::ID CC);
+
/// Helper function that creates the given libcall.
LegalizerHelper::LegalizeResult
createLibcall(MachineIRBuilder &MIRBuilder, RTLIB::Libcall Libcall,
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
index 29f0d6575bac..61e0418757bc 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
@@ -35,6 +35,7 @@ namespace llvm {
extern cl::opt<bool> DisableGISelLegalityCheck;
+class LegalizerHelper;
class MachineInstr;
class MachineIRBuilder;
class MachineRegisterInfo;
@@ -68,6 +69,9 @@ enum LegalizeAction : std::uint8_t {
/// the first two results.
MoreElements,
+ /// Perform the operation on a different, but equivalently sized type.
+ Bitcast,
+
/// The operation itself must be expressed in terms of simpler actions on
/// this target. E.g. a SREM replaced by an SDIV and subtraction.
Lower,
@@ -153,7 +157,7 @@ struct LegalizeActionStep {
LLT NewType;
LegalizeActionStep(LegalizeAction Action, unsigned TypeIdx,
- const LLT &NewType)
+ const LLT NewType)
: Action(Action), TypeIdx(TypeIdx), NewType(NewType) {}
bool operator==(const LegalizeActionStep &RHS) const {
@@ -200,6 +204,20 @@ template<typename Predicate, typename... Args>
Predicate all(Predicate P0, Predicate P1, Args... args) {
return all(all(P0, P1), args...);
}
+
+/// True iff P0 or P1 are true.
+template<typename Predicate>
+Predicate any(Predicate P0, Predicate P1) {
+ return [=](const LegalityQuery &Query) {
+ return P0(Query) || P1(Query);
+ };
+}
+/// True iff any given predicates are true.
+template<typename Predicate, typename... Args>
+Predicate any(Predicate P0, Predicate P1, Args... args) {
+ return any(any(P0, P1), args...);
+}
+
/// True iff the given type index is the specified types.
LegalityPredicate typeIs(unsigned TypeIdx, LLT TypesInit);
/// True iff the given type index is one of the specified types.
@@ -225,13 +243,16 @@ LegalityPredicate isPointer(unsigned TypeIdx);
/// space.
LegalityPredicate isPointer(unsigned TypeIdx, unsigned AddrSpace);
+/// True if the type index is a vector with element type \p EltTy
+LegalityPredicate elementTypeIs(unsigned TypeIdx, LLT EltTy);
+
/// True iff the specified type index is a scalar that's narrower than the given
/// size.
-LegalityPredicate narrowerThan(unsigned TypeIdx, unsigned Size);
+LegalityPredicate scalarNarrowerThan(unsigned TypeIdx, unsigned Size);
/// True iff the specified type index is a scalar that's wider than the given
/// size.
-LegalityPredicate widerThan(unsigned TypeIdx, unsigned Size);
+LegalityPredicate scalarWiderThan(unsigned TypeIdx, unsigned Size);
/// True iff the specified type index is a scalar or vector with an element type
/// that's narrower than the given size.
@@ -249,8 +270,20 @@ LegalityPredicate sizeNotPow2(unsigned TypeIdx);
/// is not a power of 2.
LegalityPredicate scalarOrEltSizeNotPow2(unsigned TypeIdx);
+/// True if the total bitwidth of the specified type index is \p Size bits.
+LegalityPredicate sizeIs(unsigned TypeIdx, unsigned Size);
+
/// True iff the specified type indices are both the same bit size.
LegalityPredicate sameSize(unsigned TypeIdx0, unsigned TypeIdx1);
+
+/// True iff the first type index has a larger total bit size than second type
+/// index.
+LegalityPredicate largerThan(unsigned TypeIdx0, unsigned TypeIdx1);
+
+/// True iff the first type index has a smaller total bit size than second type
+/// index.
+LegalityPredicate smallerThan(unsigned TypeIdx0, unsigned TypeIdx1);
+
/// True iff the specified MMO index has a size that is not a power of 2
LegalityPredicate memSizeInBytesNotPow2(unsigned MMOIdx);
/// True iff the specified type index is a vector whose element count is not a
@@ -427,6 +460,14 @@ class LegalizeRuleSet {
immIdx(0); // Inform verifier imm idx 0 is handled.
return actionIf(Action, typeInSet(typeIdx(0), Types));
}
+
+ LegalizeRuleSet &actionForTypeWithAnyImm(
+ LegalizeAction Action, std::initializer_list<std::pair<LLT, LLT>> Types) {
+ using namespace LegalityPredicates;
+ immIdx(0); // Inform verifier imm idx 0 is handled.
+ return actionIf(Action, typePairInSet(typeIdx(0), typeIdx(1), Types));
+ }
+
/// Use the given action when type indexes 0 and 1 are both in the given list.
/// That is, the type pair is in the cartesian product of the list.
/// Action should not be an action that requires mutation.
@@ -496,6 +537,13 @@ public:
markAllIdxsAsCovered();
return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
}
+
+ LegalizeRuleSet &legalForTypeWithAnyImm(
+ std::initializer_list<std::pair<LLT, LLT>> Types) {
+ markAllIdxsAsCovered();
+ return actionForTypeWithAnyImm(LegalizeAction::Legal, Types);
+ }
+
/// The instruction is legal when type indexes 0 and 1 along with the memory
/// size and minimum alignment is any type and size tuple in the given list.
LegalizeRuleSet &legalForTypesWithMemDesc(
@@ -531,6 +579,15 @@ public:
return actionIf(LegalizeAction::Legal, always);
}
+ /// The specified type index is coerced if predicate is true.
+ LegalizeRuleSet &bitcastIf(LegalityPredicate Predicate,
+ LegalizeMutation Mutation) {
+ // We have no choice but conservatively assume that lowering with a
+ // free-form user provided Predicate properly handles all type indices:
+ markAllIdxsAsCovered();
+ return actionIf(LegalizeAction::Bitcast, Predicate, Mutation);
+ }
+
/// The instruction is lowered.
LegalizeRuleSet &lower() {
using namespace LegalizeMutations;
@@ -667,6 +724,11 @@ public:
LegalizeRuleSet &unsupportedIf(LegalityPredicate Predicate) {
return actionIf(LegalizeAction::Unsupported, Predicate);
}
+
+ LegalizeRuleSet &unsupportedFor(std::initializer_list<LLT> Types) {
+ return actionFor(LegalizeAction::Unsupported, Types);
+ }
+
LegalizeRuleSet &unsupportedIfMemSizeNotPow2() {
return actionIf(LegalizeAction::Unsupported,
LegalityPredicates::memSizeInBytesNotPow2(0));
@@ -739,7 +801,7 @@ public:
}
/// Ensure the scalar or element is at least as wide as Ty.
- LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
+ LegalizeRuleSet &minScalarOrElt(unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(LegalizeAction::WidenScalar,
@@ -749,7 +811,7 @@ public:
/// Ensure the scalar or element is at least as wide as Ty.
LegalizeRuleSet &minScalarOrEltIf(LegalityPredicate Predicate,
- unsigned TypeIdx, const LLT &Ty) {
+ unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(LegalizeAction::WidenScalar,
@@ -759,16 +821,16 @@ public:
}
/// Ensure the scalar is at least as wide as Ty.
- LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT &Ty) {
+ LegalizeRuleSet &minScalar(unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(LegalizeAction::WidenScalar,
- narrowerThan(TypeIdx, Ty.getSizeInBits()),
+ scalarNarrowerThan(TypeIdx, Ty.getSizeInBits()),
changeTo(typeIdx(TypeIdx), Ty));
}
/// Ensure the scalar is at most as wide as Ty.
- LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT &Ty) {
+ LegalizeRuleSet &maxScalarOrElt(unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(LegalizeAction::NarrowScalar,
@@ -777,11 +839,11 @@ public:
}
/// Ensure the scalar is at most as wide as Ty.
- LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT &Ty) {
+ LegalizeRuleSet &maxScalar(unsigned TypeIdx, const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(LegalizeAction::NarrowScalar,
- widerThan(TypeIdx, Ty.getSizeInBits()),
+ scalarWiderThan(TypeIdx, Ty.getSizeInBits()),
changeTo(typeIdx(TypeIdx), Ty));
}
@@ -789,27 +851,27 @@ public:
/// For example, when the maximum size of one type depends on the size of
/// another such as extracting N bits from an M bit container.
LegalizeRuleSet &maxScalarIf(LegalityPredicate Predicate, unsigned TypeIdx,
- const LLT &Ty) {
+ const LLT Ty) {
using namespace LegalityPredicates;
using namespace LegalizeMutations;
return actionIf(
LegalizeAction::NarrowScalar,
[=](const LegalityQuery &Query) {
- return widerThan(TypeIdx, Ty.getSizeInBits()) && Predicate(Query);
+ return scalarWiderThan(TypeIdx, Ty.getSizeInBits()) && Predicate(Query);
},
changeElementTo(typeIdx(TypeIdx), Ty));
}
/// Limit the range of scalar sizes to MinTy and MaxTy.
- LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT &MinTy,
- const LLT &MaxTy) {
+ LegalizeRuleSet &clampScalar(unsigned TypeIdx, const LLT MinTy,
+ const LLT MaxTy) {
assert(MinTy.isScalar() && MaxTy.isScalar() && "Expected scalar types");
return minScalar(TypeIdx, MinTy).maxScalar(TypeIdx, MaxTy);
}
/// Limit the range of scalar sizes to MinTy and MaxTy.
- LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT &MinTy,
- const LLT &MaxTy) {
+ LegalizeRuleSet &clampScalarOrElt(unsigned TypeIdx, const LLT MinTy,
+ const LLT MaxTy) {
return minScalarOrElt(TypeIdx, MinTy).maxScalarOrElt(TypeIdx, MaxTy);
}
@@ -855,7 +917,7 @@ public:
}
/// Limit the number of elements in EltTy vectors to at least MinElements.
- LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT &EltTy,
+ LegalizeRuleSet &clampMinNumElements(unsigned TypeIdx, const LLT EltTy,
unsigned MinElements) {
// Mark the type index as covered:
typeIdx(TypeIdx);
@@ -873,7 +935,7 @@ public:
});
}
/// Limit the number of elements in EltTy vectors to at most MaxElements.
- LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT &EltTy,
+ LegalizeRuleSet &clampMaxNumElements(unsigned TypeIdx, const LLT EltTy,
unsigned MaxElements) {
// Mark the type index as covered:
typeIdx(TypeIdx);
@@ -896,12 +958,12 @@ public:
/// No effect if the type is not a vector or does not have the same element
/// type as the constraints.
/// The element type of MinTy and MaxTy must match.
- LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT &MinTy,
- const LLT &MaxTy) {
+ LegalizeRuleSet &clampNumElements(unsigned TypeIdx, const LLT MinTy,
+ const LLT MaxTy) {
assert(MinTy.getElementType() == MaxTy.getElementType() &&
"Expected element types to agree");
- const LLT &EltTy = MinTy.getElementType();
+ const LLT EltTy = MinTy.getElementType();
return clampMinNumElements(TypeIdx, EltTy, MinTy.getNumElements())
.clampMaxNumElements(TypeIdx, EltTy, MaxTy.getNumElements());
}
@@ -1149,14 +1211,20 @@ public:
bool isLegalOrCustom(const MachineInstr &MI,
const MachineRegisterInfo &MRI) const;
- virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI,
- MachineIRBuilder &MIRBuilder,
- GISelChangeObserver &Observer) const;
+ /// Called for instructions with the Custom LegalizationAction.
+ virtual bool legalizeCustom(LegalizerHelper &Helper,
+ MachineInstr &MI) const {
+ llvm_unreachable("must implement this if custom action is used");
+ }
+ /// \returns true if MI is either legal or has been legalized and false if not
+ /// legal.
/// Return true if MI is either legal or has been legalized and false
/// if not legal.
- virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI,
- MachineIRBuilder &MIRBuilder) const;
+ virtual bool legalizeIntrinsic(LegalizerHelper &Helper,
+ MachineInstr &MI) const {
+ return true;
+ }
/// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
/// widening a constant of type SmallTy which targets can override.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h
index ad1904725dcd..67e450641eaf 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Localizer.h
@@ -82,9 +82,7 @@ public:
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties()
- .set(MachineFunctionProperties::Property::IsSSA)
- .set(MachineFunctionProperties::Property::Legalized)
- .set(MachineFunctionProperties::Property::RegBankSelected);
+ .set(MachineFunctionProperties::Property::IsSSA);
}
void getAnalysisUsage(AnalysisUsage &AU) const override;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LostDebugLocObserver.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LostDebugLocObserver.h
new file mode 100644
index 000000000000..cd2a871e9579
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/LostDebugLocObserver.h
@@ -0,0 +1,50 @@
+//===----- llvm/CodeGen/GlobalISel/LostDebugLocObserver.h -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// Tracks DebugLocs between checkpoints and verifies that they are transferred.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CODEGEN_GLOBALISEL_LOSTDEBUGLOCOBSERVER_H
+#define LLVM_CODEGEN_GLOBALISEL_LOSTDEBUGLOCOBSERVER_H
+
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/CodeGen/GlobalISel/GISelChangeObserver.h"
+
+namespace llvm {
+class LostDebugLocObserver : public GISelChangeObserver {
+ StringRef DebugType;
+ SmallSet<DebugLoc, 4> LostDebugLocs;
+ SmallPtrSet<MachineInstr *, 4> PotentialMIsForDebugLocs;
+ unsigned NumLostDebugLocs = 0;
+
+public:
+ LostDebugLocObserver(StringRef DebugType) : DebugType(DebugType) {}
+
+ unsigned getNumLostDebugLocs() const { return NumLostDebugLocs; }
+
+ /// Call this to indicate that it's a good point to assess whether locations
+ /// have been lost. Typically this will be when a logical change has been
+ /// completed such as the caller has finished replacing some instructions with
+ /// alternatives. When CheckDebugLocs is true, the locations will be checked
+ /// to see if any have been lost since the last checkpoint. When
+ /// CheckDebugLocs is false, it will just reset ready for the next checkpoint
+ /// without checking anything. This can be helpful to limit the detection to
+ /// easy-to-fix portions of an algorithm before allowing more difficult ones.
+ void checkpoint(bool CheckDebugLocs = true);
+
+ void createdInstr(MachineInstr &MI) override;
+ void erasingInstr(MachineInstr &MI) override;
+ void changingInstr(MachineInstr &MI) override;
+ void changedInstr(MachineInstr &MI) override;
+
+private:
+ void analyzeDebugLocations();
+};
+
+} // namespace llvm
+#endif // ifndef LLVM_CODEGEN_GLOBALISEL_LOSTDEBUGLOCOBSERVER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
index be12341f5763..043be086ff41 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MIPatternMatch.h
@@ -12,10 +12,9 @@
#ifndef LLVM_GMIR_PATTERNMATCH_H
#define LLVM_GMIR_PATTERNMATCH_H
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
#include "llvm/CodeGen/GlobalISel/Utils.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/IR/InstrTypes.h"
namespace llvm {
namespace MIPatternMatch {
@@ -30,7 +29,7 @@ template <typename SubPatternT> struct OneUse_match {
SubPatternT SubPat;
OneUse_match(const SubPatternT &SP) : SubPat(SP) {}
- bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
return MRI.hasOneUse(Reg) && SubPat.match(MRI, Reg);
}
};
@@ -43,7 +42,7 @@ inline OneUse_match<SubPat> m_OneUse(const SubPat &SP) {
struct ConstantMatch {
int64_t &CR;
ConstantMatch(int64_t &C) : CR(C) {}
- bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
if (auto MaybeCst = getConstantVRegVal(Reg, MRI)) {
CR = *MaybeCst;
return true;
@@ -60,7 +59,7 @@ inline ConstantMatch m_ICst(int64_t &Cst) { return ConstantMatch(Cst); }
// that.
struct operand_type_match {
- bool match(const MachineRegisterInfo &MRI, unsigned Reg) { return true; }
+ bool match(const MachineRegisterInfo &MRI, Register Reg) { return true; }
bool match(const MachineRegisterInfo &MRI, MachineOperand *MO) {
return MO->isReg();
}
@@ -123,7 +122,7 @@ template <typename BindTy> struct bind_helper {
template <> struct bind_helper<MachineInstr *> {
static bool bind(const MachineRegisterInfo &MRI, MachineInstr *&MI,
- unsigned Reg) {
+ Register Reg) {
MI = MRI.getVRegDef(Reg);
if (MI)
return true;
@@ -132,7 +131,7 @@ template <> struct bind_helper<MachineInstr *> {
};
template <> struct bind_helper<LLT> {
- static bool bind(const MachineRegisterInfo &MRI, LLT &Ty, unsigned Reg) {
+ static bool bind(const MachineRegisterInfo &MRI, LLT Ty, Register Reg) {
Ty = MRI.getType(Reg);
if (Ty.isValid())
return true;
@@ -142,7 +141,7 @@ template <> struct bind_helper<LLT> {
template <> struct bind_helper<const ConstantFP *> {
static bool bind(const MachineRegisterInfo &MRI, const ConstantFP *&F,
- unsigned Reg) {
+ Register Reg) {
F = getConstantFPVRegVal(Reg, MRI);
if (F)
return true;
@@ -162,7 +161,9 @@ template <typename Class> struct bind_ty {
inline bind_ty<Register> m_Reg(Register &R) { return R; }
inline bind_ty<MachineInstr *> m_MInstr(MachineInstr *&MI) { return MI; }
-inline bind_ty<LLT> m_Type(LLT &Ty) { return Ty; }
+inline bind_ty<LLT> m_Type(LLT Ty) { return Ty; }
+inline bind_ty<CmpInst::Predicate> m_Pred(CmpInst::Predicate &P) { return P; }
+inline operand_type_match m_Pred() { return operand_type_match(); }
// Helper for matching G_FCONSTANT
inline bind_ty<const ConstantFP *> m_GFCst(const ConstantFP *&C) { return C; }
@@ -238,6 +239,18 @@ inline BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true> m_GOr(const LHS &L,
return BinaryOp_match<LHS, RHS, TargetOpcode::G_OR, true>(L, R);
}
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false>
+m_GShl(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_SHL, false>(L, R);
+}
+
+template <typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, TargetOpcode::G_LSHR, false>
+m_GLShr(const LHS &L, const RHS &R) {
+ return BinaryOp_match<LHS, RHS, TargetOpcode::G_LSHR, false>(L, R);
+}
+
// Helper for unary instructions (G_[ZSA]EXT/G_TRUNC) etc
template <typename SrcTy, unsigned Opcode> struct UnaryOp_match {
SrcTy L;
@@ -320,12 +333,51 @@ inline UnaryOp_match<SrcTy, TargetOpcode::COPY> m_Copy(SrcTy &&Src) {
return UnaryOp_match<SrcTy, TargetOpcode::COPY>(std::forward<SrcTy>(Src));
}
+// General helper for generic MI compares, i.e. G_ICMP and G_FCMP
+// TODO: Allow checking a specific predicate.
+template <typename Pred_P, typename LHS_P, typename RHS_P, unsigned Opcode>
+struct CompareOp_match {
+ Pred_P P;
+ LHS_P L;
+ RHS_P R;
+
+ CompareOp_match(const Pred_P &Pred, const LHS_P &LHS, const RHS_P &RHS)
+ : P(Pred), L(LHS), R(RHS) {}
+
+ template <typename OpTy>
+ bool match(const MachineRegisterInfo &MRI, OpTy &&Op) {
+ MachineInstr *TmpMI;
+ if (!mi_match(Op, MRI, m_MInstr(TmpMI)) || TmpMI->getOpcode() != Opcode)
+ return false;
+
+ auto TmpPred =
+ static_cast<CmpInst::Predicate>(TmpMI->getOperand(1).getPredicate());
+ if (!P.match(MRI, TmpPred))
+ return false;
+
+ return L.match(MRI, TmpMI->getOperand(2).getReg()) &&
+ R.match(MRI, TmpMI->getOperand(3).getReg());
+ }
+};
+
+template <typename Pred, typename LHS, typename RHS>
+inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP>
+m_GICmp(const Pred &P, const LHS &L, const RHS &R) {
+ return CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_ICMP>(P, L, R);
+}
+
+template <typename Pred, typename LHS, typename RHS>
+inline CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP>
+m_GFCmp(const Pred &P, const LHS &L, const RHS &R) {
+ return CompareOp_match<Pred, LHS, RHS, TargetOpcode::G_FCMP>(P, L, R);
+}
+
// Helper for checking if a Reg is of specific type.
struct CheckType {
LLT Ty;
- CheckType(const LLT &Ty) : Ty(Ty) {}
+ CheckType(const LLT Ty) : Ty(Ty) {}
- bool match(const MachineRegisterInfo &MRI, unsigned Reg) {
+ bool match(const MachineRegisterInfo &MRI, Register Reg) {
return MRI.getType(Reg) == Ty;
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
index 072a1411de8a..d6498345f25c 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
@@ -14,8 +14,6 @@
#define LLVM_CODEGEN_GLOBALISEL_MACHINEIRBUILDER_H
#include "llvm/CodeGen/GlobalISel/CSEInfo.h"
-#include "llvm/CodeGen/GlobalISel/Types.h"
-
#include "llvm/CodeGen/LowLevelType.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
@@ -37,23 +35,23 @@ class GISelChangeObserver;
/// to transfer BuilderState between different kinds of MachineIRBuilders.
struct MachineIRBuilderState {
/// MachineFunction under construction.
- MachineFunction *MF;
+ MachineFunction *MF = nullptr;
/// Information used to access the description of the opcodes.
- const TargetInstrInfo *TII;
+ const TargetInstrInfo *TII = nullptr;
/// Information used to verify types are consistent and to create virtual registers.
- MachineRegisterInfo *MRI;
+ MachineRegisterInfo *MRI = nullptr;
/// Debug location to be set to any instruction we create.
DebugLoc DL;
/// \name Fields describing the insertion point.
/// @{
- MachineBasicBlock *MBB;
+ MachineBasicBlock *MBB = nullptr;
MachineBasicBlock::iterator II;
/// @}
- GISelChangeObserver *Observer;
+ GISelChangeObserver *Observer = nullptr;
- GISelCSEInfo *CSEInfo;
+ GISelCSEInfo *CSEInfo = nullptr;
};
class DstOp {
@@ -68,7 +66,7 @@ public:
DstOp(unsigned R) : Reg(R), Ty(DstType::Ty_Reg) {}
DstOp(Register R) : Reg(R), Ty(DstType::Ty_Reg) {}
DstOp(const MachineOperand &Op) : Reg(Op.getReg()), Ty(DstType::Ty_Reg) {}
- DstOp(const LLT &T) : LLTTy(T), Ty(DstType::Ty_LLT) {}
+ DstOp(const LLT T) : LLTTy(T), Ty(DstType::Ty_LLT) {}
DstOp(const TargetRegisterClass *TRC) : RC(TRC), Ty(DstType::Ty_RC) {}
void addDefToMIB(MachineRegisterInfo &MRI, MachineInstrBuilder &MIB) const {
@@ -223,21 +221,33 @@ class MachineIRBuilder {
MachineIRBuilderState State;
protected:
- void validateTruncExt(const LLT &Dst, const LLT &Src, bool IsExtend);
+ void validateTruncExt(const LLT Dst, const LLT Src, bool IsExtend);
+
+ void validateBinaryOp(const LLT Res, const LLT Op0, const LLT Op1);
+ void validateShiftOp(const LLT Res, const LLT Op0, const LLT Op1);
- void validateBinaryOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
- void validateShiftOp(const LLT &Res, const LLT &Op0, const LLT &Op1);
+ void validateSelectOp(const LLT ResTy, const LLT TstTy, const LLT Op0Ty,
+ const LLT Op1Ty);
- void validateSelectOp(const LLT &ResTy, const LLT &TstTy, const LLT &Op0Ty,
- const LLT &Op1Ty);
- void recordInsertion(MachineInstr *MI) const;
+ void recordInsertion(MachineInstr *InsertedInstr) const {
+ if (State.Observer)
+ State.Observer->createdInstr(*InsertedInstr);
+ }
public:
/// Some constructors for easy use.
MachineIRBuilder() = default;
MachineIRBuilder(MachineFunction &MF) { setMF(MF); }
- MachineIRBuilder(MachineInstr &MI) : MachineIRBuilder(*MI.getMF()) {
+
+ MachineIRBuilder(MachineBasicBlock &MBB, MachineBasicBlock::iterator InsPt) {
+ setMF(*MBB.getParent());
+ setInsertPt(MBB, InsPt);
+ }
+
+ MachineIRBuilder(MachineInstr &MI) :
+ MachineIRBuilder(*MI.getParent(), MI.getIterator()) {
setInstr(MI);
+ setDebugLoc(MI.getDebugLoc());
}
virtual ~MachineIRBuilder() = default;
@@ -294,10 +304,16 @@ public:
/// Set the insertion point before the specified position.
/// \pre MBB must be in getMF().
/// \pre II must be a valid iterator in MBB.
- void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II);
+ void setInsertPt(MachineBasicBlock &MBB, MachineBasicBlock::iterator II) {
+ assert(MBB.getParent() == &getMF() &&
+ "Basic block is in a different function");
+ State.MBB = &MBB;
+ State.II = II;
+ }
+
/// @}
- void setCSEInfo(GISelCSEInfo *Info);
+ void setCSEInfo(GISelCSEInfo *Info) { State.CSEInfo = Info; }
/// \name Setters for the insertion point.
/// @{
@@ -306,15 +322,34 @@ public:
/// Set the insertion point to the end of \p MBB.
/// \pre \p MBB must be contained by getMF().
- void setMBB(MachineBasicBlock &MBB);
+ void setMBB(MachineBasicBlock &MBB) {
+ State.MBB = &MBB;
+ State.II = MBB.end();
+ assert(&getMF() == MBB.getParent() &&
+ "Basic block is in a different function");
+ }
/// Set the insertion point to before MI.
/// \pre MI must be in getMF().
- void setInstr(MachineInstr &MI);
+ void setInstr(MachineInstr &MI) {
+ assert(MI.getParent() && "Instruction is not part of a basic block");
+ setMBB(*MI.getParent());
+ State.II = MI.getIterator();
+ }
/// @}
- void setChangeObserver(GISelChangeObserver &Observer);
- void stopObservingChanges();
+ /// Set the insertion point to before MI, and set the debug loc to MI's loc.
+ /// \pre MI must be in getMF().
+ void setInstrAndDebugLoc(MachineInstr &MI) {
+ setInstr(MI);
+ setDebugLoc(MI.getDebugLoc());
+ }
+
+ void setChangeObserver(GISelChangeObserver &Observer) {
+ State.Observer = &Observer;
+ }
+
+ void stopObservingChanges() { State.Observer = nullptr; }
/// @}
/// Set the debug location to \p DL for all the next build instructions.
@@ -330,7 +365,9 @@ public:
/// \pre setBasicBlock or setMI must have been called.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildInstr(unsigned Opcode);
+ MachineInstrBuilder buildInstr(unsigned Opcode) {
+ return insertInstr(buildInstrNoInsert(Opcode));
+ }
/// Build but don't insert <empty> = \p Opcode <empty>.
///
@@ -379,7 +416,7 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildDynStackAlloc(const DstOp &Res, const SrcOp &Size,
- unsigned Align);
+ Align Alignment);
/// Build and insert \p Res = G_FRAME_INDEX \p Idx
///
@@ -436,12 +473,18 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
Optional<MachineInstrBuilder> materializePtrAdd(Register &Res, Register Op0,
- const LLT &ValueTy,
+ const LLT ValueTy,
uint64_t Value);
- /// Build and insert \p Res = G_PTR_MASK \p Op0, \p NumBits
+ /// Build and insert \p Res = G_PTRMASK \p Op0, \p Op1
+ MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,
+ const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_PTRMASK, {Res}, {Op0, Op1});
+ }
+
+ /// Build and insert \p Res = G_PTRMASK \p Op0, \p G_CONSTANT (1 << NumBits) - 1
///
- /// G_PTR_MASK clears the low bits of a pointer operand without destroying its
+ /// This clears the low bits of a pointer operand without destroying its
/// pointer properties. This has the effect of rounding the address *down* to
/// a specified alignment in bits.
///
@@ -452,8 +495,8 @@ public:
/// be cleared in \p Op0.
///
/// \return a MachineInstrBuilder for the newly created instruction.
- MachineInstrBuilder buildPtrMask(const DstOp &Res, const SrcOp &Op0,
- uint32_t NumBits);
+ MachineInstrBuilder buildMaskLowPtrBits(const DstOp &Res, const SrcOp &Op0,
+ uint32_t NumBits);
/// Build and insert \p Res, \p CarryOut = G_UADDO \p Op0, \p Op1
///
@@ -468,7 +511,27 @@ public:
///
/// \return The newly created instruction.
MachineInstrBuilder buildUAddo(const DstOp &Res, const DstOp &CarryOut,
- const SrcOp &Op0, const SrcOp &Op1);
+ const SrcOp &Op0, const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_UADDO, {Res, CarryOut}, {Op0, Op1});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_USUBO \p Op0, \p Op1
+ MachineInstrBuilder buildUSubo(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_USUBO, {Res, CarryOut}, {Op0, Op1});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_SADDO \p Op0, \p Op1
+ MachineInstrBuilder buildSAddo(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_SADDO, {Res, CarryOut}, {Op0, Op1});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_SUBO \p Op0, \p Op1
+ MachineInstrBuilder buildSSubo(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1) {
+ return buildInstr(TargetOpcode::G_SSUBO, {Res, CarryOut}, {Op0, Op1});
+ }
/// Build and insert \p Res, \p CarryOut = G_UADDE \p Op0,
/// \p Op1, \p CarryIn
@@ -486,7 +549,34 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildUAdde(const DstOp &Res, const DstOp &CarryOut,
const SrcOp &Op0, const SrcOp &Op1,
- const SrcOp &CarryIn);
+ const SrcOp &CarryIn) {
+ return buildInstr(TargetOpcode::G_UADDE, {Res, CarryOut},
+ {Op0, Op1, CarryIn});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_USUBE \p Op0, \p Op1, \p CarryInp
+ MachineInstrBuilder buildUSube(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1,
+ const SrcOp &CarryIn) {
+ return buildInstr(TargetOpcode::G_USUBE, {Res, CarryOut},
+ {Op0, Op1, CarryIn});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_SADDE \p Op0, \p Op1, \p CarryInp
+ MachineInstrBuilder buildSAdde(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1,
+ const SrcOp &CarryIn) {
+ return buildInstr(TargetOpcode::G_SADDE, {Res, CarryOut},
+ {Op0, Op1, CarryIn});
+ }
+
+ /// Build and insert \p Res, \p CarryOut = G_SSUBE \p Op0, \p Op1, \p CarryInp
+ MachineInstrBuilder buildSSube(const DstOp &Res, const DstOp &CarryOut,
+ const SrcOp &Op0, const SrcOp &Op1,
+ const SrcOp &CarryIn) {
+ return buildInstr(TargetOpcode::G_SSUBE, {Res, CarryOut},
+ {Op0, Op1, CarryIn});
+ }
/// Build and insert \p Res = G_ANYEXT \p Op0
///
@@ -518,6 +608,11 @@ public:
/// \return The newly created instruction.
MachineInstrBuilder buildSExt(const DstOp &Res, const SrcOp &Op);
+ /// Build and insert \p Res = G_SEXT_INREG \p Op, ImmOp
+ MachineInstrBuilder buildSExtInReg(const DstOp &Res, const SrcOp &Op, int64_t ImmOp) {
+ return buildInstr(TargetOpcode::G_SEXT_INREG, {Res}, {Op, SrcOp(ImmOp)});
+ }
+
/// Build and insert \p Res = G_FPEXT \p Op
MachineInstrBuilder buildFPExt(const DstOp &Res, const SrcOp &Op,
Optional<unsigned> Flags = None) {
@@ -732,6 +827,14 @@ public:
MachineInstrBuilder buildLoadInstr(unsigned Opcode, const DstOp &Res,
const SrcOp &Addr, MachineMemOperand &MMO);
+ /// Helper to create a load from a constant offset given a base address. Load
+ /// the type of \p Dst from \p Offset from the given base address and memory
+ /// operand.
+ MachineInstrBuilder buildLoadFromOffset(const DstOp &Dst,
+ const SrcOp &BasePtr,
+ MachineMemOperand &BaseMMO,
+ int64_t Offset);
+
/// Build and insert `G_STORE Val, Addr, MMO`.
///
/// Stores the value \p Val to \p Addr.
@@ -783,6 +886,8 @@ public:
///
/// \return a MachineInstrBuilder for the newly created instruction.
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef<Register> Ops);
+ MachineInstrBuilder buildMerge(const DstOp &Res,
+ std::initializer_list<SrcOp> Ops);
/// Build and insert \p Res0, ... = G_UNMERGE_VALUES \p Op
///
@@ -847,8 +952,8 @@ public:
MachineInstrBuilder buildConcatVectors(const DstOp &Res,
ArrayRef<Register> Ops);
- MachineInstrBuilder buildInsert(Register Res, Register Src,
- Register Op, unsigned Index);
+ MachineInstrBuilder buildInsert(const DstOp &Res, const SrcOp &Src,
+ const SrcOp &Op, unsigned Index);
/// Build and insert either a G_INTRINSIC (if \p HasSideEffects is false) or
/// G_INTRINSIC_W_SIDE_EFFECTS instruction. Its first operand will be the
@@ -876,7 +981,7 @@ public:
///
/// \return The newly created instruction.
MachineInstrBuilder buildFPTrunc(const DstOp &Res, const SrcOp &Op,
- Optional<unsigned> FLags = None);
+ Optional<unsigned> Flags = None);
/// Build and insert \p Res = G_TRUNC \p Op
///
@@ -1202,6 +1307,11 @@ public:
/// Build and insert `G_FENCE Ordering, Scope`.
MachineInstrBuilder buildFence(unsigned Ordering, unsigned Scope);
+ /// Build and insert \p Dst = G_FREEZE \p Src
+ MachineInstrBuilder buildFreeze(const DstOp &Dst, const SrcOp &Src) {
+ return buildInstr(TargetOpcode::G_FREEZE, {Dst}, {Src});
+ }
+
/// Build and insert \p Res = G_BLOCK_ADDR \p BA
///
/// G_BLOCK_ADDR computes the address of a basic block.
@@ -1280,6 +1390,30 @@ public:
return buildInstr(TargetOpcode::G_FMUL, {Dst}, {Src0, Src1}, Flags);
}
+ MachineInstrBuilder buildFMinNum(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FMINNUM, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildFMaxNum(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FMAXNUM, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildFMinNumIEEE(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FMINNUM_IEEE, {Dst}, {Src0, Src1}, Flags);
+ }
+
+ MachineInstrBuilder buildFMaxNumIEEE(const DstOp &Dst, const SrcOp &Src0,
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FMAXNUM_IEEE, {Dst}, {Src0, Src1}, Flags);
+ }
+
MachineInstrBuilder buildShl(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1,
Optional<unsigned> Flags = None) {
@@ -1368,6 +1502,11 @@ public:
return buildInstr(TargetOpcode::G_CTTZ_ZERO_UNDEF, {Dst}, {Src0});
}
+ /// Build and insert \p Dst = G_BSWAP \p Src0
+ MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0) {
+ return buildInstr(TargetOpcode::G_BSWAP, {Dst}, {Src0});
+ }
+
/// Build and insert \p Res = G_FADD \p Op0, \p Op1
MachineInstrBuilder buildFAdd(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1,
@@ -1377,8 +1516,9 @@ public:
/// Build and insert \p Res = G_FSUB \p Op0, \p Op1
MachineInstrBuilder buildFSub(const DstOp &Dst, const SrcOp &Src0,
- const SrcOp &Src1) {
- return buildInstr(TargetOpcode::G_FSUB, {Dst}, {Src0, Src1});
+ const SrcOp &Src1,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FSUB, {Dst}, {Src0, Src1}, Flags);
}
/// Build and insert \p Res = G_FMA \p Op0, \p Op1, \p Op2
@@ -1419,6 +1559,30 @@ public:
return buildInstr(TargetOpcode::G_INTRINSIC_TRUNC, {Dst}, {Src0}, Flags);
}
+ /// Build and insert \p Res = GFFLOOR \p Op0, \p Op1
+ MachineInstrBuilder buildFFloor(const DstOp &Dst, const SrcOp &Src0,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FFLOOR, {Dst}, {Src0}, Flags);
+ }
+
+ /// Build and insert \p Dst = G_FLOG \p Src
+ MachineInstrBuilder buildFLog(const DstOp &Dst, const SrcOp &Src,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FLOG, {Dst}, {Src}, Flags);
+ }
+
+ /// Build and insert \p Dst = G_FLOG2 \p Src
+ MachineInstrBuilder buildFLog2(const DstOp &Dst, const SrcOp &Src,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FLOG2, {Dst}, {Src}, Flags);
+ }
+
+ /// Build and insert \p Dst = G_FEXP2 \p Src
+ MachineInstrBuilder buildFExp2(const DstOp &Dst, const SrcOp &Src,
+ Optional<unsigned> Flags = None) {
+ return buildInstr(TargetOpcode::G_FEXP2, {Dst}, {Src}, Flags);
+ }
+
/// Build and insert \p Res = G_FCOPYSIGN \p Op0, \p Op1
MachineInstrBuilder buildFCopysign(const DstOp &Dst, const SrcOp &Src0,
const SrcOp &Src1) {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Types.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Types.h
deleted file mode 100644
index 4fd7043ba02d..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Types.h
+++ /dev/null
@@ -1,33 +0,0 @@
-//===- llvm/CodeGen/GlobalISel/Types.h - Types used by GISel ----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// This file describes high level types that are used by several passes or
-/// APIs involved in the GlobalISel pipeline.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_GLOBALISEL_TYPES_H
-#define LLVM_CODEGEN_GLOBALISEL_TYPES_H
-
-#include "llvm/ADT/DenseMap.h"
-
-namespace llvm {
-
-class Value;
-
-/// Map a value to a virtual register.
-/// For now, we chose to map aggregate types to on single virtual
-/// register. This might be revisited if it turns out to be inefficient.
-/// PR26161 tracks that.
-/// Note: We need to expose this type to the target hooks for thing like
-/// ABI lowering that would be used during IRTranslation.
-using ValueToVReg = DenseMap<const Value *, unsigned>;
-
-} // end namespace llvm
-
-#endif // LLVM_CODEGEN_GLOBALISEL_TYPES_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Utils.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
index 429d6db20e0c..42d86917721a 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/GlobalISel/Utils.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/Register.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/LowLevelTypeImpl.h"
#include "llvm/Support/MachineValueType.h"
@@ -27,6 +28,7 @@ class MachineInstr;
class MachineOperand;
class MachineOptimizationRemarkEmitter;
class MachineOptimizationRemarkMissed;
+struct MachinePointerInfo;
class MachineRegisterInfo;
class MCInstrDesc;
class RegisterBankInfo;
@@ -42,9 +44,9 @@ class APFloat;
/// create a new virtual register in the correct class.
///
/// \return The virtual register constrained to the right register class.
-unsigned constrainRegToClass(MachineRegisterInfo &MRI,
+Register constrainRegToClass(MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
- const RegisterBankInfo &RBI, unsigned Reg,
+ const RegisterBankInfo &RBI, Register Reg,
const TargetRegisterClass &RegClass);
/// Constrain the Register operand OpIdx, so that it is now constrained to the
@@ -54,14 +56,14 @@ unsigned constrainRegToClass(MachineRegisterInfo &MRI,
/// definition. The debug location of \p InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
-unsigned constrainOperandRegClass(const MachineFunction &MF,
+Register constrainOperandRegClass(const MachineFunction &MF,
const TargetRegisterInfo &TRI,
MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
const RegisterBankInfo &RBI,
MachineInstr &InsertPt,
const TargetRegisterClass &RegClass,
- const MachineOperand &RegMO, unsigned OpIdx);
+ const MachineOperand &RegMO);
/// Try to constrain Reg so that it is usable by argument OpIdx of the
/// provided MCInstrDesc \p II. If this fails, create a new virtual
@@ -72,7 +74,7 @@ unsigned constrainOperandRegClass(const MachineFunction &MF,
/// InsertPt is used for the new copy.
///
/// \return The virtual register constrained to the right register class.
-unsigned constrainOperandRegClass(const MachineFunction &MF,
+Register constrainOperandRegClass(const MachineFunction &MF,
const TargetRegisterInfo &TRI,
MachineRegisterInfo &MRI,
const TargetInstrInfo &TII,
@@ -93,6 +95,11 @@ bool constrainSelectedInstRegOperands(MachineInstr &I,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const RegisterBankInfo &RBI);
+
+/// Check if DstReg can be replaced with SrcReg depending on the register
+/// constraints.
+bool canReplaceReg(Register DstReg, Register SrcReg, MachineRegisterInfo &MRI);
+
/// Check whether an instruction \p MI is dead: it only defines dead virtual
/// registers, and doesn't have other side effects.
bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI);
@@ -108,15 +115,21 @@ void reportGISelFailure(MachineFunction &MF, const TargetPassConfig &TPC,
const char *PassName, StringRef Msg,
const MachineInstr &MI);
+/// Report an ISel warning as a missed optimization remark to the LLVMContext's
+/// diagnostic stream.
+void reportGISelWarning(MachineFunction &MF, const TargetPassConfig &TPC,
+ MachineOptimizationRemarkEmitter &MORE,
+ MachineOptimizationRemarkMissed &R);
+
/// If \p VReg is defined by a G_CONSTANT fits in int64_t
/// returns it.
-Optional<int64_t> getConstantVRegVal(unsigned VReg,
+Optional<int64_t> getConstantVRegVal(Register VReg,
const MachineRegisterInfo &MRI);
/// Simple struct used to hold a constant integer value and a virtual
/// register.
struct ValueAndVReg {
int64_t Value;
- unsigned VReg;
+ Register VReg;
};
/// If \p VReg is defined by a statically evaluable chain of
/// instructions rooted on a G_F/CONSTANT (\p LookThroughInstrs == true)
@@ -126,10 +139,10 @@ struct ValueAndVReg {
/// getConstantVRegVal.
/// When \p HandleFConstants == false the function bails on G_FCONSTANTs.
Optional<ValueAndVReg>
-getConstantVRegValWithLookThrough(unsigned VReg, const MachineRegisterInfo &MRI,
+getConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI,
bool LookThroughInstrs = true,
bool HandleFConstants = true);
-const ConstantFP* getConstantFPVRegVal(unsigned VReg,
+const ConstantFP* getConstantFPVRegVal(Register VReg,
const MachineRegisterInfo &MRI);
/// See if Reg is defined by an single def instruction that is
@@ -144,6 +157,13 @@ MachineInstr *getOpcodeDef(unsigned Opcode, Register Reg,
MachineInstr *getDefIgnoringCopies(Register Reg,
const MachineRegisterInfo &MRI);
+/// Find the source register for \p Reg, folding away any trivial copies. It
+/// will be an output register of the instruction that getDefIgnoringCopies
+/// returns. May return an invalid register if \p Reg is not a generic virtual
+/// register.
+Register getSrcRegIgnoringCopies(Register Reg,
+ const MachineRegisterInfo &MRI);
+
/// Returns an APFloat from Val converted to the appropriate size.
APFloat getAPFloatFromSize(double Val, unsigned Size);
@@ -151,11 +171,11 @@ APFloat getAPFloatFromSize(double Val, unsigned Size);
/// fallback.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU);
-Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const unsigned Op1,
- const unsigned Op2,
+Optional<APInt> ConstantFoldBinOp(unsigned Opcode, const Register Op1,
+ const Register Op2,
const MachineRegisterInfo &MRI);
-Optional<APInt> ConstantFoldExtOp(unsigned Opcode, const unsigned Op1,
+Optional<APInt> ConstantFoldExtOp(unsigned Opcode, const Register Op1,
uint64_t Imm, const MachineRegisterInfo &MRI);
/// Returns true if \p Val can be assumed to never be a NaN. If \p SNaN is true,
@@ -168,5 +188,19 @@ inline bool isKnownNeverSNaN(Register Val, const MachineRegisterInfo &MRI) {
return isKnownNeverNaN(Val, MRI, true);
}
+Align inferAlignFromPtrInfo(MachineFunction &MF, const MachinePointerInfo &MPO);
+
+/// Return the least common multiple type of \p Ty0 and \p Ty1, by changing
+/// the number of vector elements or scalar bitwidth. The intent is a
+/// G_MERGE_VALUES can be constructed from \p Ty0 elements, and unmerged into
+/// \p Ty1.
+LLT getLCMType(LLT Ty0, LLT Ty1);
+
+/// Return a type that is greatest common divisor of \p OrigTy and \p
+/// TargetTy. This will either change the number of vector elements, or
+/// bitwidth of scalars. The intent is the result type can be used as the
+/// result of a G_UNMERGE_VALUES from \p OrigTy.
+LLT getGCDType(LLT OrigTy, LLT TargetTy);
+
} // End namespace llvm.
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ISDOpcodes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ISDOpcodes.h
index 06140fae8790..534f988c5e96 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -22,1115 +22,1270 @@ namespace llvm {
///
namespace ISD {
- //===--------------------------------------------------------------------===//
- /// ISD::NodeType enum - This enum defines the target-independent operators
- /// for a SelectionDAG.
+//===--------------------------------------------------------------------===//
+/// ISD::NodeType enum - This enum defines the target-independent operators
+/// for a SelectionDAG.
+///
+/// Targets may also define target-dependent operator codes for SDNodes. For
+/// example, on x86, these are the enum values in the X86ISD namespace.
+/// Targets should aim to use target-independent operators to model their
+/// instruction sets as much as possible, and only use target-dependent
+/// operators when they have special requirements.
+///
+/// Finally, during and after selection proper, SNodes may use special
+/// operator codes that correspond directly with MachineInstr opcodes. These
+/// are used to represent selected instructions. See the isMachineOpcode()
+/// and getMachineOpcode() member functions of SDNode.
+///
+enum NodeType {
+
+ /// DELETED_NODE - This is an illegal value that is used to catch
+ /// errors. This opcode is not a legal opcode for any node.
+ DELETED_NODE,
+
+ /// EntryToken - This is the marker used to indicate the start of a region.
+ EntryToken,
+
+ /// TokenFactor - This node takes multiple tokens as input and produces a
+ /// single token result. This is used to represent the fact that the operand
+ /// operators are independent of each other.
+ TokenFactor,
+
+ /// AssertSext, AssertZext - These nodes record if a register contains a
+ /// value that has already been zero or sign extended from a narrower type.
+ /// These nodes take two operands. The first is the node that has already
+ /// been extended, and the second is a value type node indicating the width
+ /// of the extension
+ AssertSext,
+ AssertZext,
+ AssertAlign,
+
+ /// Various leaf nodes.
+ BasicBlock,
+ VALUETYPE,
+ CONDCODE,
+ Register,
+ RegisterMask,
+ Constant,
+ ConstantFP,
+ GlobalAddress,
+ GlobalTLSAddress,
+ FrameIndex,
+ JumpTable,
+ ConstantPool,
+ ExternalSymbol,
+ BlockAddress,
+
+ /// The address of the GOT
+ GLOBAL_OFFSET_TABLE,
+
+ /// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+ /// llvm.returnaddress on the DAG. These nodes take one operand, the index
+ /// of the frame or return address to return. An index of zero corresponds
+ /// to the current function's frame or return address, an index of one to
+ /// the parent's frame or return address, and so on.
+ FRAMEADDR,
+ RETURNADDR,
+ ADDROFRETURNADDR,
+ SPONENTRY,
+
+ /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
+ /// Materializes the offset from the local object pointer of another
+ /// function to a particular local object passed to llvm.localescape. The
+ /// operand is the MCSymbol label used to represent this offset, since
+ /// typically the offset is not known until after code generation of the
+ /// parent.
+ LOCAL_RECOVER,
+
+ /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
+ /// the DAG, which implements the named register global variables extension.
+ READ_REGISTER,
+ WRITE_REGISTER,
+
+ /// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+ /// first (possible) on-stack argument. This is needed for correct stack
+ /// adjustment during unwind.
+ FRAME_TO_ARGS_OFFSET,
+
+ /// EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical
+ /// Frame Address (CFA), generally the value of the stack pointer at the
+ /// call site in the previous frame.
+ EH_DWARF_CFA,
+
+ /// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+ /// 'eh_return' gcc dwarf builtin, which is used to return from
+ /// exception. The general meaning is: adjust stack by OFFSET and pass
+ /// execution to HANDLER. Many platform-related details also :)
+ EH_RETURN,
+
+ /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
+ /// This corresponds to the eh.sjlj.setjmp intrinsic.
+ /// It takes an input chain and a pointer to the jump buffer as inputs
+ /// and returns an outchain.
+ EH_SJLJ_SETJMP,
+
+ /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
+ /// This corresponds to the eh.sjlj.longjmp intrinsic.
+ /// It takes an input chain and a pointer to the jump buffer as inputs
+ /// and returns an outchain.
+ EH_SJLJ_LONGJMP,
+
+ /// OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN)
+ /// The target initializes the dispatch table here.
+ EH_SJLJ_SETUP_DISPATCH,
+
+ /// TargetConstant* - Like Constant*, but the DAG does not do any folding,
+ /// simplification, or lowering of the constant. They are used for constants
+ /// which are known to fit in the immediate fields of their users, or for
+ /// carrying magic numbers which are not values which need to be
+ /// materialized in registers.
+ TargetConstant,
+ TargetConstantFP,
+
+ /// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+ /// anything else with this node, and this is valid in the target-specific
+ /// dag, turning into a GlobalAddress operand.
+ TargetGlobalAddress,
+ TargetGlobalTLSAddress,
+ TargetFrameIndex,
+ TargetJumpTable,
+ TargetConstantPool,
+ TargetExternalSymbol,
+ TargetBlockAddress,
+
+ MCSymbol,
+
+ /// TargetIndex - Like a constant pool entry, but with completely
+ /// target-dependent semantics. Holds target flags, a 32-bit index, and a
+ /// 64-bit index. Targets can use this however they like.
+ TargetIndex,
+
+ /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with no side effects.
+ /// The first operand is the ID number of the intrinsic from the
+ /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
+ /// node returns the result of the intrinsic.
+ INTRINSIC_WO_CHAIN,
+
+ /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// returns a result. The first operand is a chain pointer. The second is
+ /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
+ /// operands to the intrinsic follow. The node has two results, the result
+ /// of the intrinsic and an output chain.
+ INTRINSIC_W_CHAIN,
+
+ /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// does not return a result. The first operand is a chain pointer. The
+ /// second is the ID number of the intrinsic from the llvm::Intrinsic
+ /// namespace. The operands to the intrinsic follow.
+ INTRINSIC_VOID,
+
+ /// CopyToReg - This node has three operands: a chain, a register number to
+ /// set to this value, and a value.
+ CopyToReg,
+
+ /// CopyFromReg - This node indicates that the input value is a virtual or
+ /// physical register that is defined outside of the scope of this
+ /// SelectionDAG. The register is available from the RegisterSDNode object.
+ CopyFromReg,
+
+ /// UNDEF - An undefined node.
+ UNDEF,
+
+ // FREEZE - FREEZE(VAL) returns an arbitrary value if VAL is UNDEF (or
+ // is evaluated to UNDEF), or returns VAL otherwise. Note that each
+ // read of UNDEF can yield different value, but FREEZE(UNDEF) cannot.
+ FREEZE,
+
+ /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
+ /// a Constant, which is required to be operand #1) half of the integer or
+ /// float value specified as operand #0. This is only for use before
+ /// legalization, for values that will be broken into multiple registers.
+ EXTRACT_ELEMENT,
+
+ /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
+ /// Given two values of the same integer value type, this produces a value
+ /// twice as big. Like EXTRACT_ELEMENT, this can only be used before
+ /// legalization. The lower part of the composite value should be in
+ /// element 0 and the upper part should be in element 1.
+ BUILD_PAIR,
+
+ /// MERGE_VALUES - This node takes multiple discrete operands and returns
+ /// them all as its individual results. This nodes has exactly the same
+ /// number of inputs and outputs. This node is useful for some pieces of the
+ /// code generator that want to think about a single node with multiple
+ /// results, not multiple nodes.
+ MERGE_VALUES,
+
+ /// Simple integer binary arithmetic operators.
+ ADD,
+ SUB,
+ MUL,
+ SDIV,
+ UDIV,
+ SREM,
+ UREM,
+
+ /// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
+ /// a signed/unsigned value of type i[2*N], and return the full value as
+ /// two results, each of type iN.
+ SMUL_LOHI,
+ UMUL_LOHI,
+
+ /// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
+ /// remainder result.
+ SDIVREM,
+ UDIVREM,
+
+ /// CARRY_FALSE - This node is used when folding other nodes,
+ /// like ADDC/SUBC, which indicate the carry result is always false.
+ CARRY_FALSE,
+
+ /// Carry-setting nodes for multiple precision addition and subtraction.
+ /// These nodes take two operands of the same value type, and produce two
+ /// results. The first result is the normal add or sub result, the second
+ /// result is the carry flag result.
+ /// FIXME: These nodes are deprecated in favor of ADDCARRY and SUBCARRY.
+ /// They are kept around for now to provide a smooth transition path
+ /// toward the use of ADDCARRY/SUBCARRY and will eventually be removed.
+ ADDC,
+ SUBC,
+
+ /// Carry-using nodes for multiple precision addition and subtraction. These
+ /// nodes take three operands: The first two are the normal lhs and rhs to
+ /// the add or sub, and the third is the input carry flag. These nodes
+ /// produce two results; the normal result of the add or sub, and the output
+ /// carry flag. These nodes both read and write a carry flag to allow them
+ /// to them to be chained together for add and sub of arbitrarily large
+ /// values.
+ ADDE,
+ SUBE,
+
+ /// Carry-using nodes for multiple precision addition and subtraction.
+ /// These nodes take three operands: The first two are the normal lhs and
+ /// rhs to the add or sub, and the third is a boolean indicating if there
+ /// is an incoming carry. These nodes produce two results: the normal
+ /// result of the add or sub, and the output carry so they can be chained
+ /// together. The use of this opcode is preferable to adde/sube if the
+ /// target supports it, as the carry is a regular value rather than a
+ /// glue, which allows further optimisation.
+ ADDCARRY,
+ SUBCARRY,
+
+ /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
+ /// These nodes take two operands: the normal LHS and RHS to the add. They
+ /// produce two results: the normal result of the add, and a boolean that
+ /// indicates if an overflow occurred (*not* a flag, because it may be store
+ /// to memory, etc.). If the type of the boolean is not i1 then the high
+ /// bits conform to getBooleanContents.
+ /// These nodes are generated from llvm.[su]add.with.overflow intrinsics.
+ SADDO,
+ UADDO,
+
+ /// Same for subtraction.
+ SSUBO,
+ USUBO,
+
+ /// Same for multiplication.
+ SMULO,
+ UMULO,
+
+ /// RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2
+ /// integers with the same bit width (W). If the true value of LHS + RHS
+ /// exceeds the largest value that can be represented by W bits, the
+ /// resulting value is this maximum value. Otherwise, if this value is less
+ /// than the smallest value that can be represented by W bits, the
+ /// resulting value is this minimum value.
+ SADDSAT,
+ UADDSAT,
+
+ /// RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2
+ /// integers with the same bit width (W). If the true value of LHS - RHS
+ /// exceeds the largest value that can be represented by W bits, the
+ /// resulting value is this maximum value. Otherwise, if this value is less
+ /// than the smallest value that can be represented by W bits, the
+ /// resulting value is this minimum value.
+ SSUBSAT,
+ USUBSAT,
+
+ /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication
+ /// on
+ /// 2 integers with the same width and scale. SCALE represents the scale of
+ /// both operands as fixed point numbers. This SCALE parameter must be a
+ /// constant integer. A scale of zero is effectively performing
+ /// multiplication on 2 integers.
+ SMULFIX,
+ UMULFIX,
+
+ /// Same as the corresponding unsaturated fixed point instructions, but the
+ /// result is clamped between the min and max values representable by the
+ /// bits of the first 2 operands.
+ SMULFIXSAT,
+ UMULFIXSAT,
+
+ /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
+ /// 2 integers with the same width and scale. SCALE represents the scale
+ /// of both operands as fixed point numbers. This SCALE parameter must be a
+ /// constant integer.
+ SDIVFIX,
+ UDIVFIX,
+
+ /// Same as the corresponding unsaturated fixed point instructions, but the
+ /// result is clamped between the min and max values representable by the
+ /// bits of the first 2 operands.
+ SDIVFIXSAT,
+ UDIVFIXSAT,
+
+ /// Simple binary floating point operators.
+ FADD,
+ FSUB,
+ FMUL,
+ FDIV,
+ FREM,
+
+ /// Constrained versions of the binary floating point operators.
+ /// These will be lowered to the simple operators before final selection.
+ /// They are used to limit optimizations while the DAG is being
+ /// optimized.
+ STRICT_FADD,
+ STRICT_FSUB,
+ STRICT_FMUL,
+ STRICT_FDIV,
+ STRICT_FREM,
+ STRICT_FMA,
+
+ /// Constrained versions of libm-equivalent floating point intrinsics.
+ /// These will be lowered to the equivalent non-constrained pseudo-op
+ /// (or expanded to the equivalent library call) before final selection.
+ /// They are used to limit optimizations while the DAG is being optimized.
+ STRICT_FSQRT,
+ STRICT_FPOW,
+ STRICT_FPOWI,
+ STRICT_FSIN,
+ STRICT_FCOS,
+ STRICT_FEXP,
+ STRICT_FEXP2,
+ STRICT_FLOG,
+ STRICT_FLOG10,
+ STRICT_FLOG2,
+ STRICT_FRINT,
+ STRICT_FNEARBYINT,
+ STRICT_FMAXNUM,
+ STRICT_FMINNUM,
+ STRICT_FCEIL,
+ STRICT_FFLOOR,
+ STRICT_FROUND,
+ STRICT_FROUNDEVEN,
+ STRICT_FTRUNC,
+ STRICT_LROUND,
+ STRICT_LLROUND,
+ STRICT_LRINT,
+ STRICT_LLRINT,
+ STRICT_FMAXIMUM,
+ STRICT_FMINIMUM,
+
+ /// STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or
+ /// unsigned integer. These have the same semantics as fptosi and fptoui
+ /// in IR.
+ /// They are used to limit optimizations while the DAG is being optimized.
+ STRICT_FP_TO_SINT,
+ STRICT_FP_TO_UINT,
+
+ /// STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to
+ /// a floating point value. These have the same semantics as sitofp and
+ /// uitofp in IR.
+ /// They are used to limit optimizations while the DAG is being optimized.
+ STRICT_SINT_TO_FP,
+ STRICT_UINT_TO_FP,
+
+ /// X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating
+ /// point type down to the precision of the destination VT. TRUNC is a
+ /// flag, which is always an integer that is zero or one. If TRUNC is 0,
+ /// this is a normal rounding, if it is 1, this FP_ROUND is known to not
+ /// change the value of Y.
///
- /// Targets may also define target-dependent operator codes for SDNodes. For
- /// example, on x86, these are the enum values in the X86ISD namespace.
- /// Targets should aim to use target-independent operators to model their
- /// instruction sets as much as possible, and only use target-dependent
- /// operators when they have special requirements.
+ /// The TRUNC = 1 case is used in cases where we know that the value will
+ /// not be modified by the node, because Y is not using any of the extra
+ /// precision of source type. This allows certain transformations like
+ /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,1)) -> X which are not safe for
+ /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,0)) because the extra bits aren't
+ /// removed.
+ /// It is used to limit optimizations while the DAG is being optimized.
+ STRICT_FP_ROUND,
+
+ /// X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP
+ /// type.
+ /// It is used to limit optimizations while the DAG is being optimized.
+ STRICT_FP_EXTEND,
+
+ /// STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used
+ /// for floating-point operands only. STRICT_FSETCC performs a quiet
+ /// comparison operation, while STRICT_FSETCCS performs a signaling
+ /// comparison operation.
+ STRICT_FSETCC,
+ STRICT_FSETCCS,
+
+ /// FMA - Perform a * b + c with no intermediate rounding step.
+ FMA,
+
+ /// FMAD - Perform a * b + c, while getting the same result as the
+ /// separately rounded operations.
+ FMAD,
+
+ /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ /// DAG node does not require that X and Y have the same type, just that
+ /// they are both floating point. X and the result must have the same type.
+ /// FCOPYSIGN(f32, f64) is allowed.
+ FCOPYSIGN,
+
+ /// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
+ /// value as an integer 0/1 value.
+ FGETSIGN,
+
+ /// Returns platform specific canonical encoding of a floating point number.
+ FCANONICALIZE,
+
+ /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a fixed-width vector
+ /// with the specified, possibly variable, elements. The types of the
+ /// operands must match the vector element type, except that integer types
+ /// are allowed to be larger than the element type, in which case the
+ /// operands are implicitly truncated. The types of the operands must all
+ /// be the same.
+ BUILD_VECTOR,
+
+ /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
+ /// at IDX replaced with VAL. If the type of VAL is larger than the vector
+ /// element type then VAL is truncated before replacement.
///
- /// Finally, during and after selection proper, SNodes may use special
- /// operator codes that correspond directly with MachineInstr opcodes. These
- /// are used to represent selected instructions. See the isMachineOpcode()
- /// and getMachineOpcode() member functions of SDNode.
+ /// If VECTOR is a scalable vector, then IDX may be larger than the minimum
+ /// vector width. IDX is not first scaled by the runtime scaling factor of
+ /// VECTOR.
+ INSERT_VECTOR_ELT,
+
+ /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// identified by the (potentially variable) element number IDX. If the return
+ /// type is an integer type larger than the element type of the vector, the
+ /// result is extended to the width of the return type. In that case, the high
+ /// bits are undefined.
///
- enum NodeType {
- /// DELETED_NODE - This is an illegal value that is used to catch
- /// errors. This opcode is not a legal opcode for any node.
- DELETED_NODE,
-
- /// EntryToken - This is the marker used to indicate the start of a region.
- EntryToken,
-
- /// TokenFactor - This node takes multiple tokens as input and produces a
- /// single token result. This is used to represent the fact that the operand
- /// operators are independent of each other.
- TokenFactor,
-
- /// AssertSext, AssertZext - These nodes record if a register contains a
- /// value that has already been zero or sign extended from a narrower type.
- /// These nodes take two operands. The first is the node that has already
- /// been extended, and the second is a value type node indicating the width
- /// of the extension
- AssertSext, AssertZext,
-
- /// Various leaf nodes.
- BasicBlock, VALUETYPE, CONDCODE, Register, RegisterMask,
- Constant, ConstantFP,
- GlobalAddress, GlobalTLSAddress, FrameIndex,
- JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
-
- /// The address of the GOT
- GLOBAL_OFFSET_TABLE,
-
- /// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
- /// llvm.returnaddress on the DAG. These nodes take one operand, the index
- /// of the frame or return address to return. An index of zero corresponds
- /// to the current function's frame or return address, an index of one to
- /// the parent's frame or return address, and so on.
- FRAMEADDR, RETURNADDR, ADDROFRETURNADDR, SPONENTRY,
-
- /// LOCAL_RECOVER - Represents the llvm.localrecover intrinsic.
- /// Materializes the offset from the local object pointer of another
- /// function to a particular local object passed to llvm.localescape. The
- /// operand is the MCSymbol label used to represent this offset, since
- /// typically the offset is not known until after code generation of the
- /// parent.
- LOCAL_RECOVER,
-
- /// READ_REGISTER, WRITE_REGISTER - This node represents llvm.register on
- /// the DAG, which implements the named register global variables extension.
- READ_REGISTER,
- WRITE_REGISTER,
-
- /// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
- /// first (possible) on-stack argument. This is needed for correct stack
- /// adjustment during unwind.
- FRAME_TO_ARGS_OFFSET,
-
- /// EH_DWARF_CFA - This node represents the pointer to the DWARF Canonical
- /// Frame Address (CFA), generally the value of the stack pointer at the
- /// call site in the previous frame.
- EH_DWARF_CFA,
-
- /// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
- /// 'eh_return' gcc dwarf builtin, which is used to return from
- /// exception. The general meaning is: adjust stack by OFFSET and pass
- /// execution to HANDLER. Many platform-related details also :)
- EH_RETURN,
-
- /// RESULT, OUTCHAIN = EH_SJLJ_SETJMP(INCHAIN, buffer)
- /// This corresponds to the eh.sjlj.setjmp intrinsic.
- /// It takes an input chain and a pointer to the jump buffer as inputs
- /// and returns an outchain.
- EH_SJLJ_SETJMP,
-
- /// OUTCHAIN = EH_SJLJ_LONGJMP(INCHAIN, buffer)
- /// This corresponds to the eh.sjlj.longjmp intrinsic.
- /// It takes an input chain and a pointer to the jump buffer as inputs
- /// and returns an outchain.
- EH_SJLJ_LONGJMP,
-
- /// OUTCHAIN = EH_SJLJ_SETUP_DISPATCH(INCHAIN)
- /// The target initializes the dispatch table here.
- EH_SJLJ_SETUP_DISPATCH,
-
- /// TargetConstant* - Like Constant*, but the DAG does not do any folding,
- /// simplification, or lowering of the constant. They are used for constants
- /// which are known to fit in the immediate fields of their users, or for
- /// carrying magic numbers which are not values which need to be
- /// materialized in registers.
- TargetConstant,
- TargetConstantFP,
-
- /// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
- /// anything else with this node, and this is valid in the target-specific
- /// dag, turning into a GlobalAddress operand.
- TargetGlobalAddress,
- TargetGlobalTLSAddress,
- TargetFrameIndex,
- TargetJumpTable,
- TargetConstantPool,
- TargetExternalSymbol,
- TargetBlockAddress,
-
- MCSymbol,
-
- /// TargetIndex - Like a constant pool entry, but with completely
- /// target-dependent semantics. Holds target flags, a 32-bit index, and a
- /// 64-bit index. Targets can use this however they like.
- TargetIndex,
-
- /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
- /// This node represents a target intrinsic function with no side effects.
- /// The first operand is the ID number of the intrinsic from the
- /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
- /// node returns the result of the intrinsic.
- INTRINSIC_WO_CHAIN,
-
- /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
- /// This node represents a target intrinsic function with side effects that
- /// returns a result. The first operand is a chain pointer. The second is
- /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
- /// operands to the intrinsic follow. The node has two results, the result
- /// of the intrinsic and an output chain.
- INTRINSIC_W_CHAIN,
-
- /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
- /// This node represents a target intrinsic function with side effects that
- /// does not return a result. The first operand is a chain pointer. The
- /// second is the ID number of the intrinsic from the llvm::Intrinsic
- /// namespace. The operands to the intrinsic follow.
- INTRINSIC_VOID,
-
- /// CopyToReg - This node has three operands: a chain, a register number to
- /// set to this value, and a value.
- CopyToReg,
-
- /// CopyFromReg - This node indicates that the input value is a virtual or
- /// physical register that is defined outside of the scope of this
- /// SelectionDAG. The register is available from the RegisterSDNode object.
- CopyFromReg,
-
- /// UNDEF - An undefined node.
- UNDEF,
-
- /// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
- /// a Constant, which is required to be operand #1) half of the integer or
- /// float value specified as operand #0. This is only for use before
- /// legalization, for values that will be broken into multiple registers.
- EXTRACT_ELEMENT,
-
- /// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
- /// Given two values of the same integer value type, this produces a value
- /// twice as big. Like EXTRACT_ELEMENT, this can only be used before
- /// legalization. The lower part of the composite value should be in
- /// element 0 and the upper part should be in element 1.
- BUILD_PAIR,
-
- /// MERGE_VALUES - This node takes multiple discrete operands and returns
- /// them all as its individual results. This nodes has exactly the same
- /// number of inputs and outputs. This node is useful for some pieces of the
- /// code generator that want to think about a single node with multiple
- /// results, not multiple nodes.
- MERGE_VALUES,
-
- /// Simple integer binary arithmetic operators.
- ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
-
- /// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
- /// a signed/unsigned value of type i[2*N], and return the full value as
- /// two results, each of type iN.
- SMUL_LOHI, UMUL_LOHI,
-
- /// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
- /// remainder result.
- SDIVREM, UDIVREM,
-
- /// CARRY_FALSE - This node is used when folding other nodes,
- /// like ADDC/SUBC, which indicate the carry result is always false.
- CARRY_FALSE,
-
- /// Carry-setting nodes for multiple precision addition and subtraction.
- /// These nodes take two operands of the same value type, and produce two
- /// results. The first result is the normal add or sub result, the second
- /// result is the carry flag result.
- /// FIXME: These nodes are deprecated in favor of ADDCARRY and SUBCARRY.
- /// They are kept around for now to provide a smooth transition path
- /// toward the use of ADDCARRY/SUBCARRY and will eventually be removed.
- ADDC, SUBC,
-
- /// Carry-using nodes for multiple precision addition and subtraction. These
- /// nodes take three operands: The first two are the normal lhs and rhs to
- /// the add or sub, and the third is the input carry flag. These nodes
- /// produce two results; the normal result of the add or sub, and the output
- /// carry flag. These nodes both read and write a carry flag to allow them
- /// to them to be chained together for add and sub of arbitrarily large
- /// values.
- ADDE, SUBE,
-
- /// Carry-using nodes for multiple precision addition and subtraction.
- /// These nodes take three operands: The first two are the normal lhs and
- /// rhs to the add or sub, and the third is a boolean indicating if there
- /// is an incoming carry. These nodes produce two results: the normal
- /// result of the add or sub, and the output carry so they can be chained
- /// together. The use of this opcode is preferable to adde/sube if the
- /// target supports it, as the carry is a regular value rather than a
- /// glue, which allows further optimisation.
- ADDCARRY, SUBCARRY,
-
- /// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
- /// These nodes take two operands: the normal LHS and RHS to the add. They
- /// produce two results: the normal result of the add, and a boolean that
- /// indicates if an overflow occurred (*not* a flag, because it may be store
- /// to memory, etc.). If the type of the boolean is not i1 then the high
- /// bits conform to getBooleanContents.
- /// These nodes are generated from llvm.[su]add.with.overflow intrinsics.
- SADDO, UADDO,
-
- /// Same for subtraction.
- SSUBO, USUBO,
-
- /// Same for multiplication.
- SMULO, UMULO,
-
- /// RESULT = [US]ADDSAT(LHS, RHS) - Perform saturation addition on 2
- /// integers with the same bit width (W). If the true value of LHS + RHS
- /// exceeds the largest value that can be represented by W bits, the
- /// resulting value is this maximum value. Otherwise, if this value is less
- /// than the smallest value that can be represented by W bits, the
- /// resulting value is this minimum value.
- SADDSAT, UADDSAT,
-
- /// RESULT = [US]SUBSAT(LHS, RHS) - Perform saturation subtraction on 2
- /// integers with the same bit width (W). If the true value of LHS - RHS
- /// exceeds the largest value that can be represented by W bits, the
- /// resulting value is this maximum value. Otherwise, if this value is less
- /// than the smallest value that can be represented by W bits, the
- /// resulting value is this minimum value.
- SSUBSAT, USUBSAT,
-
- /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point multiplication on
- /// 2 integers with the same width and scale. SCALE represents the scale of
- /// both operands as fixed point numbers. This SCALE parameter must be a
- /// constant integer. A scale of zero is effectively performing
- /// multiplication on 2 integers.
- SMULFIX, UMULFIX,
-
- /// Same as the corresponding unsaturated fixed point instructions, but the
- /// result is clamped between the min and max values representable by the
- /// bits of the first 2 operands.
- SMULFIXSAT, UMULFIXSAT,
-
- /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
- /// 2 integers with the same width and scale. SCALE represents the scale
- /// of both operands as fixed point numbers. This SCALE parameter must be a
- /// constant integer.
- SDIVFIX, UDIVFIX,
-
- /// Simple binary floating point operators.
- FADD, FSUB, FMUL, FDIV, FREM,
-
- /// Constrained versions of the binary floating point operators.
- /// These will be lowered to the simple operators before final selection.
- /// They are used to limit optimizations while the DAG is being
- /// optimized.
- STRICT_FADD, STRICT_FSUB, STRICT_FMUL, STRICT_FDIV, STRICT_FREM,
- STRICT_FMA,
-
- /// Constrained versions of libm-equivalent floating point intrinsics.
- /// These will be lowered to the equivalent non-constrained pseudo-op
- /// (or expanded to the equivalent library call) before final selection.
- /// They are used to limit optimizations while the DAG is being optimized.
- STRICT_FSQRT, STRICT_FPOW, STRICT_FPOWI, STRICT_FSIN, STRICT_FCOS,
- STRICT_FEXP, STRICT_FEXP2, STRICT_FLOG, STRICT_FLOG10, STRICT_FLOG2,
- STRICT_FRINT, STRICT_FNEARBYINT, STRICT_FMAXNUM, STRICT_FMINNUM,
- STRICT_FCEIL, STRICT_FFLOOR, STRICT_FROUND, STRICT_FTRUNC,
- STRICT_LROUND, STRICT_LLROUND, STRICT_LRINT, STRICT_LLRINT,
- STRICT_FMAXIMUM, STRICT_FMINIMUM,
-
- /// STRICT_FP_TO_[US]INT - Convert a floating point value to a signed or
- /// unsigned integer. These have the same semantics as fptosi and fptoui
- /// in IR.
- /// They are used to limit optimizations while the DAG is being optimized.
- STRICT_FP_TO_SINT,
- STRICT_FP_TO_UINT,
-
- /// STRICT_[US]INT_TO_FP - Convert a signed or unsigned integer to
- /// a floating point value. These have the same semantics as sitofp and
- /// uitofp in IR.
- /// They are used to limit optimizations while the DAG is being optimized.
- STRICT_SINT_TO_FP,
- STRICT_UINT_TO_FP,
-
- /// X = STRICT_FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating
- /// point type down to the precision of the destination VT. TRUNC is a
- /// flag, which is always an integer that is zero or one. If TRUNC is 0,
- /// this is a normal rounding, if it is 1, this FP_ROUND is known to not
- /// change the value of Y.
- ///
- /// The TRUNC = 1 case is used in cases where we know that the value will
- /// not be modified by the node, because Y is not using any of the extra
- /// precision of source type. This allows certain transformations like
- /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,1)) -> X which are not safe for
- /// STRICT_FP_EXTEND(STRICT_FP_ROUND(X,0)) because the extra bits aren't
- /// removed.
- /// It is used to limit optimizations while the DAG is being optimized.
- STRICT_FP_ROUND,
-
- /// X = STRICT_FP_EXTEND(Y) - Extend a smaller FP type into a larger FP
- /// type.
- /// It is used to limit optimizations while the DAG is being optimized.
- STRICT_FP_EXTEND,
-
- /// STRICT_FSETCC/STRICT_FSETCCS - Constrained versions of SETCC, used
- /// for floating-point operands only. STRICT_FSETCC performs a quiet
- /// comparison operation, while STRICT_FSETCCS performs a signaling
- /// comparison operation.
- STRICT_FSETCC, STRICT_FSETCCS,
-
- /// FMA - Perform a * b + c with no intermediate rounding step.
- FMA,
-
- /// FMAD - Perform a * b + c, while getting the same result as the
- /// separately rounded operations.
- FMAD,
-
- /// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
- /// DAG node does not require that X and Y have the same type, just that
- /// they are both floating point. X and the result must have the same type.
- /// FCOPYSIGN(f32, f64) is allowed.
- FCOPYSIGN,
-
- /// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
- /// value as an integer 0/1 value.
- FGETSIGN,
-
- /// Returns platform specific canonical encoding of a floating point number.
- FCANONICALIZE,
-
- /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
- /// specified, possibly variable, elements. The number of elements is
- /// required to be a power of two. The types of the operands must all be
- /// the same and must match the vector element type, except that integer
- /// types are allowed to be larger than the element type, in which case
- /// the operands are implicitly truncated.
- BUILD_VECTOR,
-
- /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
- /// at IDX replaced with VAL. If the type of VAL is larger than the vector
- /// element type then VAL is truncated before replacement.
- INSERT_VECTOR_ELT,
-
- /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
- /// identified by the (potentially variable) element number IDX. If the
- /// return type is an integer type larger than the element type of the
- /// vector, the result is extended to the width of the return type. In
- /// that case, the high bits are undefined.
- EXTRACT_VECTOR_ELT,
-
- /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
- /// vector type with the same length and element type, this produces a
- /// concatenated vector result value, with length equal to the sum of the
- /// lengths of the input vectors.
- CONCAT_VECTORS,
-
- /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector
- /// with VECTOR2 inserted into VECTOR1 at the (potentially
- /// variable) element number IDX, which must be a multiple of the
- /// VECTOR2 vector length. The elements of VECTOR1 starting at
- /// IDX are overwritten with VECTOR2. Elements IDX through
- /// vector_length(VECTOR2) must be valid VECTOR1 indices.
- INSERT_SUBVECTOR,
-
- /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
- /// vector value) starting with the element number IDX, which must be a
- /// constant multiple of the result vector length.
- EXTRACT_SUBVECTOR,
-
- /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
- /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
- /// values that indicate which value (or undef) each result element will
- /// get. These constant ints are accessible through the
- /// ShuffleVectorSDNode class. This is quite similar to the Altivec
- /// 'vperm' instruction, except that the indices must be constants and are
- /// in terms of the element size of VEC1/VEC2, not in terms of bytes.
- VECTOR_SHUFFLE,
-
- /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
- /// scalar value into element 0 of the resultant vector type. The top
- /// elements 1 to N-1 of the N-element vector are undefined. The type
- /// of the operand must match the vector element type, except when they
- /// are integer types. In this case the operand is allowed to be wider
- /// than the vector element type, and is implicitly truncated to it.
- SCALAR_TO_VECTOR,
-
- /// SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL
- /// duplicated in all lanes. The type of the operand must match the vector
- /// element type, except when they are integer types. In this case the
- /// operand is allowed to be wider than the vector element type, and is
- /// implicitly truncated to it.
- SPLAT_VECTOR,
-
- /// MULHU/MULHS - Multiply high - Multiply two integers of type iN,
- /// producing an unsigned/signed value of type i[2*N], then return the top
- /// part.
- MULHU, MULHS,
-
- /// [US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned
- /// integers.
- SMIN, SMAX, UMIN, UMAX,
-
- /// Bitwise operators - logical and, logical or, logical xor.
- AND, OR, XOR,
-
- /// ABS - Determine the unsigned absolute value of a signed integer value of
- /// the same bitwidth.
- /// Note: A value of INT_MIN will return INT_MIN, no saturation or overflow
- /// is performed.
- ABS,
-
- /// Shift and rotation operations. After legalization, the type of the
- /// shift amount is known to be TLI.getShiftAmountTy(). Before legalization
- /// the shift amount can be any type, but care must be taken to ensure it is
- /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before
- /// legalization, types like i1024 can occur and i8 doesn't have enough bits
- /// to represent the shift amount.
- /// When the 1st operand is a vector, the shift amount must be in the same
- /// type. (TLI.getShiftAmountTy() will return the same type when the input
- /// type is a vector.)
- /// For rotates and funnel shifts, the shift amount is treated as an unsigned
- /// amount modulo the element size of the first operand.
- ///
- /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
- /// fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
- /// fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW))
- SHL, SRA, SRL, ROTL, ROTR, FSHL, FSHR,
-
- /// Byte Swap and Counting operators.
- BSWAP, CTTZ, CTLZ, CTPOP, BITREVERSE,
-
- /// Bit counting operators with an undefined result for zero inputs.
- CTTZ_ZERO_UNDEF, CTLZ_ZERO_UNDEF,
-
- /// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
- /// i1 then the high bits must conform to getBooleanContents.
- SELECT,
-
- /// Select with a vector condition (op #0) and two vector operands (ops #1
- /// and #2), returning a vector result. All vectors have the same length.
- /// Much like the scalar select and setcc, each bit in the condition selects
- /// whether the corresponding result element is taken from op #1 or op #2.
- /// At first, the VSELECT condition is of vXi1 type. Later, targets may
- /// change the condition type in order to match the VSELECT node using a
- /// pattern. The condition follows the BooleanContent format of the target.
- VSELECT,
-
- /// Select with condition operator - This selects between a true value and
- /// a false value (ops #2 and #3) based on the boolean result of comparing
- /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
- /// condition code in op #4, a CondCodeSDNode.
- SELECT_CC,
-
- /// SetCC operator - This evaluates to a true value iff the condition is
- /// true. If the result value type is not i1 then the high bits conform
- /// to getBooleanContents. The operands to this are the left and right
- /// operands to compare (ops #0, and #1) and the condition code to compare
- /// them with (op #2) as a CondCodeSDNode. If the operands are vector types
- /// then the result type must also be a vector type.
- SETCC,
-
- /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but
- /// op #2 is a boolean indicating if there is an incoming carry. This
- /// operator checks the result of "LHS - RHS - Carry", and can be used to
- /// compare two wide integers:
- /// (setcccarry lhshi rhshi (subcarry lhslo rhslo) cc).
- /// Only valid for integers.
- SETCCCARRY,
-
- /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
- /// integer shift operations. The operation ordering is:
- /// [Lo,Hi] = op [LoLHS,HiLHS], Amt
- SHL_PARTS, SRA_PARTS, SRL_PARTS,
-
- /// Conversion operators. These are all single input single output
- /// operations. For all of these, the result type must be strictly
- /// wider or narrower (depending on the operation) than the source
- /// type.
-
- /// SIGN_EXTEND - Used for integer types, replicating the sign bit
- /// into new bits.
- SIGN_EXTEND,
-
- /// ZERO_EXTEND - Used for integer types, zeroing the new bits.
- ZERO_EXTEND,
-
- /// ANY_EXTEND - Used for integer types. The high bits are undefined.
- ANY_EXTEND,
-
- /// TRUNCATE - Completely drop the high bits.
- TRUNCATE,
-
- /// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
- /// depends on the first letter) to floating point.
- SINT_TO_FP,
- UINT_TO_FP,
-
- /// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
- /// sign extend a small value in a large integer register (e.g. sign
- /// extending the low 8 bits of a 32-bit register to fill the top 24 bits
- /// with the 7th bit). The size of the smaller type is indicated by the 1th
- /// operand, a ValueType node.
- SIGN_EXTEND_INREG,
-
- /// ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an
- /// in-register any-extension of the low lanes of an integer vector. The
- /// result type must have fewer elements than the operand type, and those
- /// elements must be larger integer types such that the total size of the
- /// operand type is less than or equal to the size of the result type. Each
- /// of the low operand elements is any-extended into the corresponding,
- /// wider result elements with the high bits becoming undef.
- /// NOTE: The type legalizer prefers to make the operand and result size
- /// the same to allow expansion to shuffle vector during op legalization.
- ANY_EXTEND_VECTOR_INREG,
-
- /// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an
- /// in-register sign-extension of the low lanes of an integer vector. The
- /// result type must have fewer elements than the operand type, and those
- /// elements must be larger integer types such that the total size of the
- /// operand type is less than or equal to the size of the result type. Each
- /// of the low operand elements is sign-extended into the corresponding,
- /// wider result elements.
- /// NOTE: The type legalizer prefers to make the operand and result size
- /// the same to allow expansion to shuffle vector during op legalization.
- SIGN_EXTEND_VECTOR_INREG,
-
- /// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an
- /// in-register zero-extension of the low lanes of an integer vector. The
- /// result type must have fewer elements than the operand type, and those
- /// elements must be larger integer types such that the total size of the
- /// operand type is less than or equal to the size of the result type. Each
- /// of the low operand elements is zero-extended into the corresponding,
- /// wider result elements.
- /// NOTE: The type legalizer prefers to make the operand and result size
- /// the same to allow expansion to shuffle vector during op legalization.
- ZERO_EXTEND_VECTOR_INREG,
-
- /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
- /// integer. These have the same semantics as fptosi and fptoui in IR. If
- /// the FP value cannot fit in the integer type, the results are undefined.
- FP_TO_SINT,
- FP_TO_UINT,
-
- /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
- /// down to the precision of the destination VT. TRUNC is a flag, which is
- /// always an integer that is zero or one. If TRUNC is 0, this is a
- /// normal rounding, if it is 1, this FP_ROUND is known to not change the
- /// value of Y.
- ///
- /// The TRUNC = 1 case is used in cases where we know that the value will
- /// not be modified by the node, because Y is not using any of the extra
- /// precision of source type. This allows certain transformations like
- /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
- /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
- FP_ROUND,
-
- /// FLT_ROUNDS_ - Returns current rounding mode:
- /// -1 Undefined
- /// 0 Round to 0
- /// 1 Round to nearest
- /// 2 Round to +inf
- /// 3 Round to -inf
- FLT_ROUNDS_,
-
- /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
- FP_EXTEND,
-
- /// BITCAST - This operator converts between integer, vector and FP
- /// values, as if the value was stored to memory with one type and loaded
- /// from the same address with the other type (or equivalently for vector
- /// format conversions, etc). The source and result are required to have
- /// the same bit size (e.g. f32 <-> i32). This can also be used for
- /// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
- /// getNode().
- ///
- /// This operator is subtly different from the bitcast instruction from
- /// LLVM-IR since this node may change the bits in the register. For
- /// example, this occurs on big-endian NEON and big-endian MSA where the
- /// layout of the bits in the register depends on the vector type and this
- /// operator acts as a shuffle operation for some vector type combinations.
- BITCAST,
-
- /// ADDRSPACECAST - This operator converts between pointers of different
- /// address spaces.
- ADDRSPACECAST,
-
- /// FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions
- /// and truncation for half-precision (16 bit) floating numbers. These nodes
- /// form a semi-softened interface for dealing with f16 (as an i16), which
- /// is often a storage-only type but has native conversions.
- FP16_TO_FP, FP_TO_FP16,
-
- /// Perform various unary floating-point operations inspired by libm. For
- /// FPOWI, the result is undefined if if the integer operand doesn't fit
- /// into 32 bits.
- FNEG, FABS, FSQRT, FCBRT, FSIN, FCOS, FPOWI, FPOW,
- FLOG, FLOG2, FLOG10, FEXP, FEXP2,
- FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR,
- LROUND, LLROUND, LRINT, LLRINT,
-
- /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
- /// values.
- //
- /// In the case where a single input is a NaN (either signaling or quiet),
- /// the non-NaN input is returned.
- ///
- /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
- FMINNUM, FMAXNUM,
-
- /// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
- /// two values, following the IEEE-754 2008 definition. This differs from
- /// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
- /// signaling NaN, returns a quiet NaN.
- FMINNUM_IEEE, FMAXNUM_IEEE,
-
- /// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
- /// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
- /// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
- FMINIMUM, FMAXIMUM,
-
- /// FSINCOS - Compute both fsin and fcos as a single operation.
- FSINCOS,
-
- /// LOAD and STORE have token chains as their first operand, then the same
- /// operands as an LLVM load/store instruction, then an offset node that
- /// is added / subtracted from the base pointer to form the address (for
- /// indexed memory ops).
- LOAD, STORE,
-
- /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
- /// to a specified boundary. This node always has two return values: a new
- /// stack pointer value and a chain. The first operand is the token chain,
- /// the second is the number of bytes to allocate, and the third is the
- /// alignment boundary. The size is guaranteed to be a multiple of the
- /// stack alignment, and the alignment is guaranteed to be bigger than the
- /// stack alignment (if required) or 0 to get standard stack alignment.
- DYNAMIC_STACKALLOC,
-
- /// Control flow instructions. These all have token chains.
-
- /// BR - Unconditional branch. The first operand is the chain
- /// operand, the second is the MBB to branch to.
- BR,
-
- /// BRIND - Indirect branch. The first operand is the chain, the second
- /// is the value to branch to, which must be of the same type as the
- /// target's pointer type.
- BRIND,
-
- /// BR_JT - Jumptable branch. The first operand is the chain, the second
- /// is the jumptable index, the last one is the jumptable entry index.
- BR_JT,
-
- /// BRCOND - Conditional branch. The first operand is the chain, the
- /// second is the condition, the third is the block to branch to if the
- /// condition is true. If the type of the condition is not i1, then the
- /// high bits must conform to getBooleanContents.
- BRCOND,
-
- /// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
- /// that the condition is represented as condition code, and two nodes to
- /// compare, rather than as a combined SetCC node. The operands in order
- /// are chain, cc, lhs, rhs, block to branch to if condition is true.
- BR_CC,
-
- /// INLINEASM - Represents an inline asm block. This node always has two
- /// return values: a chain and a flag result. The inputs are as follows:
- /// Operand #0 : Input chain.
- /// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
- /// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
- /// Operand #3 : HasSideEffect, IsAlignStack bits.
- /// After this, it is followed by a list of operands with this format:
- /// ConstantSDNode: Flags that encode whether it is a mem or not, the
- /// of operands that follow, etc. See InlineAsm.h.
- /// ... however many operands ...
- /// Operand #last: Optional, an incoming flag.
- ///
- /// The variable width operands are required to represent target addressing
- /// modes as a single "operand", even though they may have multiple
- /// SDOperands.
- INLINEASM,
-
- /// INLINEASM_BR - Terminator version of inline asm. Used by asm-goto.
- INLINEASM_BR,
-
- /// EH_LABEL - Represents a label in mid basic block used to track
- /// locations needed for debug and exception handling tables. These nodes
- /// take a chain as input and return a chain.
- EH_LABEL,
-
- /// ANNOTATION_LABEL - Represents a mid basic block label used by
- /// annotations. This should remain within the basic block and be ordered
- /// with respect to other call instructions, but loads and stores may float
- /// past it.
- ANNOTATION_LABEL,
-
- /// CATCHPAD - Represents a catchpad instruction.
- CATCHPAD,
-
- /// CATCHRET - Represents a return from a catch block funclet. Used for
- /// MSVC compatible exception handling. Takes a chain operand and a
- /// destination basic block operand.
- CATCHRET,
-
- /// CLEANUPRET - Represents a return from a cleanup block funclet. Used for
- /// MSVC compatible exception handling. Takes only a chain operand.
- CLEANUPRET,
-
- /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
- /// value, the same type as the pointer type for the system, and an output
- /// chain.
- STACKSAVE,
-
- /// STACKRESTORE has two operands, an input chain and a pointer to restore
- /// to it returns an output chain.
- STACKRESTORE,
-
- /// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end
- /// of a call sequence, and carry arbitrary information that target might
- /// want to know. The first operand is a chain, the rest are specified by
- /// the target and not touched by the DAG optimizers.
- /// Targets that may use stack to pass call arguments define additional
- /// operands:
- /// - size of the call frame part that must be set up within the
- /// CALLSEQ_START..CALLSEQ_END pair,
- /// - part of the call frame prepared prior to CALLSEQ_START.
- /// Both these parameters must be constants, their sum is the total call
- /// frame size.
- /// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
- CALLSEQ_START, // Beginning of a call sequence
- CALLSEQ_END, // End of a call sequence
-
- /// VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
- /// and the alignment. It returns a pair of values: the vaarg value and a
- /// new chain.
- VAARG,
-
- /// VACOPY - VACOPY has 5 operands: an input chain, a destination pointer,
- /// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
- /// source.
- VACOPY,
-
- /// VAEND, VASTART - VAEND and VASTART have three operands: an input chain,
- /// pointer, and a SRCVALUE.
- VAEND, VASTART,
-
- /// SRCVALUE - This is a node type that holds a Value* that is used to
- /// make reference to a value in the LLVM IR.
- SRCVALUE,
-
- /// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
- /// reference metadata in the IR.
- MDNODE_SDNODE,
-
- /// PCMARKER - This corresponds to the pcmarker intrinsic.
- PCMARKER,
-
- /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
- /// It produces a chain and one i64 value. The only operand is a chain.
- /// If i64 is not legal, the result will be expanded into smaller values.
- /// Still, it returns an i64, so targets should set legality for i64.
- /// The result is the content of the architecture-specific cycle
- /// counter-like register (or other high accuracy low latency clock source).
- READCYCLECOUNTER,
-
- /// HANDLENODE node - Used as a handle for various purposes.
- HANDLENODE,
-
- /// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
- /// takes as input a token chain, the pointer to the trampoline, the pointer
- /// to the nested function, the pointer to pass for the 'nest' parameter, a
- /// SRCVALUE for the trampoline and another for the nested function
- /// (allowing targets to access the original Function*).
- /// It produces a token chain as output.
- INIT_TRAMPOLINE,
-
- /// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
- /// It takes a pointer to the trampoline and produces a (possibly) new
- /// pointer to the same trampoline with platform-specific adjustments
- /// applied. The pointer it returns points to an executable block of code.
- ADJUST_TRAMPOLINE,
-
- /// TRAP - Trapping instruction
- TRAP,
-
- /// DEBUGTRAP - Trap intended to get the attention of a debugger.
- DEBUGTRAP,
-
- /// PREFETCH - This corresponds to a prefetch intrinsic. The first operand
- /// is the chain. The other operands are the address to prefetch,
- /// read / write specifier, locality specifier and instruction / data cache
- /// specifier.
- PREFETCH,
-
- /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
- /// This corresponds to the fence instruction. It takes an input chain, and
- /// two integer constants: an AtomicOrdering and a SynchronizationScope.
- ATOMIC_FENCE,
-
- /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
- /// This corresponds to "load atomic" instruction.
- ATOMIC_LOAD,
-
- /// OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val)
- /// This corresponds to "store atomic" instruction.
- ATOMIC_STORE,
-
- /// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
- /// For double-word atomic operations:
- /// ValLo, ValHi, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmpLo, cmpHi,
- /// swapLo, swapHi)
- /// This corresponds to the cmpxchg instruction.
- ATOMIC_CMP_SWAP,
-
- /// Val, Success, OUTCHAIN
- /// = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap)
- /// N.b. this is still a strong cmpxchg operation, so
- /// Success == "Val == cmp".
- ATOMIC_CMP_SWAP_WITH_SUCCESS,
-
- /// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
- /// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
- /// For double-word atomic operations:
- /// ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi)
- /// ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi)
- /// These correspond to the atomicrmw instruction.
- ATOMIC_SWAP,
- ATOMIC_LOAD_ADD,
- ATOMIC_LOAD_SUB,
- ATOMIC_LOAD_AND,
- ATOMIC_LOAD_CLR,
- ATOMIC_LOAD_OR,
- ATOMIC_LOAD_XOR,
- ATOMIC_LOAD_NAND,
- ATOMIC_LOAD_MIN,
- ATOMIC_LOAD_MAX,
- ATOMIC_LOAD_UMIN,
- ATOMIC_LOAD_UMAX,
- ATOMIC_LOAD_FADD,
- ATOMIC_LOAD_FSUB,
-
- // Masked load and store - consecutive vector load and store operations
- // with additional mask operand that prevents memory accesses to the
- // masked-off lanes.
- //
- // Val, OutChain = MLOAD(BasePtr, Mask, PassThru)
- // OutChain = MSTORE(Value, BasePtr, Mask)
- MLOAD, MSTORE,
-
- // Masked gather and scatter - load and store operations for a vector of
- // random addresses with additional mask operand that prevents memory
- // accesses to the masked-off lanes.
- //
- // Val, OutChain = GATHER(InChain, PassThru, Mask, BasePtr, Index, Scale)
- // OutChain = SCATTER(InChain, Value, Mask, BasePtr, Index, Scale)
- //
- // The Index operand can have more vector elements than the other operands
- // due to type legalization. The extra elements are ignored.
- MGATHER, MSCATTER,
-
- /// This corresponds to the llvm.lifetime.* intrinsics. The first operand
- /// is the chain and the second operand is the alloca pointer.
- LIFETIME_START, LIFETIME_END,
-
- /// GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the
- /// beginning and end of GC transition sequence, and carry arbitrary
- /// information that target might need for lowering. The first operand is
- /// a chain, the rest are specified by the target and not touched by the DAG
- /// optimizers. GC_TRANSITION_START..GC_TRANSITION_END pairs may not be
- /// nested.
- GC_TRANSITION_START,
- GC_TRANSITION_END,
-
- /// GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of
- /// the most recent dynamic alloca. For most targets that would be 0, but
- /// for some others (e.g. PowerPC, PowerPC64) that would be compile-time
- /// known nonzero constant. The only operand here is the chain.
- GET_DYNAMIC_AREA_OFFSET,
-
- /// Generic reduction nodes. These nodes represent horizontal vector
- /// reduction operations, producing a scalar result.
- /// The STRICT variants perform reductions in sequential order. The first
- /// operand is an initial scalar accumulator value, and the second operand
- /// is the vector to reduce.
- VECREDUCE_STRICT_FADD, VECREDUCE_STRICT_FMUL,
- /// These reductions are non-strict, and have a single vector operand.
- VECREDUCE_FADD, VECREDUCE_FMUL,
- /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
- VECREDUCE_FMAX, VECREDUCE_FMIN,
- /// Integer reductions may have a result type larger than the vector element
- /// type. However, the reduction is performed using the vector element type
- /// and the value in the top bits is unspecified.
- VECREDUCE_ADD, VECREDUCE_MUL,
- VECREDUCE_AND, VECREDUCE_OR, VECREDUCE_XOR,
- VECREDUCE_SMAX, VECREDUCE_SMIN, VECREDUCE_UMAX, VECREDUCE_UMIN,
-
- /// BUILTIN_OP_END - This must be the last enum value in this list.
- /// The target-specific pre-isel opcode values start here.
- BUILTIN_OP_END
- };
-
- /// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations
- /// which cannot raise FP exceptions should be less than this value.
- /// Those that do must not be less than this value.
- static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END+400;
-
- /// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
- /// which do not reference a specific memory location should be less than
- /// this value. Those that do must not be less than this value, and can
- /// be used with SelectionDAG::getMemIntrinsicNode.
- static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+500;
-
- //===--------------------------------------------------------------------===//
- /// MemIndexedMode enum - This enum defines the load / store indexed
- /// addressing modes.
+ /// If VECTOR is a scalable vector, then IDX may be larger than the minimum
+ /// vector width. IDX is not first scaled by the runtime scaling factor of
+ /// VECTOR.
+ EXTRACT_VECTOR_ELT,
+
+ /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
+ /// vector type with the same length and element type, this produces a
+ /// concatenated vector result value, with length equal to the sum of the
+ /// lengths of the input vectors. If VECTOR0 is a fixed-width vector, then
+ /// VECTOR1..VECTORN must all be fixed-width vectors. Similarly, if VECTOR0
+ /// is a scalable vector, then VECTOR1..VECTORN must all be scalable vectors.
+ CONCAT_VECTORS,
+
+ /// INSERT_SUBVECTOR(VECTOR1, VECTOR2, IDX) - Returns a vector with VECTOR2
+ /// inserted into VECTOR1. IDX represents the starting element number at which
+ /// VECTOR2 will be inserted. IDX must be a constant multiple of T's known
+ /// minimum vector length. Let the type of VECTOR2 be T, then if T is a
+ /// scalable vector, IDX is first scaled by the runtime scaling factor of T.
+ /// The elements of VECTOR1 starting at IDX are overwritten with VECTOR2.
+ /// Elements IDX through (IDX + num_elements(T) - 1) must be valid VECTOR1
+ /// indices. If this condition cannot be determined statically but is false at
+ /// runtime, then the result vector is undefined.
///
- /// UNINDEXED "Normal" load / store. The effective address is already
- /// computed and is available in the base pointer. The offset
- /// operand is always undefined. In addition to producing a
- /// chain, an unindexed load produces one value (result of the
- /// load); an unindexed store does not produce a value.
+ /// This operation supports inserting a fixed-width vector into a scalable
+ /// vector, but not the other way around.
+ INSERT_SUBVECTOR,
+
+ /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR.
+ /// Let the result type be T, then IDX represents the starting element number
+ /// from which a subvector of type T is extracted. IDX must be a constant
+ /// multiple of T's known minimum vector length. If T is a scalable vector,
+ /// IDX is first scaled by the runtime scaling factor of T. Elements IDX
+ /// through (IDX + num_elements(T) - 1) must be valid VECTOR indices. If this
+ /// condition cannot be determined statically but is false at runtime, then
+ /// the result vector is undefined.
///
- /// PRE_INC Similar to the unindexed mode where the effective address is
- /// PRE_DEC the value of the base pointer add / subtract the offset.
- /// It considers the computation as being folded into the load /
- /// store operation (i.e. the load / store does the address
- /// computation as well as performing the memory transaction).
- /// The base operand is always undefined. In addition to
- /// producing a chain, pre-indexed load produces two values
- /// (result of the load and the result of the address
- /// computation); a pre-indexed store produces one value (result
- /// of the address computation).
+ /// This operation supports extracting a fixed-width vector from a scalable
+ /// vector, but not the other way around.
+ EXTRACT_SUBVECTOR,
+
+ /// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
+ /// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
+ /// values that indicate which value (or undef) each result element will
+ /// get. These constant ints are accessible through the
+ /// ShuffleVectorSDNode class. This is quite similar to the Altivec
+ /// 'vperm' instruction, except that the indices must be constants and are
+ /// in terms of the element size of VEC1/VEC2, not in terms of bytes.
+ VECTOR_SHUFFLE,
+
+ /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+ /// scalar value into element 0 of the resultant vector type. The top
+ /// elements 1 to N-1 of the N-element vector are undefined. The type
+ /// of the operand must match the vector element type, except when they
+ /// are integer types. In this case the operand is allowed to be wider
+ /// than the vector element type, and is implicitly truncated to it.
+ SCALAR_TO_VECTOR,
+
+ /// SPLAT_VECTOR(VAL) - Returns a vector with the scalar value VAL
+ /// duplicated in all lanes. The type of the operand must match the vector
+ /// element type, except when they are integer types. In this case the
+ /// operand is allowed to be wider than the vector element type, and is
+ /// implicitly truncated to it.
+ SPLAT_VECTOR,
+
+ /// MULHU/MULHS - Multiply high - Multiply two integers of type iN,
+ /// producing an unsigned/signed value of type i[2*N], then return the top
+ /// part.
+ MULHU,
+ MULHS,
+
+ /// [US]{MIN/MAX} - Binary minimum or maximum or signed or unsigned
+ /// integers.
+ SMIN,
+ SMAX,
+ UMIN,
+ UMAX,
+
+ /// Bitwise operators - logical and, logical or, logical xor.
+ AND,
+ OR,
+ XOR,
+
+ /// ABS - Determine the unsigned absolute value of a signed integer value of
+ /// the same bitwidth.
+ /// Note: A value of INT_MIN will return INT_MIN, no saturation or overflow
+ /// is performed.
+ ABS,
+
+ /// Shift and rotation operations. After legalization, the type of the
+ /// shift amount is known to be TLI.getShiftAmountTy(). Before legalization
+ /// the shift amount can be any type, but care must be taken to ensure it is
+ /// large enough. TLI.getShiftAmountTy() is i8 on some targets, but before
+ /// legalization, types like i1024 can occur and i8 doesn't have enough bits
+ /// to represent the shift amount.
+ /// When the 1st operand is a vector, the shift amount must be in the same
+ /// type. (TLI.getShiftAmountTy() will return the same type when the input
+ /// type is a vector.)
+ /// For rotates and funnel shifts, the shift amount is treated as an unsigned
+ /// amount modulo the element size of the first operand.
///
- /// POST_INC The effective address is the value of the base pointer. The
- /// POST_DEC value of the offset operand is then added to / subtracted
- /// from the base after memory transaction. In addition to
- /// producing a chain, post-indexed load produces two values
- /// (the result of the load and the result of the base +/- offset
- /// computation); a post-indexed store produces one value (the
- /// the result of the base +/- offset computation).
- enum MemIndexedMode {
- UNINDEXED = 0,
- PRE_INC,
- PRE_DEC,
- POST_INC,
- POST_DEC
- };
-
- static const int LAST_INDEXED_MODE = POST_DEC + 1;
-
- //===--------------------------------------------------------------------===//
- /// MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's
- /// index parameter when calculating addresses.
+ /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
+ /// fshl(X,Y,Z): (X << (Z % BW)) | (Y >> (BW - (Z % BW)))
+ /// fshr(X,Y,Z): (X << (BW - (Z % BW))) | (Y >> (Z % BW))
+ SHL,
+ SRA,
+ SRL,
+ ROTL,
+ ROTR,
+ FSHL,
+ FSHR,
+
+ /// Byte Swap and Counting operators.
+ BSWAP,
+ CTTZ,
+ CTLZ,
+ CTPOP,
+ BITREVERSE,
+
+ /// Bit counting operators with an undefined result for zero inputs.
+ CTTZ_ZERO_UNDEF,
+ CTLZ_ZERO_UNDEF,
+
+ /// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
+ /// i1 then the high bits must conform to getBooleanContents.
+ SELECT,
+
+ /// Select with a vector condition (op #0) and two vector operands (ops #1
+ /// and #2), returning a vector result. All vectors have the same length.
+ /// Much like the scalar select and setcc, each bit in the condition selects
+ /// whether the corresponding result element is taken from op #1 or op #2.
+ /// At first, the VSELECT condition is of vXi1 type. Later, targets may
+ /// change the condition type in order to match the VSELECT node using a
+ /// pattern. The condition follows the BooleanContent format of the target.
+ VSELECT,
+
+ /// Select with condition operator - This selects between a true value and
+ /// a false value (ops #2 and #3) based on the boolean result of comparing
+ /// the lhs and rhs (ops #0 and #1) of a conditional expression with the
+ /// condition code in op #4, a CondCodeSDNode.
+ SELECT_CC,
+
+ /// SetCC operator - This evaluates to a true value iff the condition is
+ /// true. If the result value type is not i1 then the high bits conform
+ /// to getBooleanContents. The operands to this are the left and right
+ /// operands to compare (ops #0, and #1) and the condition code to compare
+ /// them with (op #2) as a CondCodeSDNode. If the operands are vector types
+ /// then the result type must also be a vector type.
+ SETCC,
+
+ /// Like SetCC, ops #0 and #1 are the LHS and RHS operands to compare, but
+ /// op #2 is a boolean indicating if there is an incoming carry. This
+ /// operator checks the result of "LHS - RHS - Carry", and can be used to
+ /// compare two wide integers:
+ /// (setcccarry lhshi rhshi (subcarry lhslo rhslo) cc).
+ /// Only valid for integers.
+ SETCCCARRY,
+
+ /// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+ /// integer shift operations. The operation ordering is:
+ /// [Lo,Hi] = op [LoLHS,HiLHS], Amt
+ SHL_PARTS,
+ SRA_PARTS,
+ SRL_PARTS,
+
+ /// Conversion operators. These are all single input single output
+ /// operations. For all of these, the result type must be strictly
+ /// wider or narrower (depending on the operation) than the source
+ /// type.
+
+ /// SIGN_EXTEND - Used for integer types, replicating the sign bit
+ /// into new bits.
+ SIGN_EXTEND,
+
+ /// ZERO_EXTEND - Used for integer types, zeroing the new bits.
+ ZERO_EXTEND,
+
+ /// ANY_EXTEND - Used for integer types. The high bits are undefined.
+ ANY_EXTEND,
+
+ /// TRUNCATE - Completely drop the high bits.
+ TRUNCATE,
+
+ /// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+ /// depends on the first letter) to floating point.
+ SINT_TO_FP,
+ UINT_TO_FP,
+
+ /// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+ /// sign extend a small value in a large integer register (e.g. sign
+ /// extending the low 8 bits of a 32-bit register to fill the top 24 bits
+ /// with the 7th bit). The size of the smaller type is indicated by the 1th
+ /// operand, a ValueType node.
+ SIGN_EXTEND_INREG,
+
+ /// ANY_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register any-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is any-extended into the corresponding,
+ /// wider result elements with the high bits becoming undef.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
+ ANY_EXTEND_VECTOR_INREG,
+
+ /// SIGN_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register sign-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is sign-extended into the corresponding,
+ /// wider result elements.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
+ SIGN_EXTEND_VECTOR_INREG,
+
+ /// ZERO_EXTEND_VECTOR_INREG(Vector) - This operator represents an
+ /// in-register zero-extension of the low lanes of an integer vector. The
+ /// result type must have fewer elements than the operand type, and those
+ /// elements must be larger integer types such that the total size of the
+ /// operand type is less than or equal to the size of the result type. Each
+ /// of the low operand elements is zero-extended into the corresponding,
+ /// wider result elements.
+ /// NOTE: The type legalizer prefers to make the operand and result size
+ /// the same to allow expansion to shuffle vector during op legalization.
+ ZERO_EXTEND_VECTOR_INREG,
+
+ /// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
+ /// integer. These have the same semantics as fptosi and fptoui in IR. If
+ /// the FP value cannot fit in the integer type, the results are undefined.
+ FP_TO_SINT,
+ FP_TO_UINT,
+
+ /// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
+ /// down to the precision of the destination VT. TRUNC is a flag, which is
+ /// always an integer that is zero or one. If TRUNC is 0, this is a
+ /// normal rounding, if it is 1, this FP_ROUND is known to not change the
+ /// value of Y.
///
- /// SIGNED_SCALED Addr = Base + ((signed)Index * sizeof(element))
- /// SIGNED_UNSCALED Addr = Base + (signed)Index
- /// UNSIGNED_SCALED Addr = Base + ((unsigned)Index * sizeof(element))
- /// UNSIGNED_UNSCALED Addr = Base + (unsigned)Index
- enum MemIndexType {
- SIGNED_SCALED = 0,
- SIGNED_UNSCALED,
- UNSIGNED_SCALED,
- UNSIGNED_UNSCALED
- };
-
- static const int LAST_MEM_INDEX_TYPE = UNSIGNED_UNSCALED + 1;
-
- //===--------------------------------------------------------------------===//
- /// LoadExtType enum - This enum defines the three variants of LOADEXT
- /// (load with extension).
+ /// The TRUNC = 1 case is used in cases where we know that the value will
+ /// not be modified by the node, because Y is not using any of the extra
+ /// precision of source type. This allows certain transformations like
+ /// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
+ /// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
+ FP_ROUND,
+
+ /// FLT_ROUNDS_ - Returns current rounding mode:
+ /// -1 Undefined
+ /// 0 Round to 0
+ /// 1 Round to nearest
+ /// 2 Round to +inf
+ /// 3 Round to -inf
+ /// Result is rounding mode and chain. Input is a chain.
+ FLT_ROUNDS_,
+
+ /// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
+ FP_EXTEND,
+
+ /// BITCAST - This operator converts between integer, vector and FP
+ /// values, as if the value was stored to memory with one type and loaded
+ /// from the same address with the other type (or equivalently for vector
+ /// format conversions, etc). The source and result are required to have
+ /// the same bit size (e.g. f32 <-> i32). This can also be used for
+ /// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
+ /// getNode().
///
- /// SEXTLOAD loads the integer operand and sign extends it to a larger
- /// integer result type.
- /// ZEXTLOAD loads the integer operand and zero extends it to a larger
- /// integer result type.
- /// EXTLOAD is used for two things: floating point extending loads and
- /// integer extending loads [the top bits are undefined].
- enum LoadExtType {
- NON_EXTLOAD = 0,
- EXTLOAD,
- SEXTLOAD,
- ZEXTLOAD
- };
-
- static const int LAST_LOADEXT_TYPE = ZEXTLOAD + 1;
-
- NodeType getExtForLoadExtType(bool IsFP, LoadExtType);
-
- //===--------------------------------------------------------------------===//
- /// ISD::CondCode enum - These are ordered carefully to make the bitfields
- /// below work out, when considering SETFALSE (something that never exists
- /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
- /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
- /// to. If the "N" column is 1, the result of the comparison is undefined if
- /// the input is a NAN.
+ /// This operator is subtly different from the bitcast instruction from
+ /// LLVM-IR since this node may change the bits in the register. For
+ /// example, this occurs on big-endian NEON and big-endian MSA where the
+ /// layout of the bits in the register depends on the vector type and this
+ /// operator acts as a shuffle operation for some vector type combinations.
+ BITCAST,
+
+ /// ADDRSPACECAST - This operator converts between pointers of different
+ /// address spaces.
+ ADDRSPACECAST,
+
+ /// FP16_TO_FP, FP_TO_FP16 - These operators are used to perform promotions
+ /// and truncation for half-precision (16 bit) floating numbers. These nodes
+ /// form a semi-softened interface for dealing with f16 (as an i16), which
+ /// is often a storage-only type but has native conversions.
+ FP16_TO_FP,
+ FP_TO_FP16,
+ STRICT_FP16_TO_FP,
+ STRICT_FP_TO_FP16,
+
+ /// Perform various unary floating-point operations inspired by libm. For
+ /// FPOWI, the result is undefined if if the integer operand doesn't fit
+ /// into 32 bits.
+ FNEG,
+ FABS,
+ FSQRT,
+ FCBRT,
+ FSIN,
+ FCOS,
+ FPOWI,
+ FPOW,
+ FLOG,
+ FLOG2,
+ FLOG10,
+ FEXP,
+ FEXP2,
+ FCEIL,
+ FTRUNC,
+ FRINT,
+ FNEARBYINT,
+ FROUND,
+ FROUNDEVEN,
+ FFLOOR,
+ LROUND,
+ LLROUND,
+ LRINT,
+ LLRINT,
+
+ /// FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
+ /// values.
+ //
+ /// In the case where a single input is a NaN (either signaling or quiet),
+ /// the non-NaN input is returned.
///
- /// All of these (except for the 'always folded ops') should be handled for
- /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
- /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+ /// The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
+ FMINNUM,
+ FMAXNUM,
+
+ /// FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
+ /// two values, following the IEEE-754 2008 definition. This differs from
+ /// FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
+ /// signaling NaN, returns a quiet NaN.
+ FMINNUM_IEEE,
+ FMAXNUM_IEEE,
+
+ /// FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
+ /// as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
+ /// semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
+ FMINIMUM,
+ FMAXIMUM,
+
+ /// FSINCOS - Compute both fsin and fcos as a single operation.
+ FSINCOS,
+
+ /// LOAD and STORE have token chains as their first operand, then the same
+ /// operands as an LLVM load/store instruction, then an offset node that
+ /// is added / subtracted from the base pointer to form the address (for
+ /// indexed memory ops).
+ LOAD,
+ STORE,
+
+ /// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+ /// to a specified boundary. This node always has two return values: a new
+ /// stack pointer value and a chain. The first operand is the token chain,
+ /// the second is the number of bytes to allocate, and the third is the
+ /// alignment boundary. The size is guaranteed to be a multiple of the
+ /// stack alignment, and the alignment is guaranteed to be bigger than the
+ /// stack alignment (if required) or 0 to get standard stack alignment.
+ DYNAMIC_STACKALLOC,
+
+ /// Control flow instructions. These all have token chains.
+
+ /// BR - Unconditional branch. The first operand is the chain
+ /// operand, the second is the MBB to branch to.
+ BR,
+
+ /// BRIND - Indirect branch. The first operand is the chain, the second
+ /// is the value to branch to, which must be of the same type as the
+ /// target's pointer type.
+ BRIND,
+
+ /// BR_JT - Jumptable branch. The first operand is the chain, the second
+ /// is the jumptable index, the last one is the jumptable entry index.
+ BR_JT,
+
+ /// BRCOND - Conditional branch. The first operand is the chain, the
+ /// second is the condition, the third is the block to branch to if the
+ /// condition is true. If the type of the condition is not i1, then the
+ /// high bits must conform to getBooleanContents.
+ BRCOND,
+
+ /// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
+ /// that the condition is represented as condition code, and two nodes to
+ /// compare, rather than as a combined SetCC node. The operands in order
+ /// are chain, cc, lhs, rhs, block to branch to if condition is true.
+ BR_CC,
+
+ /// INLINEASM - Represents an inline asm block. This node always has two
+ /// return values: a chain and a flag result. The inputs are as follows:
+ /// Operand #0 : Input chain.
+ /// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ /// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
+ /// Operand #3 : HasSideEffect, IsAlignStack bits.
+ /// After this, it is followed by a list of operands with this format:
+ /// ConstantSDNode: Flags that encode whether it is a mem or not, the
+ /// of operands that follow, etc. See InlineAsm.h.
+ /// ... however many operands ...
+ /// Operand #last: Optional, an incoming flag.
///
- /// Note that these are laid out in a specific order to allow bit-twiddling
- /// to transform conditions.
- enum CondCode {
- // Opcode N U L G E Intuitive operation
- SETFALSE, // 0 0 0 0 Always false (always folded)
- SETOEQ, // 0 0 0 1 True if ordered and equal
- SETOGT, // 0 0 1 0 True if ordered and greater than
- SETOGE, // 0 0 1 1 True if ordered and greater than or equal
- SETOLT, // 0 1 0 0 True if ordered and less than
- SETOLE, // 0 1 0 1 True if ordered and less than or equal
- SETONE, // 0 1 1 0 True if ordered and operands are unequal
- SETO, // 0 1 1 1 True if ordered (no nans)
- SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
- SETUEQ, // 1 0 0 1 True if unordered or equal
- SETUGT, // 1 0 1 0 True if unordered or greater than
- SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
- SETULT, // 1 1 0 0 True if unordered or less than
- SETULE, // 1 1 0 1 True if unordered, less than, or equal
- SETUNE, // 1 1 1 0 True if unordered or not equal
- SETTRUE, // 1 1 1 1 Always true (always folded)
- // Don't care operations: undefined if the input is a nan.
- SETFALSE2, // 1 X 0 0 0 Always false (always folded)
- SETEQ, // 1 X 0 0 1 True if equal
- SETGT, // 1 X 0 1 0 True if greater than
- SETGE, // 1 X 0 1 1 True if greater than or equal
- SETLT, // 1 X 1 0 0 True if less than
- SETLE, // 1 X 1 0 1 True if less than or equal
- SETNE, // 1 X 1 1 0 True if not equal
- SETTRUE2, // 1 X 1 1 1 Always true (always folded)
-
- SETCC_INVALID // Marker value.
- };
-
- /// Return true if this is a setcc instruction that performs a signed
- /// comparison when used with integer operands.
- inline bool isSignedIntSetCC(CondCode Code) {
- return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
- }
-
- /// Return true if this is a setcc instruction that performs an unsigned
- /// comparison when used with integer operands.
- inline bool isUnsignedIntSetCC(CondCode Code) {
- return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
- }
-
- /// Return true if the specified condition returns true if the two operands to
- /// the condition are equal. Note that if one of the two operands is a NaN,
- /// this value is meaningless.
- inline bool isTrueWhenEqual(CondCode Cond) {
- return ((int)Cond & 1) != 0;
- }
-
- /// This function returns 0 if the condition is always false if an operand is
- /// a NaN, 1 if the condition is always true if the operand is a NaN, and 2 if
- /// the condition is undefined if the operand is a NaN.
- inline unsigned getUnorderedFlavor(CondCode Cond) {
- return ((int)Cond >> 3) & 3;
- }
-
- /// Return the operation corresponding to !(X op Y), where 'op' is a valid
- /// SetCC operation.
- CondCode getSetCCInverse(CondCode Operation, EVT Type);
-
- namespace GlobalISel {
- /// Return the operation corresponding to !(X op Y), where 'op' is a valid
- /// SetCC operation. The U bit of the condition code has different meanings
- /// between floating point and integer comparisons and LLT's don't provide
- /// this distinction. As such we need to be told whether the comparison is
- /// floating point or integer-like. Pointers should use integer-like
- /// comparisons.
- CondCode getSetCCInverse(CondCode Operation, bool isIntegerLike);
- } // end namespace GlobalISel
-
- /// Return the operation corresponding to (Y op X) when given the operation
- /// for (X op Y).
- CondCode getSetCCSwappedOperands(CondCode Operation);
-
- /// Return the result of a logical OR between different comparisons of
- /// identical values: ((X op1 Y) | (X op2 Y)). This function returns
- /// SETCC_INVALID if it is not possible to represent the resultant comparison.
- CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, EVT Type);
-
- /// Return the result of a logical AND between different comparisons of
- /// identical values: ((X op1 Y) & (X op2 Y)). This function returns
- /// SETCC_INVALID if it is not possible to represent the resultant comparison.
- CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, EVT Type);
-
-} // end llvm::ISD namespace
-
-} // end llvm namespace
+ /// The variable width operands are required to represent target addressing
+ /// modes as a single "operand", even though they may have multiple
+ /// SDOperands.
+ INLINEASM,
+
+ /// INLINEASM_BR - Branching version of inline asm. Used by asm-goto.
+ INLINEASM_BR,
+
+ /// EH_LABEL - Represents a label in mid basic block used to track
+ /// locations needed for debug and exception handling tables. These nodes
+ /// take a chain as input and return a chain.
+ EH_LABEL,
+
+ /// ANNOTATION_LABEL - Represents a mid basic block label used by
+ /// annotations. This should remain within the basic block and be ordered
+ /// with respect to other call instructions, but loads and stores may float
+ /// past it.
+ ANNOTATION_LABEL,
+
+ /// CATCHRET - Represents a return from a catch block funclet. Used for
+ /// MSVC compatible exception handling. Takes a chain operand and a
+ /// destination basic block operand.
+ CATCHRET,
+
+ /// CLEANUPRET - Represents a return from a cleanup block funclet. Used for
+ /// MSVC compatible exception handling. Takes only a chain operand.
+ CLEANUPRET,
+
+ /// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ /// value, the same type as the pointer type for the system, and an output
+ /// chain.
+ STACKSAVE,
+
+ /// STACKRESTORE has two operands, an input chain and a pointer to restore
+ /// to it returns an output chain.
+ STACKRESTORE,
+
+ /// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end
+ /// of a call sequence, and carry arbitrary information that target might
+ /// want to know. The first operand is a chain, the rest are specified by
+ /// the target and not touched by the DAG optimizers.
+ /// Targets that may use stack to pass call arguments define additional
+ /// operands:
+ /// - size of the call frame part that must be set up within the
+ /// CALLSEQ_START..CALLSEQ_END pair,
+ /// - part of the call frame prepared prior to CALLSEQ_START.
+ /// Both these parameters must be constants, their sum is the total call
+ /// frame size.
+ /// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
+ CALLSEQ_START, // Beginning of a call sequence
+ CALLSEQ_END, // End of a call sequence
+
+ /// VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE,
+ /// and the alignment. It returns a pair of values: the vaarg value and a
+ /// new chain.
+ VAARG,
+
+ /// VACOPY - VACOPY has 5 operands: an input chain, a destination pointer,
+ /// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ /// source.
+ VACOPY,
+
+ /// VAEND, VASTART - VAEND and VASTART have three operands: an input chain,
+ /// pointer, and a SRCVALUE.
+ VAEND,
+ VASTART,
+
+ // PREALLOCATED_SETUP - This has 2 operands: an input chain and a SRCVALUE
+ // with the preallocated call Value.
+ PREALLOCATED_SETUP,
+ // PREALLOCATED_ARG - This has 3 operands: an input chain, a SRCVALUE
+ // with the preallocated call Value, and a constant int.
+ PREALLOCATED_ARG,
+
+ /// SRCVALUE - This is a node type that holds a Value* that is used to
+ /// make reference to a value in the LLVM IR.
+ SRCVALUE,
+
+ /// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
+ /// reference metadata in the IR.
+ MDNODE_SDNODE,
+
+ /// PCMARKER - This corresponds to the pcmarker intrinsic.
+ PCMARKER,
+
+ /// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+ /// It produces a chain and one i64 value. The only operand is a chain.
+ /// If i64 is not legal, the result will be expanded into smaller values.
+ /// Still, it returns an i64, so targets should set legality for i64.
+ /// The result is the content of the architecture-specific cycle
+ /// counter-like register (or other high accuracy low latency clock source).
+ READCYCLECOUNTER,
+
+ /// HANDLENODE node - Used as a handle for various purposes.
+ HANDLENODE,
+
+ /// INIT_TRAMPOLINE - This corresponds to the init_trampoline intrinsic. It
+ /// takes as input a token chain, the pointer to the trampoline, the pointer
+ /// to the nested function, the pointer to pass for the 'nest' parameter, a
+ /// SRCVALUE for the trampoline and another for the nested function
+ /// (allowing targets to access the original Function*).
+ /// It produces a token chain as output.
+ INIT_TRAMPOLINE,
+
+ /// ADJUST_TRAMPOLINE - This corresponds to the adjust_trampoline intrinsic.
+ /// It takes a pointer to the trampoline and produces a (possibly) new
+ /// pointer to the same trampoline with platform-specific adjustments
+ /// applied. The pointer it returns points to an executable block of code.
+ ADJUST_TRAMPOLINE,
+
+ /// TRAP - Trapping instruction
+ TRAP,
+
+ /// DEBUGTRAP - Trap intended to get the attention of a debugger.
+ DEBUGTRAP,
+
+ /// PREFETCH - This corresponds to a prefetch intrinsic. The first operand
+ /// is the chain. The other operands are the address to prefetch,
+ /// read / write specifier, locality specifier and instruction / data cache
+ /// specifier.
+ PREFETCH,
+
+ /// OUTCHAIN = ATOMIC_FENCE(INCHAIN, ordering, scope)
+ /// This corresponds to the fence instruction. It takes an input chain, and
+ /// two integer constants: an AtomicOrdering and a SynchronizationScope.
+ ATOMIC_FENCE,
+
+ /// Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr)
+ /// This corresponds to "load atomic" instruction.
+ ATOMIC_LOAD,
+
+ /// OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val)
+ /// This corresponds to "store atomic" instruction.
+ ATOMIC_STORE,
+
+ /// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
+ /// For double-word atomic operations:
+ /// ValLo, ValHi, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmpLo, cmpHi,
+ /// swapLo, swapHi)
+ /// This corresponds to the cmpxchg instruction.
+ ATOMIC_CMP_SWAP,
+
+ /// Val, Success, OUTCHAIN
+ /// = ATOMIC_CMP_SWAP_WITH_SUCCESS(INCHAIN, ptr, cmp, swap)
+ /// N.b. this is still a strong cmpxchg operation, so
+ /// Success == "Val == cmp".
+ ATOMIC_CMP_SWAP_WITH_SUCCESS,
+
+ /// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
+ /// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
+ /// For double-word atomic operations:
+ /// ValLo, ValHi, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amtLo, amtHi)
+ /// ValLo, ValHi, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amtLo, amtHi)
+ /// These correspond to the atomicrmw instruction.
+ ATOMIC_SWAP,
+ ATOMIC_LOAD_ADD,
+ ATOMIC_LOAD_SUB,
+ ATOMIC_LOAD_AND,
+ ATOMIC_LOAD_CLR,
+ ATOMIC_LOAD_OR,
+ ATOMIC_LOAD_XOR,
+ ATOMIC_LOAD_NAND,
+ ATOMIC_LOAD_MIN,
+ ATOMIC_LOAD_MAX,
+ ATOMIC_LOAD_UMIN,
+ ATOMIC_LOAD_UMAX,
+ ATOMIC_LOAD_FADD,
+ ATOMIC_LOAD_FSUB,
+
+ // Masked load and store - consecutive vector load and store operations
+ // with additional mask operand that prevents memory accesses to the
+ // masked-off lanes.
+ //
+ // Val, OutChain = MLOAD(BasePtr, Mask, PassThru)
+ // OutChain = MSTORE(Value, BasePtr, Mask)
+ MLOAD,
+ MSTORE,
+
+ // Masked gather and scatter - load and store operations for a vector of
+ // random addresses with additional mask operand that prevents memory
+ // accesses to the masked-off lanes.
+ //
+ // Val, OutChain = GATHER(InChain, PassThru, Mask, BasePtr, Index, Scale)
+ // OutChain = SCATTER(InChain, Value, Mask, BasePtr, Index, Scale)
+ //
+ // The Index operand can have more vector elements than the other operands
+ // due to type legalization. The extra elements are ignored.
+ MGATHER,
+ MSCATTER,
+
+ /// This corresponds to the llvm.lifetime.* intrinsics. The first operand
+ /// is the chain and the second operand is the alloca pointer.
+ LIFETIME_START,
+ LIFETIME_END,
+
+ /// GC_TRANSITION_START/GC_TRANSITION_END - These operators mark the
+ /// beginning and end of GC transition sequence, and carry arbitrary
+ /// information that target might need for lowering. The first operand is
+ /// a chain, the rest are specified by the target and not touched by the DAG
+ /// optimizers. GC_TRANSITION_START..GC_TRANSITION_END pairs may not be
+ /// nested.
+ GC_TRANSITION_START,
+ GC_TRANSITION_END,
+
+ /// GET_DYNAMIC_AREA_OFFSET - get offset from native SP to the address of
+ /// the most recent dynamic alloca. For most targets that would be 0, but
+ /// for some others (e.g. PowerPC, PowerPC64) that would be compile-time
+ /// known nonzero constant. The only operand here is the chain.
+ GET_DYNAMIC_AREA_OFFSET,
+
+ /// VSCALE(IMM) - Returns the runtime scaling factor used to calculate the
+ /// number of elements within a scalable vector. IMM is a constant integer
+ /// multiplier that is applied to the runtime value.
+ VSCALE,
+
+ /// Generic reduction nodes. These nodes represent horizontal vector
+ /// reduction operations, producing a scalar result.
+ /// The STRICT variants perform reductions in sequential order. The first
+ /// operand is an initial scalar accumulator value, and the second operand
+ /// is the vector to reduce.
+ VECREDUCE_STRICT_FADD,
+ VECREDUCE_STRICT_FMUL,
+ /// These reductions are non-strict, and have a single vector operand.
+ VECREDUCE_FADD,
+ VECREDUCE_FMUL,
+ /// FMIN/FMAX nodes can have flags, for NaN/NoNaN variants.
+ VECREDUCE_FMAX,
+ VECREDUCE_FMIN,
+ /// Integer reductions may have a result type larger than the vector element
+ /// type. However, the reduction is performed using the vector element type
+ /// and the value in the top bits is unspecified.
+ VECREDUCE_ADD,
+ VECREDUCE_MUL,
+ VECREDUCE_AND,
+ VECREDUCE_OR,
+ VECREDUCE_XOR,
+ VECREDUCE_SMAX,
+ VECREDUCE_SMIN,
+ VECREDUCE_UMAX,
+ VECREDUCE_UMIN,
+
+ /// BUILTIN_OP_END - This must be the last enum value in this list.
+ /// The target-specific pre-isel opcode values start here.
+ BUILTIN_OP_END
+};
+
+/// FIRST_TARGET_STRICTFP_OPCODE - Target-specific pre-isel operations
+/// which cannot raise FP exceptions should be less than this value.
+/// Those that do must not be less than this value.
+static const int FIRST_TARGET_STRICTFP_OPCODE = BUILTIN_OP_END + 400;
+
+/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
+/// which do not reference a specific memory location should be less than
+/// this value. Those that do must not be less than this value, and can
+/// be used with SelectionDAG::getMemIntrinsicNode.
+static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END + 500;
+
+//===--------------------------------------------------------------------===//
+/// MemIndexedMode enum - This enum defines the load / store indexed
+/// addressing modes.
+///
+/// UNINDEXED "Normal" load / store. The effective address is already
+/// computed and is available in the base pointer. The offset
+/// operand is always undefined. In addition to producing a
+/// chain, an unindexed load produces one value (result of the
+/// load); an unindexed store does not produce a value.
+///
+/// PRE_INC Similar to the unindexed mode where the effective address is
+/// PRE_DEC the value of the base pointer add / subtract the offset.
+/// It considers the computation as being folded into the load /
+/// store operation (i.e. the load / store does the address
+/// computation as well as performing the memory transaction).
+/// The base operand is always undefined. In addition to
+/// producing a chain, pre-indexed load produces two values
+/// (result of the load and the result of the address
+/// computation); a pre-indexed store produces one value (result
+/// of the address computation).
+///
+/// POST_INC The effective address is the value of the base pointer. The
+/// POST_DEC value of the offset operand is then added to / subtracted
+/// from the base after memory transaction. In addition to
+/// producing a chain, post-indexed load produces two values
+/// (the result of the load and the result of the base +/- offset
+/// computation); a post-indexed store produces one value (the
+/// the result of the base +/- offset computation).
+enum MemIndexedMode { UNINDEXED = 0, PRE_INC, PRE_DEC, POST_INC, POST_DEC };
+
+static const int LAST_INDEXED_MODE = POST_DEC + 1;
+
+//===--------------------------------------------------------------------===//
+/// MemIndexType enum - This enum defines how to interpret MGATHER/SCATTER's
+/// index parameter when calculating addresses.
+///
+/// SIGNED_SCALED Addr = Base + ((signed)Index * sizeof(element))
+/// SIGNED_UNSCALED Addr = Base + (signed)Index
+/// UNSIGNED_SCALED Addr = Base + ((unsigned)Index * sizeof(element))
+/// UNSIGNED_UNSCALED Addr = Base + (unsigned)Index
+enum MemIndexType {
+ SIGNED_SCALED = 0,
+ SIGNED_UNSCALED,
+ UNSIGNED_SCALED,
+ UNSIGNED_UNSCALED
+};
+
+static const int LAST_MEM_INDEX_TYPE = UNSIGNED_UNSCALED + 1;
+
+//===--------------------------------------------------------------------===//
+/// LoadExtType enum - This enum defines the three variants of LOADEXT
+/// (load with extension).
+///
+/// SEXTLOAD loads the integer operand and sign extends it to a larger
+/// integer result type.
+/// ZEXTLOAD loads the integer operand and zero extends it to a larger
+/// integer result type.
+/// EXTLOAD is used for two things: floating point extending loads and
+/// integer extending loads [the top bits are undefined].
+enum LoadExtType { NON_EXTLOAD = 0, EXTLOAD, SEXTLOAD, ZEXTLOAD };
+
+static const int LAST_LOADEXT_TYPE = ZEXTLOAD + 1;
+
+NodeType getExtForLoadExtType(bool IsFP, LoadExtType);
+
+//===--------------------------------------------------------------------===//
+/// ISD::CondCode enum - These are ordered carefully to make the bitfields
+/// below work out, when considering SETFALSE (something that never exists
+/// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
+/// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
+/// to. If the "N" column is 1, the result of the comparison is undefined if
+/// the input is a NAN.
+///
+/// All of these (except for the 'always folded ops') should be handled for
+/// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
+/// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+///
+/// Note that these are laid out in a specific order to allow bit-twiddling
+/// to transform conditions.
+enum CondCode {
+ // Opcode N U L G E Intuitive operation
+ SETFALSE, // 0 0 0 0 Always false (always folded)
+ SETOEQ, // 0 0 0 1 True if ordered and equal
+ SETOGT, // 0 0 1 0 True if ordered and greater than
+ SETOGE, // 0 0 1 1 True if ordered and greater than or equal
+ SETOLT, // 0 1 0 0 True if ordered and less than
+ SETOLE, // 0 1 0 1 True if ordered and less than or equal
+ SETONE, // 0 1 1 0 True if ordered and operands are unequal
+ SETO, // 0 1 1 1 True if ordered (no nans)
+ SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ SETUEQ, // 1 0 0 1 True if unordered or equal
+ SETUGT, // 1 0 1 0 True if unordered or greater than
+ SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
+ SETULT, // 1 1 0 0 True if unordered or less than
+ SETULE, // 1 1 0 1 True if unordered, less than, or equal
+ SETUNE, // 1 1 1 0 True if unordered or not equal
+ SETTRUE, // 1 1 1 1 Always true (always folded)
+ // Don't care operations: undefined if the input is a nan.
+ SETFALSE2, // 1 X 0 0 0 Always false (always folded)
+ SETEQ, // 1 X 0 0 1 True if equal
+ SETGT, // 1 X 0 1 0 True if greater than
+ SETGE, // 1 X 0 1 1 True if greater than or equal
+ SETLT, // 1 X 1 0 0 True if less than
+ SETLE, // 1 X 1 0 1 True if less than or equal
+ SETNE, // 1 X 1 1 0 True if not equal
+ SETTRUE2, // 1 X 1 1 1 Always true (always folded)
+
+ SETCC_INVALID // Marker value.
+};
+
+/// Return true if this is a setcc instruction that performs a signed
+/// comparison when used with integer operands.
+inline bool isSignedIntSetCC(CondCode Code) {
+ return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
+}
+
+/// Return true if this is a setcc instruction that performs an unsigned
+/// comparison when used with integer operands.
+inline bool isUnsignedIntSetCC(CondCode Code) {
+ return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
+}
+
+/// Return true if the specified condition returns true if the two operands to
+/// the condition are equal. Note that if one of the two operands is a NaN,
+/// this value is meaningless.
+inline bool isTrueWhenEqual(CondCode Cond) { return ((int)Cond & 1) != 0; }
+
+/// This function returns 0 if the condition is always false if an operand is
+/// a NaN, 1 if the condition is always true if the operand is a NaN, and 2 if
+/// the condition is undefined if the operand is a NaN.
+inline unsigned getUnorderedFlavor(CondCode Cond) {
+ return ((int)Cond >> 3) & 3;
+}
+
+/// Return the operation corresponding to !(X op Y), where 'op' is a valid
+/// SetCC operation.
+CondCode getSetCCInverse(CondCode Operation, EVT Type);
+
+namespace GlobalISel {
+/// Return the operation corresponding to !(X op Y), where 'op' is a valid
+/// SetCC operation. The U bit of the condition code has different meanings
+/// between floating point and integer comparisons and LLT's don't provide
+/// this distinction. As such we need to be told whether the comparison is
+/// floating point or integer-like. Pointers should use integer-like
+/// comparisons.
+CondCode getSetCCInverse(CondCode Operation, bool isIntegerLike);
+} // end namespace GlobalISel
+
+/// Return the operation corresponding to (Y op X) when given the operation
+/// for (X op Y).
+CondCode getSetCCSwappedOperands(CondCode Operation);
+
+/// Return the result of a logical OR between different comparisons of
+/// identical values: ((X op1 Y) | (X op2 Y)). This function returns
+/// SETCC_INVALID if it is not possible to represent the resultant comparison.
+CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, EVT Type);
+
+/// Return the result of a logical AND between different comparisons of
+/// identical values: ((X op1 Y) & (X op2 Y)). This function returns
+/// SETCC_INVALID if it is not possible to represent the resultant comparison.
+CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, EVT Type);
+
+} // namespace ISD
+
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/IndirectThunks.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/IndirectThunks.h
new file mode 100644
index 000000000000..810acc0bcf8b
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/IndirectThunks.h
@@ -0,0 +1,110 @@
+//===---- IndirectThunks.h - Indirect Thunk Base Class ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Contains a base class for Passes that inject an MI thunk.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INDIRECTTHUNKS_H
+#define LLVM_INDIRECTTHUNKS_H
+
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+
+template <typename Derived> class ThunkInserter {
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+protected:
+ bool InsertedThunks;
+ void doInitialization(Module &M) {}
+ void createThunkFunction(MachineModuleInfo &MMI, StringRef Name);
+
+public:
+ void init(Module &M) {
+ InsertedThunks = false;
+ getDerived().doInitialization(M);
+ }
+ // return `true` if `MMI` or `MF` was modified
+ bool run(MachineModuleInfo &MMI, MachineFunction &MF);
+};
+
+template <typename Derived>
+void ThunkInserter<Derived>::createThunkFunction(MachineModuleInfo &MMI,
+ StringRef Name) {
+ assert(Name.startswith(getDerived().getThunkPrefix()) &&
+ "Created a thunk with an unexpected prefix!");
+
+ Module &M = const_cast<Module &>(*MMI.getModule());
+ LLVMContext &Ctx = M.getContext();
+ auto Type = FunctionType::get(Type::getVoidTy(Ctx), false);
+ Function *F =
+ Function::Create(Type, GlobalValue::LinkOnceODRLinkage, Name, &M);
+ F->setVisibility(GlobalValue::HiddenVisibility);
+ F->setComdat(M.getOrInsertComdat(Name));
+
+ // Add Attributes so that we don't create a frame, unwind information, or
+ // inline.
+ AttrBuilder B;
+ B.addAttribute(llvm::Attribute::NoUnwind);
+ B.addAttribute(llvm::Attribute::Naked);
+ F->addAttributes(llvm::AttributeList::FunctionIndex, B);
+
+ // Populate our function a bit so that we can verify.
+ BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
+ IRBuilder<> Builder(Entry);
+
+ Builder.CreateRetVoid();
+
+ // MachineFunctions aren't created automatically for the IR-level constructs
+ // we already made. Create them and insert them into the module.
+ MachineFunction &MF = MMI.getOrCreateMachineFunction(*F);
+ // A MachineBasicBlock must not be created for the Entry block; code
+ // generation from an empty naked function in C source code also does not
+ // generate one. At least GlobalISel asserts if this invariant isn't
+ // respected.
+
+ // Set MF properties. We never use vregs...
+ MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
+}
+
+template <typename Derived>
+bool ThunkInserter<Derived>::run(MachineModuleInfo &MMI, MachineFunction &MF) {
+ // If MF is not a thunk, check to see if we need to insert a thunk.
+ if (!MF.getName().startswith(getDerived().getThunkPrefix())) {
+ // If we've already inserted a thunk, nothing else to do.
+ if (InsertedThunks)
+ return false;
+
+ // Only add a thunk if one of the functions has the corresponding feature
+ // enabled in its subtarget, and doesn't enable external thunks.
+ // FIXME: Conditionalize on indirect calls so we don't emit a thunk when
+ // nothing will end up calling it.
+ // FIXME: It's a little silly to look at every function just to enumerate
+ // the subtargets, but eventually we'll want to look at them for indirect
+ // calls, so maybe this is OK.
+ if (!getDerived().mayUseThunk(MF))
+ return false;
+
+ getDerived().insertThunks(MMI);
+ InsertedThunks = true;
+ return true;
+ }
+
+ // If this *is* a thunk function, we need to populate it with the correct MI.
+ getDerived().populateThunk(MF);
+ return true;
+}
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/IntrinsicLowering.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/IntrinsicLowering.h
index daf2d9a47801..8593f54f3961 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/IntrinsicLowering.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/IntrinsicLowering.h
@@ -19,7 +19,6 @@
namespace llvm {
class CallInst;
-class Module;
class DataLayout;
class IntrinsicLowering {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LexicalScopes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LexicalScopes.h
index 253d4734995b..bac850d327ef 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LexicalScopes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LexicalScopes.h
@@ -163,8 +163,8 @@ public:
void getMachineBasicBlocks(const DILocation *DL,
SmallPtrSetImpl<const MachineBasicBlock *> &MBBs);
- /// dominates - Return true if DebugLoc's lexical scope dominates at least one
- /// machine instruction's lexical scope in a given machine basic block.
+ /// Return true if DebugLoc's lexical scope dominates at least one machine
+ /// instruction's lexical scope in a given machine basic block.
bool dominates(const DILocation *DL, MachineBasicBlock *MBB);
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
@@ -250,6 +250,11 @@ private:
/// CurrentFnLexicalScope - Top level scope for the current function.
///
LexicalScope *CurrentFnLexicalScope = nullptr;
+
+ /// Map a location to the set of basic blocks it dominates. This is a cache
+ /// for \ref LexicalScopes::getMachineBasicBlocks results.
+ using BlockSetT = SmallPtrSet<const MachineBasicBlock *, 4>;
+ DenseMap<const DILocation *, std::unique_ptr<BlockSetT>> DominatedBlocks;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveInterval.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveInterval.h
index fe5adb59dac2..0764257125e6 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveInterval.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveInterval.h
@@ -617,7 +617,7 @@ namespace llvm {
/// subranges). Returns true if found at least one index.
template <typename Range, typename OutputIt>
bool findIndexesLiveAt(Range &&R, OutputIt O) const {
- assert(std::is_sorted(R.begin(), R.end()));
+ assert(llvm::is_sorted(R));
auto Idx = R.begin(), EndIdx = R.end();
auto Seg = segments.begin(), EndSeg = segments.end();
bool Found = false;
@@ -625,11 +625,12 @@ namespace llvm {
// if the Seg is lower find first segment that is above Idx using binary
// search
if (Seg->end <= *Idx) {
- Seg = std::upper_bound(++Seg, EndSeg, *Idx,
- [=](typename std::remove_reference<decltype(*Idx)>::type V,
- const typename std::remove_reference<decltype(*Seg)>::type &S) {
- return V < S.end;
- });
+ Seg = std::upper_bound(
+ ++Seg, EndSeg, *Idx,
+ [=](std::remove_reference_t<decltype(*Idx)> V,
+ const std::remove_reference_t<decltype(*Seg)> &S) {
+ return V < S.end;
+ });
if (Seg == EndSeg)
break;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervalCalc.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervalCalc.h
new file mode 100644
index 000000000000..76005e835595
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervalCalc.h
@@ -0,0 +1,71 @@
+//===- LiveIntervalCalc.h - Calculate live intervals -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The LiveIntervalCalc class is an extension of LiveRangeCalc targeted to the
+// computation and modification of the LiveInterval variants of LiveRanges.
+// LiveIntervals are meant to track liveness of registers and stack slots and
+// LiveIntervalCalc adds to LiveRangeCalc all the machinery requied to
+// construct the liveness of virtual registers tracked by a LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_LIVEINTERVALCALC_H
+#define LLVM_LIB_CODEGEN_LIVEINTERVALCALC_H
+
+#include "llvm/CodeGen/LiveRangeCalc.h"
+
+namespace llvm {
+
+template <class NodeT> class DomTreeNodeBase;
+
+using MachineDomTreeNode = DomTreeNodeBase<MachineBasicBlock>;
+
+class LiveIntervalCalc : public LiveRangeCalc {
+ /// Extend the live range of @p LR to reach all uses of Reg.
+ ///
+ /// If @p LR is a main range, or if @p LI is null, then all uses must be
+ /// jointly dominated by the definitions from @p LR. If @p LR is a subrange
+ /// of the live interval @p LI, corresponding to lane mask @p LaneMask,
+ /// all uses must be jointly dominated by the definitions from @p LR
+ /// together with definitions of other lanes where @p LR becomes undefined
+ /// (via <def,read-undef> operands).
+ /// If @p LR is a main range, the @p LaneMask should be set to ~0, i.e.
+ /// LaneBitmask::getAll().
+ void extendToUses(LiveRange &LR, Register Reg, LaneBitmask LaneMask,
+ LiveInterval *LI = nullptr);
+
+public:
+ LiveIntervalCalc() = default;
+
+ /// createDeadDefs - Create a dead def in LI for every def operand of Reg.
+ /// Each instruction defining Reg gets a new VNInfo with a corresponding
+ /// minimal live range.
+ void createDeadDefs(LiveRange &LR, Register Reg);
+
+ /// Extend the live range of @p LR to reach all uses of Reg.
+ ///
+ /// All uses must be jointly dominated by existing liveness. PHI-defs are
+ /// inserted as needed to preserve SSA form.
+ void extendToUses(LiveRange &LR, MCRegister PhysReg) {
+ extendToUses(LR, PhysReg, LaneBitmask::getAll());
+ }
+
+ /// Calculates liveness for the register specified in live interval @p LI.
+ /// Creates subregister live ranges as needed if subreg liveness tracking is
+ /// enabled.
+ void calculate(LiveInterval &LI, bool TrackSubRegs);
+
+ /// For live interval \p LI with correct SubRanges construct matching
+ /// information for the main live range. Expects the main live range to not
+ /// have any segments or value numbers.
+ void constructMainRangeFromSubranges(LiveInterval &LI);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_LIVEINTERVALCALC_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervals.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervals.h
index 2bfc99624937..945a40829714 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervals.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveIntervals.h
@@ -22,7 +22,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -40,8 +39,9 @@ namespace llvm {
extern cl::opt<bool> UseSegmentSetForPhysRegs;
+class AAResults;
class BitVector;
-class LiveRangeCalc;
+class LiveIntervalCalc;
class MachineBlockFrequencyInfo;
class MachineDominatorTree;
class MachineFunction;
@@ -56,10 +56,10 @@ class VirtRegMap;
MachineRegisterInfo* MRI;
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
- AliasAnalysis *AA;
+ AAResults *AA;
SlotIndexes* Indexes;
MachineDominatorTree *DomTree = nullptr;
- LiveRangeCalc *LRCalc = nullptr;
+ LiveIntervalCalc *LICalc = nullptr;
/// Special pool allocator for VNInfo's (LiveInterval val#).
VNInfo::Allocator VNInfoAllocator;
@@ -212,7 +212,7 @@ class VirtRegMap;
return Indexes;
}
- AliasAnalysis *getAliasAnalysis() const {
+ AAResults *getAliasAnalysis() const {
return AA;
}
@@ -256,8 +256,9 @@ class VirtRegMap;
return Indexes->getMBBFromIndex(index);
}
- void insertMBBInMaps(MachineBasicBlock *MBB) {
- Indexes->insertMBBInMaps(MBB);
+ void insertMBBInMaps(MachineBasicBlock *MBB,
+ MachineInstr *InsertionPoint = nullptr) {
+ Indexes->insertMBBInMaps(MBB, InsertionPoint);
assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
"Blocks must be added in order.");
RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
@@ -310,16 +311,16 @@ class VirtRegMap;
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
void handleMove(MachineInstr &MI, bool UpdateFlags = false);
- /// Update intervals for operands of \p MI so that they begin/end on the
- /// SlotIndex for \p BundleStart.
+ /// Update intervals of operands of all instructions in the newly
+ /// created bundle specified by \p BundleStart.
///
/// \param UpdateFlags Update live intervals for nonallocatable physregs.
///
- /// Requires MI and BundleStart to have SlotIndexes, and assumes
- /// existing liveness is accurate. BundleStart should be the first
- /// instruction in the Bundle.
- void handleMoveIntoBundle(MachineInstr &MI, MachineInstr &BundleStart,
- bool UpdateFlags = false);
+ /// Assumes existing liveness is accurate.
+ /// \pre BundleStart should be the first instruction in the Bundle.
+ /// \pre BundleStart should not have a have SlotIndex as one will be assigned.
+ void handleMoveIntoNewBundle(MachineInstr &BundleStart,
+ bool UpdateFlags = false);
/// Update live intervals for instructions in a range of iterators. It is
/// intended for use after target hooks that may insert or remove
@@ -333,7 +334,7 @@ class VirtRegMap;
void repairIntervalsInRange(MachineBasicBlock *MBB,
MachineBasicBlock::iterator Begin,
MachineBasicBlock::iterator End,
- ArrayRef<unsigned> OrigRegs);
+ ArrayRef<Register> OrigRegs);
// Register mask functions.
//
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeCalc.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeCalc.h
index 08026c05733c..bbb6f2ddd233 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeCalc.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeCalc.h
@@ -1,4 +1,4 @@
-//===- LiveRangeCalc.h - Calculate live ranges ------------------*- C++ -*-===//
+//===- LiveRangeCalc.h - Calculate live ranges -----------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,15 +6,17 @@
//
//===----------------------------------------------------------------------===//
//
-// The LiveRangeCalc class can be used to compute live ranges from scratch. It
-// caches information about values in the CFG to speed up repeated operations
-// on the same live range. The cache can be shared by non-overlapping live
-// ranges. SplitKit uses that when computing the live range of split products.
+// The LiveRangeCalc class can be used to implement the computation of
+// live ranges from scratch.
+// It caches information about values in the CFG to speed up repeated
+// operations on the same live range. The cache can be shared by
+// non-overlapping live ranges. SplitKit uses that when computing the live
+// range of split products.
//
// A low-level interface is available to clients that know where a variable is
// live, but don't know which value it has as every point. LiveRangeCalc will
// propagate values down the dominator tree, and even insert PHI-defs where
-// needed. SplitKit uses this faster interface when possible.
+// needed. SplitKit uses this faster interface when possible.
//
//===----------------------------------------------------------------------===//
@@ -159,18 +161,14 @@ class LiveRangeCalc {
/// the given @p LiveOuts.
void updateFromLiveIns();
- /// Extend the live range of @p LR to reach all uses of Reg.
- ///
- /// If @p LR is a main range, or if @p LI is null, then all uses must be
- /// jointly dominated by the definitions from @p LR. If @p LR is a subrange
- /// of the live interval @p LI, corresponding to lane mask @p LaneMask,
- /// all uses must be jointly dominated by the definitions from @p LR
- /// together with definitions of other lanes where @p LR becomes undefined
- /// (via <def,read-undef> operands).
- /// If @p LR is a main range, the @p LaneMask should be set to ~0, i.e.
- /// LaneBitmask::getAll().
- void extendToUses(LiveRange &LR, unsigned Reg, LaneBitmask LaneMask,
- LiveInterval *LI = nullptr);
+protected:
+ /// Some getters to expose in a read-only way some private fields to
+ /// subclasses.
+ const MachineFunction *getMachineFunction() { return MF; }
+ const MachineRegisterInfo *getRegInfo() const { return MRI; }
+ SlotIndexes *getIndexes() { return Indexes; }
+ MachineDominatorTree *getDomTree() { return DomTree; }
+ VNInfo::Allocator *getVNAlloc() { return Alloc; }
/// Reset Map and Seen fields.
void resetLiveOutMap();
@@ -210,29 +208,6 @@ public:
void extend(LiveRange &LR, SlotIndex Use, unsigned PhysReg,
ArrayRef<SlotIndex> Undefs);
- /// createDeadDefs - Create a dead def in LI for every def operand of Reg.
- /// Each instruction defining Reg gets a new VNInfo with a corresponding
- /// minimal live range.
- void createDeadDefs(LiveRange &LR, unsigned Reg);
-
- /// Extend the live range of @p LR to reach all uses of Reg.
- ///
- /// All uses must be jointly dominated by existing liveness. PHI-defs are
- /// inserted as needed to preserve SSA form.
- void extendToUses(LiveRange &LR, unsigned PhysReg) {
- extendToUses(LR, PhysReg, LaneBitmask::getAll());
- }
-
- /// Calculates liveness for the register specified in live interval @p LI.
- /// Creates subregister live ranges as needed if subreg liveness tracking is
- /// enabled.
- void calculate(LiveInterval &LI, bool TrackSubRegs);
-
- /// For live interval \p LI with correct SubRanges construct matching
- /// information for the main live range. Expects the main live range to not
- /// have any segments or value numbers.
- void constructMainRangeFromSubranges(LiveInterval &LI);
-
//===--------------------------------------------------------------------===//
// Low-level interface.
//===--------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeEdit.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeEdit.h
index 6519937ec071..3c4273130ab2 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeEdit.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveRangeEdit.h
@@ -22,7 +22,6 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -33,6 +32,7 @@
namespace llvm {
+class AAResults;
class LiveIntervals;
class MachineBlockFrequencyInfo;
class MachineInstr;
@@ -68,7 +68,7 @@ public:
private:
LiveInterval *Parent;
- SmallVectorImpl<unsigned> &NewRegs;
+ SmallVectorImpl<Register> &NewRegs;
MachineRegisterInfo &MRI;
LiveIntervals &LIS;
VirtRegMap *VRM;
@@ -94,7 +94,7 @@ private:
SmallPtrSet<const VNInfo *, 4> Rematted;
/// scanRemattable - Identify the Parent values that may rematerialize.
- void scanRemattable(AliasAnalysis *aa);
+ void scanRemattable(AAResults *aa);
/// allUsesAvailableAt - Return true if all registers used by OrigMI at
/// OrigIdx are also available with the same value at UseIdx.
@@ -110,18 +110,18 @@ private:
/// Helper for eliminateDeadDefs.
void eliminateDeadDef(MachineInstr *MI, ToShrinkSet &ToShrink,
- AliasAnalysis *AA);
+ AAResults *AA);
/// MachineRegisterInfo callback to notify when new virtual
/// registers are created.
- void MRI_NoteNewVirtualRegister(unsigned VReg) override;
+ void MRI_NoteNewVirtualRegister(Register VReg) override;
/// Check if MachineOperand \p MO is a last use/kill either in the
/// main live range of \p LI or in one of the matching subregister ranges.
bool useIsKill(const LiveInterval &LI, const MachineOperand &MO) const;
/// Create a new empty interval based on OldReg.
- LiveInterval &createEmptyIntervalFrom(unsigned OldReg, bool createSubRanges);
+ LiveInterval &createEmptyIntervalFrom(Register OldReg, bool createSubRanges);
public:
/// Create a LiveRangeEdit for breaking down parent into smaller pieces.
@@ -135,7 +135,7 @@ public:
/// be done. This could be the case if called before Regalloc.
/// @param deadRemats The collection of all the instructions defining an
/// original reg and are dead after remat.
- LiveRangeEdit(LiveInterval *parent, SmallVectorImpl<unsigned> &newRegs,
+ LiveRangeEdit(LiveInterval *parent, SmallVectorImpl<Register> &newRegs,
MachineFunction &MF, LiveIntervals &lis, VirtRegMap *vrm,
Delegate *delegate = nullptr,
SmallPtrSet<MachineInstr *, 32> *deadRemats = nullptr)
@@ -152,15 +152,15 @@ public:
return *Parent;
}
- unsigned getReg() const { return getParent().reg; }
+ Register getReg() const { return getParent().reg; }
/// Iterator for accessing the new registers added by this edit.
- using iterator = SmallVectorImpl<unsigned>::const_iterator;
+ using iterator = SmallVectorImpl<Register>::const_iterator;
iterator begin() const { return NewRegs.begin() + FirstNew; }
iterator end() const { return NewRegs.end(); }
unsigned size() const { return NewRegs.size() - FirstNew; }
bool empty() const { return size() == 0; }
- unsigned get(unsigned idx) const { return NewRegs[idx + FirstNew]; }
+ Register get(unsigned idx) const { return NewRegs[idx + FirstNew]; }
/// pop_back - It allows LiveRangeEdit users to drop new registers.
/// The context is when an original def instruction of a register is
@@ -172,12 +172,12 @@ public:
/// we want to drop it from the NewRegs set.
void pop_back() { NewRegs.pop_back(); }
- ArrayRef<unsigned> regs() const {
+ ArrayRef<Register> regs() const {
return makeArrayRef(NewRegs).slice(FirstNew);
}
/// createFrom - Create a new virtual register based on OldReg.
- unsigned createFrom(unsigned OldReg);
+ Register createFrom(Register OldReg);
/// create - Create a new register with the same class and original slot as
/// parent.
@@ -185,17 +185,17 @@ public:
return createEmptyIntervalFrom(getReg(), true);
}
- unsigned create() { return createFrom(getReg()); }
+ Register create() { return createFrom(getReg()); }
/// anyRematerializable - Return true if any parent values may be
/// rematerializable.
/// This function must be called before any rematerialization is attempted.
- bool anyRematerializable(AliasAnalysis *);
+ bool anyRematerializable(AAResults *);
/// checkRematerializable - Manually add VNI to the list of rematerializable
/// values if DefMI may be rematerializable.
bool checkRematerializable(VNInfo *VNI, const MachineInstr *DefMI,
- AliasAnalysis *);
+ AAResults *);
/// Remat - Information needed to rematerialize at a specific location.
struct Remat {
@@ -234,7 +234,7 @@ public:
/// eraseVirtReg - Notify the delegate that Reg is no longer in use, and try
/// to erase it from LIS.
- void eraseVirtReg(unsigned Reg);
+ void eraseVirtReg(Register Reg);
/// eliminateDeadDefs - Try to delete machine instructions that are now dead
/// (allDefsAreDead returns true). This may cause live intervals to be trimmed
@@ -243,8 +243,8 @@ public:
/// allocator. These registers should not be split into new intervals
/// as currently those new intervals are not guaranteed to spill.
void eliminateDeadDefs(SmallVectorImpl<MachineInstr *> &Dead,
- ArrayRef<unsigned> RegsBeingSpilled = None,
- AliasAnalysis *AA = nullptr);
+ ArrayRef<Register> RegsBeingSpilled = None,
+ AAResults *AA = nullptr);
/// calculateRegClassAndHint - Recompute register class and hint for each new
/// register.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveVariables.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveVariables.h
index 7b45f7d76af5..efb0fa85a0fe 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveVariables.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/LiveVariables.h
@@ -297,6 +297,11 @@ public:
MachineBasicBlock *DomBB,
MachineBasicBlock *SuccBB);
+ void addNewBlock(MachineBasicBlock *BB,
+ MachineBasicBlock *DomBB,
+ MachineBasicBlock *SuccBB,
+ std::vector<SparseBitVector<>> &LiveInSets);
+
/// isPHIJoin - Return true if Reg is a phi join register.
bool isPHIJoin(unsigned Reg) { return PHIJoins.test(Reg); }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MBFIWrapper.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MBFIWrapper.h
new file mode 100644
index 000000000000..062431a6f96b
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MBFIWrapper.h
@@ -0,0 +1,46 @@
+//===- llvm/CodeGen/MBFIWrapper.h -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This class keeps track of branch frequencies of newly created blocks and
+// tail-merged blocks. Used by the TailDuplication and MachineBlockPlacement.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MBFIWRAPPER_H
+#define LLVM_CODEGEN_MBFIWRAPPER_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/BlockFrequency.h"
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineBlockFrequencyInfo;
+
+class MBFIWrapper {
+ public:
+ MBFIWrapper(const MachineBlockFrequencyInfo &I) : MBFI(I) {}
+
+ BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const;
+ void setBlockFreq(const MachineBasicBlock *MBB, BlockFrequency F);
+ raw_ostream &printBlockFreq(raw_ostream &OS,
+ const MachineBasicBlock *MBB) const;
+ raw_ostream &printBlockFreq(raw_ostream &OS,
+ const BlockFrequency Freq) const;
+ void view(const Twine &Name, bool isSimple = true);
+ uint64_t getEntryFreq() const;
+ const MachineBlockFrequencyInfo &getMBFI() { return MBFI; }
+
+ private:
+ const MachineBlockFrequencyInfo &MBFI;
+ DenseMap<const MachineBasicBlock *, BlockFrequency> MergedBBFreq;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_CODEGEN_MBFIWRAPPER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIParser.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
index 8ca665b23b28..590b3dcdd93b 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIParser.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -40,8 +41,8 @@ struct VRegInfo {
const TargetRegisterClass *RC;
const RegisterBank *RegBank;
} D;
- unsigned VReg;
- unsigned PreferredReg = 0;
+ Register VReg;
+ Register PreferredReg;
};
using Name2RegClassMap = StringMap<const TargetRegisterClass *>;
@@ -55,7 +56,7 @@ private:
StringMap<unsigned> Names2InstrOpCodes;
/// Maps from register names to registers.
- StringMap<unsigned> Names2Regs;
+ StringMap<Register> Names2Regs;
/// Maps from register mask names to register masks.
StringMap<const uint32_t *> Names2RegMasks;
@@ -100,7 +101,7 @@ public:
/// Try to convert a register name to a register number. Return true if the
/// register name is invalid.
- bool getRegisterByName(StringRef RegName, unsigned &Reg);
+ bool getRegisterByName(StringRef RegName, Register &Reg);
/// Check if the given identifier is a name of a register mask.
///
@@ -164,7 +165,7 @@ struct PerFunctionMIParsingState {
PerTargetMIParsingState &Target;
DenseMap<unsigned, MachineBasicBlock *> MBBSlots;
- DenseMap<unsigned, VRegInfo *> VRegInfos;
+ DenseMap<Register, VRegInfo *> VRegInfos;
StringMap<VRegInfo *> VRegInfosNamed;
DenseMap<unsigned, int> FixedStackObjectSlots;
DenseMap<unsigned, int> StackObjectSlots;
@@ -178,7 +179,7 @@ struct PerFunctionMIParsingState {
const SlotMapping &IRSlots,
PerTargetMIParsingState &Target);
- VRegInfo &getVRegInfo(unsigned Num);
+ VRegInfo &getVRegInfo(Register Num);
VRegInfo &getVRegInfoNamed(StringRef RegName);
const Value *getIRValue(unsigned Slot);
};
@@ -216,10 +217,10 @@ bool parseMBBReference(PerFunctionMIParsingState &PFS,
SMDiagnostic &Error);
bool parseRegisterReference(PerFunctionMIParsingState &PFS,
- unsigned &Reg, StringRef Src,
+ Register &Reg, StringRef Src,
SMDiagnostic &Error);
-bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, unsigned &Reg,
+bool parseNamedRegisterReference(PerFunctionMIParsingState &PFS, Register &Reg,
StringRef Src, SMDiagnostic &Error);
bool parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
index 385baea0446f..a7c69e2d43ef 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRParser/MIRParser.h
@@ -29,6 +29,9 @@ class MachineModuleInfo;
class SMDiagnostic;
class StringRef;
+typedef llvm::function_ref<Optional<std::string>(StringRef)>
+ DataLayoutCallbackTy;
+
/// This class initializes machine functions by applying the state loaded from
/// a MIR file.
class MIRParser {
@@ -43,7 +46,8 @@ public:
///
/// A new, empty module is created if the LLVM IR isn't present.
/// \returns nullptr if a parsing error occurred.
- std::unique_ptr<Module> parseIRModule();
+ std::unique_ptr<Module> parseIRModule(
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
/// Parses MachineFunctions in the MIR file and add them to the given
/// MachineModuleInfo \p MMI.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index 069d0aa45095..c68b073ebb8c 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -142,6 +142,23 @@ template <> struct ScalarEnumerationTraits<MachineJumpTableInfo::JTEntryKind> {
}
};
+template <> struct ScalarTraits<MaybeAlign> {
+ static void output(const MaybeAlign &Alignment, void *,
+ llvm::raw_ostream &out) {
+ out << uint64_t(Alignment ? Alignment->value() : 0U);
+ }
+ static StringRef input(StringRef Scalar, void *, MaybeAlign &Alignment) {
+ unsigned long long n;
+ if (getAsUnsignedInteger(Scalar, 10, n))
+ return "invalid number";
+ if (n > 0 && !isPowerOf2_64(n))
+ return "must be 0 or a power of two";
+ Alignment = MaybeAlign(n);
+ return StringRef();
+ }
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+};
+
} // end namespace yaml
} // end namespace llvm
@@ -212,7 +229,7 @@ struct MachineStackObject {
ObjectType Type = DefaultType;
int64_t Offset = 0;
uint64_t Size = 0;
- unsigned Alignment = 0;
+ MaybeAlign Alignment = None;
TargetStackID::Value StackID;
StringValue CalleeSavedRegister;
bool CalleeSavedRestored = true;
@@ -252,7 +269,7 @@ template <> struct MappingTraits<MachineStackObject> {
YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
if (Object.Type != MachineStackObject::VariableSized)
YamlIO.mapRequired("size", Object.Size);
- YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
+ YamlIO.mapOptional("alignment", Object.Alignment, None);
YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
YamlIO.mapOptional("callee-saved-register", Object.CalleeSavedRegister,
StringValue()); // Don't print it out when it's empty.
@@ -278,7 +295,7 @@ struct FixedMachineStackObject {
ObjectType Type = DefaultType;
int64_t Offset = 0;
uint64_t Size = 0;
- unsigned Alignment = 0;
+ MaybeAlign Alignment = None;
TargetStackID::Value StackID;
bool IsImmutable = false;
bool IsAliased = false;
@@ -327,7 +344,7 @@ template <> struct MappingTraits<FixedMachineStackObject> {
FixedMachineStackObject::DefaultType); // Don't print the default type.
YamlIO.mapOptional("offset", Object.Offset, (int64_t)0);
YamlIO.mapOptional("size", Object.Size, (uint64_t)0);
- YamlIO.mapOptional("alignment", Object.Alignment, (unsigned)0);
+ YamlIO.mapOptional("alignment", Object.Alignment, None);
YamlIO.mapOptional("stack-id", Object.StackID, TargetStackID::Default);
if (Object.Type != FixedMachineStackObject::SpillSlot) {
YamlIO.mapOptional("isImmutable", Object.IsImmutable, false);
@@ -411,7 +428,7 @@ template <> struct MappingTraits<CallSiteInfo> {
struct MachineConstantPoolValue {
UnsignedValue ID;
StringValue Value;
- unsigned Alignment = 0;
+ MaybeAlign Alignment = None;
bool IsTargetSpecific = false;
bool operator==(const MachineConstantPoolValue &Other) const {
@@ -425,7 +442,7 @@ template <> struct MappingTraits<MachineConstantPoolValue> {
static void mapping(IO &YamlIO, MachineConstantPoolValue &Constant) {
YamlIO.mapRequired("id", Constant.ID);
YamlIO.mapOptional("value", Constant.Value, StringValue());
- YamlIO.mapOptional("alignment", Constant.Alignment, (unsigned)0);
+ YamlIO.mapOptional("alignment", Constant.Alignment, None);
YamlIO.mapOptional("isTargetSpecific", Constant.IsTargetSpecific, false);
}
};
@@ -571,7 +588,7 @@ template <> struct MappingTraits<std::unique_ptr<MachineFunctionInfo>> {
struct MachineFunction {
StringRef Name;
- unsigned Alignment = 0;
+ MaybeAlign Alignment = None;
bool ExposesReturnsTwice = false;
// GISel MachineFunctionProperties.
bool Legalized = false;
@@ -599,7 +616,7 @@ struct MachineFunction {
template <> struct MappingTraits<MachineFunction> {
static void mapping(IO &YamlIO, MachineFunction &MF) {
YamlIO.mapRequired("name", MF.Name);
- YamlIO.mapOptional("alignment", MF.Alignment, (unsigned)0);
+ YamlIO.mapOptional("alignment", MF.Alignment, None);
YamlIO.mapOptional("exposesReturnsTwice", MF.ExposesReturnsTwice, false);
YamlIO.mapOptional("legalized", MF.Legalized, false);
YamlIO.mapOptional("regBankSelected", MF.RegBankSelected, false);
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h
index ccdde78a0b22..d6cb7211cf70 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBasicBlock.h
@@ -15,16 +15,13 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/ilist.h"
-#include "llvm/ADT/ilist_node.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/simple_ilist.h"
+#include "llvm/ADT/SparseBitVector.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundleIterator.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/LaneBitmask.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/BranchProbability.h"
-#include "llvm/Support/Printable.h"
#include <cassert>
#include <cstdint>
#include <functional>
@@ -39,12 +36,44 @@ class MachineFunction;
class MCSymbol;
class ModuleSlotTracker;
class Pass;
+class Printable;
class SlotIndexes;
class StringRef;
class raw_ostream;
class TargetRegisterClass;
class TargetRegisterInfo;
+// This structure uniquely identifies a basic block section.
+// Possible values are
+// {Type: Default, Number: (unsigned)} (These are regular section IDs)
+// {Type: Exception, Number: 0} (ExceptionSectionID)
+// {Type: Cold, Number: 0} (ColdSectionID)
+struct MBBSectionID {
+ enum SectionType {
+ Default = 0, // Regular section (these sections are distinguished by the
+ // Number field).
+ Exception, // Special section type for exception handling blocks
+ Cold, // Special section type for cold blocks
+ } Type;
+ unsigned Number;
+
+ MBBSectionID(unsigned N) : Type(Default), Number(N) {}
+
+ // Special unique sections for cold and exception blocks.
+ const static MBBSectionID ColdSectionID;
+ const static MBBSectionID ExceptionSectionID;
+
+ bool operator==(const MBBSectionID &Other) const {
+ return Type == Other.Type && Number == Other.Number;
+ }
+
+ bool operator!=(const MBBSectionID &Other) const { return !(*this == Other); }
+
+private:
+ // This is only used to construct the special cold and exception sections.
+ MBBSectionID(SectionType T) : Type(T), Number(0) {}
+};
+
template <> struct ilist_traits<MachineInstr> {
private:
friend class MachineBasicBlock; // Set by the owning MachineBasicBlock.
@@ -129,10 +158,25 @@ private:
/// Indicate that this basic block is the entry block of a cleanup funclet.
bool IsCleanupFuncletEntry = false;
+ /// With basic block sections, this stores the Section ID of the basic block.
+ MBBSectionID SectionID{0};
+
+ // Indicate that this basic block begins a section.
+ bool IsBeginSection = false;
+
+ // Indicate that this basic block ends a section.
+ bool IsEndSection = false;
+
+ /// Indicate that this basic block is the indirect dest of an INLINEASM_BR.
+ bool IsInlineAsmBrIndirectTarget = false;
+
/// since getSymbol is a relatively heavy-weight operation, the symbol
/// is only computed once and is cached.
mutable MCSymbol *CachedMCSymbol = nullptr;
+ /// Used during basic block sections to mark the end of a basic block.
+ MCSymbol *EndMCSymbol = nullptr;
+
// Intrusive list support
MachineBasicBlock() = default;
@@ -331,7 +375,7 @@ public:
/// Add PhysReg as live in to this block, and ensure that there is a copy of
/// PhysReg to a virtual register of class RC. Return the virtual register
/// that is a copy of the live in PhysReg.
- unsigned addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
+ Register addLiveIn(MCRegister PhysReg, const TargetRegisterClass *RC);
/// Remove the specified register from the live in set.
void removeLiveIn(MCPhysReg Reg,
@@ -408,6 +452,43 @@ public:
/// Indicates if this is the entry block of a cleanup funclet.
void setIsCleanupFuncletEntry(bool V = true) { IsCleanupFuncletEntry = V; }
+ /// Returns true if this block begins any section.
+ bool isBeginSection() const { return IsBeginSection; }
+
+ /// Returns true if this block ends any section.
+ bool isEndSection() const { return IsEndSection; }
+
+ void setIsBeginSection(bool V = true) { IsBeginSection = V; }
+
+ void setIsEndSection(bool V = true) { IsEndSection = V; }
+
+ /// Returns the section ID of this basic block.
+ MBBSectionID getSectionID() const { return SectionID; }
+
+ /// Returns the unique section ID number of this basic block.
+ unsigned getSectionIDNum() const {
+ return ((unsigned)MBBSectionID::SectionType::Cold) -
+ ((unsigned)SectionID.Type) + SectionID.Number;
+ }
+
+ /// Sets the section ID for this basic block.
+ void setSectionID(MBBSectionID V) { SectionID = V; }
+
+ /// Returns true if this block may have an INLINEASM_BR (overestimate, by
+ /// checking if any of the successors are indirect targets of any inlineasm_br
+ /// in the function).
+ bool mayHaveInlineAsmBr() const;
+
+ /// Returns true if this is the indirect dest of an INLINEASM_BR.
+ bool isInlineAsmBrIndirectTarget() const {
+ return IsInlineAsmBrIndirectTarget;
+ }
+
+ /// Indicates if this is the indirect dest of an INLINEASM_BR.
+ void setIsInlineAsmBrIndirectTarget(bool V = true) {
+ IsInlineAsmBrIndirectTarget = V;
+ }
+
/// Returns true if it is legal to hoist instructions into this block.
bool isLegalToHoistInto() const;
@@ -419,11 +500,18 @@ public:
void moveBefore(MachineBasicBlock *NewAfter);
void moveAfter(MachineBasicBlock *NewBefore);
- /// Update the terminator instructions in block to account for changes to the
- /// layout. If the block previously used a fallthrough, it may now need a
- /// branch, and if it previously used branching it may now be able to use a
- /// fallthrough.
- void updateTerminator();
+ /// Returns true if this and MBB belong to the same section.
+ bool sameSection(const MachineBasicBlock *MBB) const {
+ return getSectionID() == MBB->getSectionID();
+ }
+
+ /// Update the terminator instructions in block to account for changes to
+ /// block layout which may have been made. PreviousLayoutSuccessor should be
+ /// set to the block which may have been used as fallthrough before the block
+ /// layout was modified. If the block previously fell through to that block,
+ /// it may now need a branch. If it previously branched to another block, it
+ /// may now be able to fallthrough to the current layout successor.
+ void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor);
// Machine-CFG mutators
@@ -588,7 +676,9 @@ public:
///
/// This function updates LiveVariables, MachineDominatorTree, and
/// MachineLoopInfo, as applicable.
- MachineBasicBlock *SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P);
+ MachineBasicBlock *
+ SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P,
+ std::vector<SparseBitVector<>> *LiveInSets = nullptr);
/// Check if the edge between this block and the given successor \p
/// Succ, can be split. If this returns true a subsequent call to
@@ -737,16 +827,6 @@ public:
/// instead of basic block \p Old.
void replacePhiUsesWith(MachineBasicBlock *Old, MachineBasicBlock *New);
- /// Various pieces of code can cause excess edges in the CFG to be inserted.
- /// If we have proven that MBB can only branch to DestA and DestB, remove any
- /// other MBB successors from the CFG. DestA and DestB can be null. Besides
- /// DestA and DestB, retain other edges leading to LandingPads (currently
- /// there can be only one; we don't check or require that here). Note it is
- /// possible that DestA and/or DestB are LandingPads.
- bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
- MachineBasicBlock *DestB,
- bool IsCond);
-
/// Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE
/// and DBG_LABEL instructions. Return UnknownLoc if there is none.
DebugLoc findDebugLoc(instr_iterator MBBI);
@@ -781,7 +861,7 @@ public:
///
/// \p Reg must be a physical register.
LivenessQueryResult computeRegisterLiveness(const TargetRegisterInfo *TRI,
- unsigned Reg,
+ MCRegister Reg,
const_iterator Before,
unsigned Neighborhood = 10) const;
@@ -946,7 +1026,7 @@ public:
template<typename IterT>
inline IterT skipDebugInstructionsForward(IterT It, IterT End) {
while (It != End && It->isDebugInstr())
- It++;
+ ++It;
return It;
}
@@ -957,10 +1037,31 @@ inline IterT skipDebugInstructionsForward(IterT It, IterT End) {
template<class IterT>
inline IterT skipDebugInstructionsBackward(IterT It, IterT Begin) {
while (It != Begin && It->isDebugInstr())
- It--;
+ --It;
return It;
}
+/// Increment \p It, then continue incrementing it while it points to a debug
+/// instruction. A replacement for std::next.
+template <typename IterT> inline IterT next_nodbg(IterT It, IterT End) {
+ return skipDebugInstructionsForward(std::next(It), End);
+}
+
+/// Decrement \p It, then continue decrementing it while it points to a debug
+/// instruction. A replacement for std::prev.
+template <typename IterT> inline IterT prev_nodbg(IterT It, IterT Begin) {
+ return skipDebugInstructionsBackward(std::prev(It), Begin);
+}
+
+/// Construct a range iterator which begins at \p It and moves forwards until
+/// \p End is reached, skipping any debug instructions.
+template <typename IterT>
+inline auto instructionsWithoutDebug(IterT It, IterT End) {
+ return make_filter_range(make_range(It, End), [](const MachineInstr &MI) {
+ return !MI.isDebugInstr();
+ });
+}
+
} // end namespace llvm
#endif // LLVM_CODEGEN_MACHINEBASICBLOCK_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
index 2a826d0b64c0..0f8d69ebd7da 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineBlockFrequencyInfo.h
@@ -66,6 +66,8 @@ public:
bool isIrrLoopHeader(const MachineBasicBlock *MBB);
+ void setBlockFreq(const MachineBasicBlock *MBB, uint64_t Freq);
+
const MachineFunction *getFunction() const;
const MachineBranchProbabilityInfo *getMBPI() const;
void view(const Twine &Name, bool isSimple = true) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineCombinerPattern.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
index 149fe043d1f5..e9f52fb064e1 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineCombinerPattern.h
@@ -25,6 +25,10 @@ enum class MachineCombinerPattern {
REASSOC_XA_BY,
REASSOC_XA_YB,
+ // These are patterns matched by the PowerPC to reassociate FMA chains.
+ REASSOC_XY_AMM_BMM,
+ REASSOC_XMM_AMM_BMM,
+
// These are multiply-add patterns matched by the AArch64 machine combiner.
MULADDW_OP1,
MULADDW_OP2,
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineConstantPool.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineConstantPool.h
index 4d07b620a4b4..cfc9ca88c976 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineConstantPool.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineConstantPool.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/MC/SectionKind.h"
+#include "llvm/Support/Alignment.h"
#include <climits>
#include <vector>
@@ -45,7 +46,7 @@ public:
Type *getType() const { return Ty; }
virtual int getExistingMachineCPValue(MachineConstantPool *CP,
- unsigned Alignment) = 0;
+ Align Alignment) = 0;
virtual void addSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
@@ -71,31 +72,27 @@ public:
MachineConstantPoolValue *MachineCPVal;
} Val;
- /// The required alignment for this entry. The top bit is set when Val is
- /// a target specific MachineConstantPoolValue.
- unsigned Alignment;
+ /// The required alignment for this entry.
+ Align Alignment;
- MachineConstantPoolEntry(const Constant *V, unsigned A)
- : Alignment(A) {
+ bool IsMachineConstantPoolEntry;
+
+ MachineConstantPoolEntry(const Constant *V, Align A)
+ : Alignment(A), IsMachineConstantPoolEntry(false) {
Val.ConstVal = V;
}
- MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned A)
- : Alignment(A) {
+ MachineConstantPoolEntry(MachineConstantPoolValue *V, Align A)
+ : Alignment(A), IsMachineConstantPoolEntry(true) {
Val.MachineCPVal = V;
- Alignment |= 1U << (sizeof(unsigned) * CHAR_BIT - 1);
}
/// isMachineConstantPoolEntry - Return true if the MachineConstantPoolEntry
/// is indeed a target specific constantpool entry, not a wrapper over a
/// Constant.
- bool isMachineConstantPoolEntry() const {
- return (int)Alignment < 0;
- }
+ bool isMachineConstantPoolEntry() const { return IsMachineConstantPoolEntry; }
- int getAlignment() const {
- return Alignment & ~(1 << (sizeof(unsigned) * CHAR_BIT - 1));
- }
+ Align getAlign() const { return Alignment; }
Type *getType() const;
@@ -118,7 +115,7 @@ public:
/// address of the function constant pool values.
/// The machine constant pool.
class MachineConstantPool {
- unsigned PoolAlignment; ///< The alignment for the pool.
+ Align PoolAlignment; ///< The alignment for the pool.
std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
/// MachineConstantPoolValues that use an existing MachineConstantPoolEntry.
DenseSet<MachineConstantPoolValue*> MachineCPVsSharingEntries;
@@ -132,16 +129,15 @@ public:
: PoolAlignment(1), DL(DL) {}
~MachineConstantPool();
- /// getConstantPoolAlignment - Return the alignment required by
- /// the whole constant pool, of which the first element must be aligned.
- unsigned getConstantPoolAlignment() const { return PoolAlignment; }
+ /// Return the alignment required by the whole constant pool, of which the
+ /// first element must be aligned.
+ Align getConstantPoolAlign() const { return PoolAlignment; }
/// getConstantPoolIndex - Create a new entry in the constant pool or return
/// an existing one. User must specify the minimum required alignment for
/// the object.
- unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment);
- unsigned getConstantPoolIndex(MachineConstantPoolValue *V,
- unsigned Alignment);
+ unsigned getConstantPoolIndex(const Constant *C, Align Alignment);
+ unsigned getConstantPoolIndex(MachineConstantPoolValue *V, Align Alignment);
/// isEmpty - Return true if this constant pool contains no constants.
bool isEmpty() const { return Constants.empty(); }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineDominators.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineDominators.h
index 9d31232c9b95..cf3af4d38223 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineDominators.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineDominators.h
@@ -93,15 +93,6 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const override;
- /// getRoots - Return the root blocks of the current CFG. This may include
- /// multiple blocks if we are computing post dominators. For forward
- /// dominators, this will always be a single block (the entry node).
- ///
- const SmallVectorImpl<MachineBasicBlock*> &getRoots() const {
- applySplitCriticalEdges();
- return DT->getRoots();
- }
-
MachineBasicBlock *getRoot() const {
applySplitCriticalEdges();
return DT->getRoot();
@@ -270,7 +261,8 @@ template <class T> struct GraphTraits;
template <>
struct GraphTraits<MachineDomTreeNode *>
: public MachineDomTreeGraphTraitsBase<MachineDomTreeNode,
- MachineDomTreeNode::iterator> {};
+ MachineDomTreeNode::const_iterator> {
+};
template <>
struct GraphTraits<const MachineDomTreeNode *>
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 05b34d92651c..5cd7f9cde674 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -460,22 +460,34 @@ public:
Objects[ObjectIdx+NumFixedObjects].Size = Size;
}
+ LLVM_ATTRIBUTE_DEPRECATED(inline unsigned getObjectAlignment(int ObjectIdx)
+ const,
+ "Use getObjectAlign instead") {
+ return getObjectAlign(ObjectIdx).value();
+ }
+
/// Return the alignment of the specified stack object.
- unsigned getObjectAlignment(int ObjectIdx) const {
- assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ Align getObjectAlign(int ObjectIdx) const {
+ assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
- return Objects[ObjectIdx + NumFixedObjects].Alignment.value();
+ return Objects[ObjectIdx + NumFixedObjects].Alignment;
}
/// setObjectAlignment - Change the alignment of the specified stack object.
- void setObjectAlignment(int ObjectIdx, unsigned Align) {
- assert(unsigned(ObjectIdx+NumFixedObjects) < Objects.size() &&
+ void setObjectAlignment(int ObjectIdx, Align Alignment) {
+ assert(unsigned(ObjectIdx + NumFixedObjects) < Objects.size() &&
"Invalid Object Idx!");
- Objects[ObjectIdx + NumFixedObjects].Alignment = assumeAligned(Align);
+ Objects[ObjectIdx + NumFixedObjects].Alignment = Alignment;
// Only ensure max alignment for the default stack.
if (getStackID(ObjectIdx) == 0)
- ensureMaxAlignment(Align);
+ ensureMaxAlignment(Alignment);
+ }
+
+ LLVM_ATTRIBUTE_DEPRECATED(inline void setObjectAlignment(int ObjectIdx,
+ unsigned Align),
+ "Use the version that takes Align instead") {
+ setObjectAlignment(ObjectIdx, assumeAligned(Align));
}
/// Return the underlying Alloca of the specified
@@ -563,12 +575,19 @@ public:
/// Return the alignment in bytes that this function must be aligned to,
/// which is greater than the default stack alignment provided by the target.
- unsigned getMaxAlignment() const { return MaxAlignment.value(); }
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getMaxAlignment() const,
+ "Use getMaxAlign instead") {
+ return MaxAlignment.value();
+ }
+ /// Return the alignment in bytes that this function must be aligned to,
+ /// which is greater than the default stack alignment provided by the target.
+ Align getMaxAlign() const { return MaxAlignment; }
/// Make sure the function is at least Align bytes aligned.
void ensureMaxAlignment(Align Alignment);
- /// FIXME: Remove this once transition to Align is over.
- inline void ensureMaxAlignment(unsigned Align) {
+
+ LLVM_ATTRIBUTE_DEPRECATED(inline void ensureMaxAlignment(unsigned Align),
+ "Use the version that uses Align instead") {
ensureMaxAlignment(assumeAligned(Align));
}
@@ -736,11 +755,12 @@ public:
/// a nonnegative identifier to represent it.
int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot,
const AllocaInst *Alloca = nullptr, uint8_t ID = 0);
- /// FIXME: Remove this function when transition to Align is over.
- inline int CreateStackObject(uint64_t Size, unsigned Alignment,
- bool isSpillSlot,
- const AllocaInst *Alloca = nullptr,
- uint8_t ID = 0) {
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline int CreateStackObject(uint64_t Size, unsigned Alignment,
+ bool isSpillSlot,
+ const AllocaInst *Alloca = nullptr,
+ uint8_t ID = 0),
+ "Use CreateStackObject that takes an Align instead") {
return CreateStackObject(Size, assumeAligned(Alignment), isSpillSlot,
Alloca, ID);
}
@@ -748,8 +768,9 @@ public:
/// Create a new statically sized stack object that represents a spill slot,
/// returning a nonnegative identifier to represent it.
int CreateSpillStackObject(uint64_t Size, Align Alignment);
- /// FIXME: Remove this function when transition to Align is over.
- inline int CreateSpillStackObject(uint64_t Size, unsigned Alignment) {
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline int CreateSpillStackObject(uint64_t Size, unsigned Alignment),
+ "Use CreateSpillStackObject that takes an Align instead") {
return CreateSpillStackObject(Size, assumeAligned(Alignment));
}
@@ -764,7 +785,9 @@ public:
/// created, whether or not the index returned is actually used.
int CreateVariableSizedObject(Align Alignment, const AllocaInst *Alloca);
/// FIXME: Remove this function when transition to Align is over.
- int CreateVariableSizedObject(unsigned Alignment, const AllocaInst *Alloca) {
+ LLVM_ATTRIBUTE_DEPRECATED(int CreateVariableSizedObject(
+ unsigned Alignment, const AllocaInst *Alloca),
+ "Use the version that takes an Align instead") {
return CreateVariableSizedObject(assumeAligned(Alignment), Alloca);
}
@@ -777,8 +800,8 @@ public:
/// Used by prolog/epilog inserter to set the function's callee saved
/// information.
- void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
- CSInfo = CSI;
+ void setCalleeSavedInfo(std::vector<CalleeSavedInfo> CSI) {
+ CSInfo = std::move(CSI);
}
/// Has the callee saved info been calculated yet?
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFunction.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFunction.h
index 7f4a3a8c2f97..809c21dd26fc 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -20,11 +20,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Analysis/EHPersonalities.h"
@@ -35,8 +32,8 @@
#include "llvm/Support/ArrayRecycler.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Recycler.h"
+#include "llvm/Target/TargetOptions.h"
#include <cassert>
#include <cstdint>
#include <memory>
@@ -49,10 +46,12 @@ class BasicBlock;
class BlockAddress;
class DataLayout;
class DebugLoc;
+struct DenormalMode;
class DIExpression;
class DILocalVariable;
class DILocation;
class Function;
+class GISelChangeObserver;
class GlobalValue;
class LLVMTargetMachine;
class MachineConstantPool;
@@ -64,10 +63,12 @@ class MachineRegisterInfo;
class MCContext;
class MCInstrDesc;
class MCSymbol;
+class MCSection;
class Pass;
class PseudoSourceValueManager;
class raw_ostream;
class SlotIndexes;
+class StringRef;
class TargetRegisterClass;
class TargetSubtargetInfo;
struct WasmEHFuncInfo;
@@ -143,6 +144,8 @@ public:
// operands, this also means that all generic virtual registers have been
// constrained to virtual registers (assigned to register classes) and that
// all sizes attached to them have been eliminated.
+ // TiedOpsRewritten: The twoaddressinstruction pass will set this flag, it
+ // means that tied-def have been rewritten to meet the RegConstraint.
enum class Property : unsigned {
IsSSA,
NoPHIs,
@@ -152,7 +155,8 @@ public:
Legalized,
RegBankSelected,
Selected,
- LastProperty = Selected,
+ TiedOpsRewritten,
+ LastProperty = TiedOpsRewritten,
};
bool hasProperty(Property P) const {
@@ -221,7 +225,7 @@ struct LandingPadInfo {
};
class MachineFunction {
- const Function &F;
+ Function &F;
const LLVMTargetMachine &Target;
const TargetSubtargetInfo *STI;
MCContext &Ctx;
@@ -243,6 +247,9 @@ class MachineFunction {
// Keep track of jump tables for switch instructions
MachineJumpTableInfo *JumpTableInfo;
+ // Keep track of the function section.
+ MCSection *Section = nullptr;
+
// Keeps track of Wasm exception handling related data. This will be null for
// functions that aren't using a wasm EH personality.
WasmEHFuncInfo *WasmEHInfo = nullptr;
@@ -256,6 +263,12 @@ class MachineFunction {
// numbered and this vector keeps track of the mapping from ID's to MBB's.
std::vector<MachineBasicBlock*> MBBNumbering;
+ // Unary encoding of basic block symbols is used to reduce size of ".strtab".
+ // Basic block number 'i' gets a prefix of length 'i'. The ith character also
+ // denotes the type of basic block number 'i'. Return blocks are marked with
+ // 'r', landing pads with 'l' and regular blocks with 'a'.
+ std::vector<char> BBSectionsSymbolPrefix;
+
// Pool-allocate MachineFunction-lifetime and IR objects.
BumpPtrAllocator Allocator;
@@ -331,6 +344,9 @@ class MachineFunction {
bool HasEHScopes = false;
bool HasEHFunclets = false;
+ /// Section Type for basic blocks, only relevant with basic block sections.
+ BasicBlockSection BBSectionsType = BasicBlockSection::None;
+
/// List of C++ TypeInfo used.
std::vector<const GlobalValue *> TypeInfos;
@@ -384,9 +400,9 @@ public:
/// For now we support only cases when argument is transferred through one
/// register.
struct ArgRegPair {
- unsigned Reg;
+ Register Reg;
uint16_t ArgNo;
- ArgRegPair(unsigned R, unsigned Arg) : Reg(R), ArgNo(Arg) {
+ ArgRegPair(Register R, unsigned Arg) : Reg(R), ArgNo(Arg) {
assert(Arg < (1 << 16) && "Arg out of range");
}
};
@@ -396,6 +412,7 @@ public:
private:
Delegate *TheDelegate = nullptr;
+ GISelChangeObserver *Observer = nullptr;
using CallSiteInfoMap = DenseMap<const MachineInstr *, CallSiteInfo>;
/// Map a call instruction to call site arguments forwarding info.
@@ -414,7 +431,7 @@ public:
using VariableDbgInfoMapTy = SmallVector<VariableDbgInfo, 4>;
VariableDbgInfoMapTy VariableDbgInfos;
- MachineFunction(const Function &F, const LLVMTargetMachine &Target,
+ MachineFunction(Function &F, const LLVMTargetMachine &Target,
const TargetSubtargetInfo &STI, unsigned FunctionNum,
MachineModuleInfo &MMI);
MachineFunction(const MachineFunction &) = delete;
@@ -444,15 +461,28 @@ public:
TheDelegate = delegate;
}
+ void setObserver(GISelChangeObserver *O) { Observer = O; }
+
+ GISelChangeObserver *getObserver() const { return Observer; }
+
MachineModuleInfo &getMMI() const { return MMI; }
MCContext &getContext() const { return Ctx; }
+ /// Returns the Section this function belongs to.
+ MCSection *getSection() const { return Section; }
+
+ /// Indicates the Section this function belongs to.
+ void setSection(MCSection *S) { Section = S; }
+
PseudoSourceValueManager &getPSVManager() const { return *PSVManager; }
/// Return the DataLayout attached to the Module associated to this MF.
const DataLayout &getDataLayout() const;
/// Return the LLVM function that this machine code represents
+ Function &getFunction() { return F; }
+
+ /// Return the LLVM function that this machine code represents
const Function &getFunction() const { return F; }
/// getName - Return the name of the corresponding LLVM function.
@@ -461,6 +491,26 @@ public:
/// getFunctionNumber - Return a unique ID for the current function.
unsigned getFunctionNumber() const { return FunctionNumber; }
+ /// Returns true if this function has basic block sections enabled.
+ bool hasBBSections() const {
+ return (BBSectionsType == BasicBlockSection::All ||
+ BBSectionsType == BasicBlockSection::List);
+ }
+
+ /// Returns true if basic block labels are to be generated for this function.
+ bool hasBBLabels() const {
+ return BBSectionsType == BasicBlockSection::Labels;
+ }
+
+ void setBBSectionsType(BasicBlockSection V) { BBSectionsType = V; }
+
+ /// Creates basic block Labels for this function.
+ void createBBLabels();
+
+ /// Assign IsBeginSection IsEndSection fields for basic blocks in this
+ /// function.
+ void assignBeginEndSections();
+
/// getTarget - Return the target machine this machine code is compiled with
const LLVMTargetMachine &getTarget() const { return Target; }
@@ -643,7 +693,7 @@ public:
/// addLiveIn - Add the specified physical register as a live-in value and
/// create a corresponding virtual register for it.
- unsigned addLiveIn(unsigned PReg, const TargetRegisterClass *RC);
+ Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC);
//===--------------------------------------------------------------------===//
// BasicBlock accessor functions.
@@ -753,9 +803,8 @@ public:
/// explicitly deallocated.
MachineMemOperand *getMachineMemOperand(
MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s,
- unsigned base_alignment, const AAMDNodes &AAInfo = AAMDNodes(),
- const MDNode *Ranges = nullptr,
- SyncScope::ID SSID = SyncScope::System,
+ Align base_alignment, const AAMDNodes &AAInfo = AAMDNodes(),
+ const MDNode *Ranges = nullptr, SyncScope::ID SSID = SyncScope::System,
AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
AtomicOrdering FailureOrdering = AtomicOrdering::NotAtomic);
@@ -983,10 +1032,14 @@ public:
return VariableDbgInfos;
}
+ /// Start tracking the arguments passed to the call \p CallI.
void addCallArgsForwardingRegs(const MachineInstr *CallI,
CallSiteInfoImpl &&CallInfo) {
- assert(CallI->isCall());
- CallSitesInfo[CallI] = std::move(CallInfo);
+ assert(CallI->isCandidateForCallSiteEntry());
+ bool Inserted =
+ CallSitesInfo.try_emplace(CallI, std::move(CallInfo)).second;
+ (void)Inserted;
+ assert(Inserted && "Call site info not unique");
}
const CallSiteInfoMap &getCallSitesInfo() const {
@@ -996,21 +1049,24 @@ public:
/// Following functions update call site info. They should be called before
/// removing, replacing or copying call instruction.
- /// Move the call site info from \p Old to \New call site info. This function
- /// is used when we are replacing one call instruction with another one to
- /// the same callee.
- void moveCallSiteInfo(const MachineInstr *Old,
- const MachineInstr *New);
-
/// Erase the call site info for \p MI. It is used to remove a call
/// instruction from the instruction stream.
void eraseCallSiteInfo(const MachineInstr *MI);
-
/// Copy the call site info from \p Old to \ New. Its usage is when we are
/// making a copy of the instruction that will be inserted at different point
/// of the instruction stream.
void copyCallSiteInfo(const MachineInstr *Old,
const MachineInstr *New);
+
+ const std::vector<char> &getBBSectionsSymbolPrefix() const {
+ return BBSectionsSymbolPrefix;
+ }
+
+ /// Move the call site info from \p Old to \New call site info. This function
+ /// is used when we are replacing one call instruction with another one to
+ /// the same callee.
+ void moveCallSiteInfo(const MachineInstr *Old,
+ const MachineInstr *New);
};
//===--------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h
index 6d4ab3b2a2a5..970d6d7db334 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -42,7 +42,6 @@ class DIExpression;
class DILocalVariable;
class MachineBasicBlock;
class MachineFunction;
-class MachineMemOperand;
class MachineRegisterInfo;
class ModuleSlotTracker;
class raw_ostream;
@@ -106,6 +105,9 @@ public:
// known to be exact.
NoFPExcept = 1 << 14, // Instruction does not raise
// floatint-point exceptions.
+ NoMerge = 1 << 15, // Passes that drop source location info
+ // (e.g. branch folding) should skip
+ // this instruction.
};
private:
@@ -115,8 +117,6 @@ private:
// Operands are allocated by an ArrayRecycler.
MachineOperand *Operands = nullptr; // Pointer to the first operand.
unsigned NumOperands = 0; // Number of operands on instruction.
- using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
- OperandCapacity CapOperands; // Capacity of the Operands array.
uint16_t Flags = 0; // Various bits of additional
// information about machine
@@ -129,6 +129,11 @@ private:
// anything other than to convey comment
// information to AsmPrinter.
+ // OperandCapacity has uint8_t size, so it should be next to AsmPrinterFlags
+ // to properly pack.
+ using OperandCapacity = ArrayRecycler<MachineOperand>::Capacity;
+ OperandCapacity CapOperands; // Capacity of the Operands array.
+
/// Internal implementation detail class that provides out-of-line storage for
/// extra info used by the machine instruction when this info cannot be stored
/// in-line within the instruction itself.
@@ -262,6 +267,10 @@ private:
// MachineInstrs are pool-allocated and owned by MachineFunction.
friend class MachineFunction;
+ void
+ dumprImpl(const MachineRegisterInfo &MRI, unsigned Depth, unsigned MaxDepth,
+ SmallPtrSetImpl<const MachineInstr *> &AlreadySeenInstrs) const;
+
public:
MachineInstr(const MachineInstr &) = delete;
MachineInstr &operator=(const MachineInstr &) = delete;
@@ -399,10 +408,31 @@ public:
/// Returns the debug location id of this MachineInstr.
const DebugLoc &getDebugLoc() const { return debugLoc; }
+ /// Return the operand containing the offset to be used if this DBG_VALUE
+ /// instruction is indirect; will be an invalid register if this value is
+ /// not indirect, and an immediate with value 0 otherwise.
+ const MachineOperand &getDebugOffset() const {
+ assert(isDebugValue() && "not a DBG_VALUE");
+ return getOperand(1);
+ }
+ MachineOperand &getDebugOffset() {
+ assert(isDebugValue() && "not a DBG_VALUE");
+ return getOperand(1);
+ }
+
+ /// Return the operand for the debug variable referenced by
+ /// this DBG_VALUE instruction.
+ const MachineOperand &getDebugVariableOp() const;
+ MachineOperand &getDebugVariableOp();
+
/// Return the debug variable referenced by
/// this DBG_VALUE instruction.
const DILocalVariable *getDebugVariable() const;
+ /// Return the operand for the complex address expression referenced by
+ /// this DBG_VALUE instruction.
+ MachineOperand &getDebugExpressionOp();
+
/// Return the complex address expression referenced by
/// this DBG_VALUE instruction.
const DIExpression *getDebugExpression() const;
@@ -428,6 +458,11 @@ public:
/// Retuns the total number of operands.
unsigned getNumOperands() const { return NumOperands; }
+ /// Returns the total number of operands which are debug locations.
+ unsigned getNumDebugOperands() const {
+ return std::distance(debug_operands().begin(), debug_operands().end());
+ }
+
const MachineOperand& getOperand(unsigned i) const {
assert(i < getNumOperands() && "getOperand() out of range!");
return Operands[i];
@@ -437,6 +472,38 @@ public:
return Operands[i];
}
+ MachineOperand &getDebugOperand(unsigned Index) {
+ assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
+ return *(debug_operands().begin() + Index);
+ }
+ const MachineOperand &getDebugOperand(unsigned Index) const {
+ assert(Index < getNumDebugOperands() && "getDebugOperand() out of range!");
+ return *(debug_operands().begin() + Index);
+ }
+
+ /// Returns a pointer to the operand corresponding to a debug use of Reg, or
+ /// nullptr if Reg is not used in any debug operand.
+ const MachineOperand *getDebugOperandForReg(Register Reg) const {
+ const MachineOperand *RegOp =
+ find_if(debug_operands(), [Reg](const MachineOperand &Op) {
+ return Op.isReg() && Op.getReg() == Reg;
+ });
+ return RegOp == adl_end(debug_operands()) ? nullptr : RegOp;
+ }
+ MachineOperand *getDebugOperandForReg(Register Reg) {
+ MachineOperand *RegOp =
+ find_if(debug_operands(), [Reg](const MachineOperand &Op) {
+ return Op.isReg() && Op.getReg() == Reg;
+ });
+ return RegOp == adl_end(debug_operands()) ? nullptr : RegOp;
+ }
+
+ unsigned getDebugOperandIndex(const MachineOperand *Op) const {
+ assert(Op >= adl_begin(debug_operands()) &&
+ Op <= adl_end(debug_operands()) && "Expected a debug operand.");
+ return std::distance(adl_begin(debug_operands()), Op);
+ }
+
/// Returns the total number of definitions.
unsigned getNumDefs() const {
return getNumExplicitDefs() + MCID->getNumImplicitDefs();
@@ -509,6 +576,17 @@ public:
iterator_range<const_mop_iterator> implicit_operands() const {
return make_range(explicit_operands().end(), operands_end());
}
+ /// Returns a range over all operands that are used to determine the variable
+ /// location for this DBG_VALUE instruction.
+ iterator_range<mop_iterator> debug_operands() {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ return make_range(operands_begin(), operands_begin() + 1);
+ }
+ /// \copydoc debug_operands()
+ iterator_range<const_mop_iterator> debug_operands() const {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ return make_range(operands_begin(), operands_begin() + 1);
+ }
/// Returns a range over all explicit operands that are register definitions.
/// Implicit definition are not included!
iterator_range<mop_iterator> defs() {
@@ -683,6 +761,14 @@ public:
return hasProperty(MCID::Call, Type);
}
+ /// Return true if this is a call instruction that may have an associated
+ /// call site entry in the debug info.
+ bool isCandidateForCallSiteEntry(QueryType Type = IgnoreBundle) const;
+ /// Return true if copying, moving, or erasing this instruction requires
+ /// updating Call Site Info (see \ref copyCallSiteInfo, \ref moveCallSiteInfo,
+ /// \ref eraseCallSiteInfo).
+ bool shouldUpdateCallSiteInfo() const;
+
/// Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
@@ -701,7 +787,7 @@ public:
/// Returns true if this is a conditional, unconditional, or indirect branch.
/// Predicates below can be used to discriminate between
- /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+ /// these cases, and the TargetInstrInfo::analyzeBranch method can be used to
/// get more information.
bool isBranch(QueryType Type = AnyInBundle) const {
return hasProperty(MCID::Branch, Type);
@@ -715,7 +801,7 @@ public:
/// Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
- /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// block. The TargetInstrInfo::analyzeBranch method can be used to get more
/// information about this branch.
bool isConditionalBranch(QueryType Type = AnyInBundle) const {
return isBranch(Type) && !isBarrier(Type) && !isIndirectBranch(Type);
@@ -723,7 +809,7 @@ public:
/// Return true if this is a branch which always
/// transfers control flow to some other block. The
- /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// TargetInstrInfo::analyzeBranch method can be used to get more information
/// about this branch.
bool isUnconditionalBranch(QueryType Type = AnyInBundle) const {
return isBranch(Type) && isBarrier(Type) && !isIndirectBranch(Type);
@@ -1058,12 +1144,12 @@ public:
bool isDebugLabel() const { return getOpcode() == TargetOpcode::DBG_LABEL; }
bool isDebugInstr() const { return isDebugValue() || isDebugLabel(); }
- /// A DBG_VALUE is indirect iff the first operand is a register and
- /// the second operand is an immediate.
+ bool isDebugOffsetImm() const { return getDebugOffset().isImm(); }
+
+ /// A DBG_VALUE is indirect iff the location operand is a register and
+ /// the offset operand is an immediate.
bool isIndirectDebugValue() const {
- return isDebugValue()
- && getOperand(0).isReg()
- && getOperand(1).isImm();
+ return isDebugValue() && getDebugOperand(0).isReg() && isDebugOffsetImm();
}
/// A DBG_VALUE is an entry value iff its debug expression contains the
@@ -1073,7 +1159,8 @@ public:
/// Return true if the instruction is a debug value which describes a part of
/// a variable as unavailable.
bool isUndefDebugValue() const {
- return isDebugValue() && getOperand(0).isReg() && !getOperand(0).getReg().isValid();
+ return isDebugValue() && getDebugOperand(0).isReg() &&
+ !getDebugOperand(0).getReg().isValid();
}
bool isPHI() const {
@@ -1530,6 +1617,10 @@ public:
bool AddNewLine = true,
const TargetInstrInfo *TII = nullptr) const;
void dump() const;
+ /// Print on dbgs() the current instruction and the instructions defining its
+ /// operands and so on until we reach \p MaxDepth.
+ void dumpr(const MachineRegisterInfo &MRI,
+ unsigned MaxDepth = UINT_MAX) const;
/// @}
//===--------------------------------------------------------------------===//
@@ -1665,6 +1756,16 @@ public:
return getOperand(getNumExplicitDefs()).getIntrinsicID();
}
+ /// Sets all register debug operands in this debug value instruction to be
+ /// undef.
+ void setDebugValueUndef() {
+ assert(isDebugValue() && "Must be a debug value instruction.");
+ for (MachineOperand &MO : debug_operands()) {
+ if (MO.isReg())
+ MO.setReg(0);
+ }
+ }
+
private:
/// If this instruction is embedded into a MachineFunction, return the
/// MachineRegisterInfo object for the current function, otherwise
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundle.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundle.h
index 517f03e60933..8a73f9a18f47 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundle.h
@@ -238,7 +238,7 @@ struct VirtRegInfo {
/// each operand referring to Reg.
/// @returns A filled-in RegInfo struct.
VirtRegInfo AnalyzeVirtRegInBundle(
- MachineInstr &MI, unsigned Reg,
+ MachineInstr &MI, Register Reg,
SmallVectorImpl<std::pair<MachineInstr *, unsigned>> *Ops = nullptr);
/// Information about how a physical register Reg is used by a set of
@@ -281,7 +281,7 @@ struct PhysRegInfo {
///
/// @param Reg The physical register to analyze.
/// @returns A filled-in PhysRegInfo struct.
-PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, unsigned Reg,
+PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg,
const TargetRegisterInfo *TRI);
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
index 0f59563e7e1b..250cb0d78a68 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineInstrBundleIterator.h
@@ -152,8 +152,8 @@ public:
template <class OtherTy>
MachineInstrBundleIterator(
const MachineInstrBundleIterator<OtherTy, IsReverse> &I,
- typename std::enable_if<std::is_convertible<OtherTy *, Ty *>::value,
- void *>::type = nullptr)
+ std::enable_if_t<std::is_convertible<OtherTy *, Ty *>::value, void *> =
+ nullptr)
: MII(I.getInstrIterator()) {}
MachineInstrBundleIterator() : MII(nullptr) {}
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineMemOperand.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineMemOperand.h
index 7ee700c62a25..1befe93def7d 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineMemOperand.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineMemOperand.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Value.h" // PointerLikeTypeTraits<Value*>
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/DataTypes.h"
@@ -58,8 +59,8 @@ struct MachinePointerInfo {
AddrSpace = v ? v->getAddressSpace() : 0;
}
- explicit MachinePointerInfo(unsigned AddressSpace = 0)
- : V((const Value *)nullptr), Offset(0), StackID(0),
+ explicit MachinePointerInfo(unsigned AddressSpace = 0, int64_t offset = 0)
+ : V((const Value *)nullptr), Offset(offset), StackID(0),
AddrSpace(AddressSpace) {}
explicit MachinePointerInfo(
@@ -77,10 +78,10 @@ struct MachinePointerInfo {
MachinePointerInfo getWithOffset(int64_t O) const {
if (V.isNull())
- return MachinePointerInfo(AddrSpace);
+ return MachinePointerInfo(AddrSpace, Offset + O);
if (V.is<const Value*>())
- return MachinePointerInfo(V.get<const Value*>(), Offset+O, StackID);
- return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset+O,
+ return MachinePointerInfo(V.get<const Value*>(), Offset + O, StackID);
+ return MachinePointerInfo(V.get<const PseudoSourceValue*>(), Offset + O,
StackID);
}
@@ -169,7 +170,7 @@ private:
MachinePointerInfo PtrInfo;
uint64_t Size;
Flags FlagVals;
- uint16_t BaseAlignLog2; // log_2(base_alignment) + 1
+ Align BaseAlign;
MachineAtomicInfo AtomicInfo;
AAMDNodes AAInfo;
const MDNode *Ranges;
@@ -181,8 +182,7 @@ public:
/// atomic operations the atomic ordering requirements when store does not
/// occur must also be specified.
MachineMemOperand(MachinePointerInfo PtrInfo, Flags flags, uint64_t s,
- uint64_t a,
- const AAMDNodes &AAInfo = AAMDNodes(),
+ Align a, const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr,
SyncScope::ID SSID = SyncScope::System,
AtomicOrdering Ordering = AtomicOrdering::NotAtomic,
@@ -223,13 +223,21 @@ public:
/// Return the size in bits of the memory reference.
uint64_t getSizeInBits() const { return Size * 8; }
+ LLVM_ATTRIBUTE_DEPRECATED(uint64_t getAlignment() const,
+ "Use getAlign instead");
+
/// Return the minimum known alignment in bytes of the actual memory
/// reference.
- uint64_t getAlignment() const;
+ Align getAlign() const;
+
+ LLVM_ATTRIBUTE_DEPRECATED(uint64_t getBaseAlignment() const,
+ "Use getBaseAlign instead") {
+ return BaseAlign.value();
+ }
/// Return the minimum known alignment in bytes of the base address, without
/// the offset.
- uint64_t getBaseAlignment() const { return (1ull << BaseAlignLog2) >> 1; }
+ Align getBaseAlign() const { return BaseAlign; }
/// Return the AA tags for the memory reference.
AAMDNodes getAAInfo() const { return AAInfo; }
@@ -307,7 +315,7 @@ public:
LHS.getFlags() == RHS.getFlags() &&
LHS.getAAInfo() == RHS.getAAInfo() &&
LHS.getRanges() == RHS.getRanges() &&
- LHS.getAlignment() == RHS.getAlignment() &&
+ LHS.getAlign() == RHS.getAlign() &&
LHS.getAddrSpace() == RHS.getAddrSpace();
}
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h
index 6902dada2423..0ee595b5b5ce 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineModuleInfo.h
@@ -165,9 +165,9 @@ public:
/// Returns the MachineFunction constructed for the IR function \p F.
/// Creates a new MachineFunction if none exists yet.
- MachineFunction &getOrCreateMachineFunction(const Function &F);
+ MachineFunction &getOrCreateMachineFunction(Function &F);
- /// \bried Returns the MachineFunction associated to IR function \p F if there
+ /// \brief Returns the MachineFunction associated to IR function \p F if there
/// is one, otherwise nullptr.
MachineFunction *getMachineFunction(const Function &F) const;
@@ -233,13 +233,6 @@ public:
/// to emit them as well, return the whole set.
ArrayRef<MCSymbol *> getAddrLabelSymbolToEmit(const BasicBlock *BB);
- /// If the specified function has had any references to address-taken blocks
- /// generated, but the block got deleted, return the symbol now so we can
- /// emit it. This prevents emitting a reference to a symbol that has no
- /// definition.
- void takeDeletedSymbolsForFunction(const Function *F,
- std::vector<MCSymbol*> &Result);
-
/// \name Exception Handling
/// \{
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h
index 9ba2b01cb4bd..0f252137364c 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -612,14 +612,14 @@ public:
/// It is sometimes necessary to detach the register mask pointer from its
/// machine operand. This static method can be used for such detached bit
/// mask pointers.
- static bool clobbersPhysReg(const uint32_t *RegMask, unsigned PhysReg) {
+ static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg) {
// See TargetRegisterInfo.h.
assert(PhysReg < (1u << 30) && "Not a physical register");
return !(RegMask[PhysReg / 32] & (1u << PhysReg % 32));
}
/// clobbersPhysReg - Returns true if this RegMask operand clobbers PhysReg.
- bool clobbersPhysReg(unsigned PhysReg) const {
+ bool clobbersPhysReg(MCRegister PhysReg) const {
return clobbersPhysReg(getRegMask(), PhysReg);
}
@@ -698,6 +698,11 @@ public:
Contents.RegMask = RegMaskPtr;
}
+ void setIntrinsicID(Intrinsic::ID IID) {
+ assert(isIntrinsicID() && "Wrong MachineOperand mutator");
+ Contents.IntrinsicID = IID;
+ }
+
void setPredicate(unsigned Predicate) {
assert(isPredicate() && "Wrong MachineOperand mutator");
Contents.Pred = Predicate;
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
index b2f8ad55fbd8..8cc5909c40b7 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineOptimizationRemarkEmitter.h
@@ -159,7 +159,7 @@ public:
/// that non-trivial false positives can be quickly detected by the user.
bool allowExtraAnalysis(StringRef PassName) const {
return (
- MF.getFunction().getContext().getRemarkStreamer() ||
+ MF.getFunction().getContext().getLLVMRemarkStreamer() ||
MF.getFunction().getContext().getDiagHandlerPtr()->isAnyRemarkEnabled(
PassName));
}
@@ -172,7 +172,7 @@ public:
// remarks enabled. We can't currently check whether remarks are requested
// for the calling pass since that requires actually building the remark.
- if (MF.getFunction().getContext().getRemarkStreamer() ||
+ if (MF.getFunction().getContext().getLLVMRemarkStreamer() ||
MF.getFunction()
.getContext()
.getDiagHandlerPtr()
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePipeliner.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePipeliner.h
index 24e85a953d47..8b2c27e7b888 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePipeliner.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePipeliner.h
@@ -43,6 +43,7 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
+#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
@@ -60,6 +61,7 @@ extern cl::opt<bool> SwpEnableCopyToPhi;
class MachinePipeliner : public MachineFunctionPass {
public:
MachineFunction *MF = nullptr;
+ MachineOptimizationRemarkEmitter *ORE = nullptr;
const MachineLoopInfo *MLI = nullptr;
const MachineDominatorTree *MDT = nullptr;
const InstrItineraryData *InstrItins;
@@ -96,6 +98,7 @@ public:
AU.addRequired<MachineLoopInfo>();
AU.addRequired<MachineDominatorTree>();
AU.addRequired<LiveIntervals>();
+ AU.addRequired<MachineOptimizationRemarkEmitterPass>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -330,10 +333,22 @@ public:
NodeSet() = default;
NodeSet(iterator S, iterator E) : Nodes(S, E), HasRecurrence(true) {
Latency = 0;
- for (unsigned i = 0, e = Nodes.size(); i < e; ++i)
- for (const SDep &Succ : Nodes[i]->Succs)
- if (Nodes.count(Succ.getSUnit()))
- Latency += Succ.getLatency();
+ for (unsigned i = 0, e = Nodes.size(); i < e; ++i) {
+ DenseMap<SUnit *, unsigned> SuccSUnitLatency;
+ for (const SDep &Succ : Nodes[i]->Succs) {
+ auto SuccSUnit = Succ.getSUnit();
+ if (!Nodes.count(SuccSUnit))
+ continue;
+ unsigned CurLatency = Succ.getLatency();
+ unsigned MaxLatency = 0;
+ if (SuccSUnitLatency.count(SuccSUnit))
+ MaxLatency = SuccSUnitLatency[SuccSUnit];
+ if (CurLatency > MaxLatency)
+ SuccSUnitLatency[SuccSUnit] = CurLatency;
+ }
+ for (auto SUnitLatency : SuccSUnitLatency)
+ Latency += SUnitLatency.second;
+ }
}
bool insert(SUnit *SU) { return Nodes.insert(SU); }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePostDominators.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePostDominators.h
index cb258b5e7b21..cee4294f6317 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePostDominators.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachinePostDominators.h
@@ -33,12 +33,14 @@ public:
MachinePostDominatorTree();
- FunctionPass *createMachinePostDominatorTreePass();
-
- const SmallVectorImpl<MachineBasicBlock *> &getRoots() const {
- return PDT->getRoots();
+ PostDomTreeT &getBase() {
+ if (!PDT)
+ PDT.reset(new PostDomTreeT());
+ return *PDT;
}
+ FunctionPass *createMachinePostDominatorTreePass();
+
MachineDomTreeNode *getRootNode() const { return PDT->getRootNode(); }
MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegisterInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
index 488a5a55a169..35aab5018fa4 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -57,7 +57,7 @@ public:
public:
virtual ~Delegate() = default;
- virtual void MRI_NoteNewVirtualRegister(unsigned Reg) = 0;
+ virtual void MRI_NoteNewVirtualRegister(Register Reg) = 0;
};
private:
@@ -98,7 +98,7 @@ private:
/// first member of the pair being non-zero. If the hinted register is
/// virtual, it means the allocator should prefer the physical register
/// allocated to it if any.
- IndexedMap<std::pair<unsigned, SmallVector<unsigned, 4>>,
+ IndexedMap<std::pair<Register, SmallVector<Register, 4>>,
VirtReg2IndexFunctor> RegAllocHints;
/// PhysRegUseDefLists - This is an array of the head of the use/def list for
@@ -143,7 +143,7 @@ private:
/// Live in values are typically arguments in registers. LiveIn values are
/// allowed to have virtual registers associated with them, stored in the
/// second element.
- std::vector<std::pair<unsigned, unsigned>> LiveIns;
+ std::vector<std::pair<MCRegister, Register>> LiveIns;
public:
explicit MachineRegisterInfo(MachineFunction *MF);
@@ -232,7 +232,7 @@ public:
/// Disables the register from the list of CSRs.
/// I.e. the register will not appear as part of the CSR mask.
/// \see UpdatedCalleeSavedRegs.
- void disableCalleeSavedRegister(unsigned Reg);
+ void disableCalleeSavedRegister(MCRegister Reg);
/// Returns list of callee saved registers.
/// The function returns the updated CSR list (after taking into account
@@ -253,7 +253,7 @@ public:
void moveOperands(MachineOperand *Dst, MachineOperand *Src, unsigned NumOps);
/// Verify the sanity of the use list for Reg.
- void verifyUseList(unsigned Reg) const;
+ void verifyUseList(Register Reg) const;
/// Verify the use list of all registers.
void verifyUseLists() const;
@@ -278,12 +278,12 @@ public:
/// register.
using reg_iterator =
defusechain_iterator<true, true, false, true, false, false>;
- reg_iterator reg_begin(unsigned RegNo) const {
+ reg_iterator reg_begin(Register RegNo) const {
return reg_iterator(getRegUseDefListHead(RegNo));
}
static reg_iterator reg_end() { return reg_iterator(nullptr); }
- inline iterator_range<reg_iterator> reg_operands(unsigned Reg) const {
+ inline iterator_range<reg_iterator> reg_operands(Register Reg) const {
return make_range(reg_begin(Reg), reg_end());
}
@@ -291,7 +291,7 @@ public:
/// of the specified register, stepping by MachineInstr.
using reg_instr_iterator =
defusechain_instr_iterator<true, true, false, false, true, false>;
- reg_instr_iterator reg_instr_begin(unsigned RegNo) const {
+ reg_instr_iterator reg_instr_begin(Register RegNo) const {
return reg_instr_iterator(getRegUseDefListHead(RegNo));
}
static reg_instr_iterator reg_instr_end() {
@@ -299,7 +299,7 @@ public:
}
inline iterator_range<reg_instr_iterator>
- reg_instructions(unsigned Reg) const {
+ reg_instructions(Register Reg) const {
return make_range(reg_instr_begin(Reg), reg_instr_end());
}
@@ -307,20 +307,20 @@ public:
/// of the specified register, stepping by bundle.
using reg_bundle_iterator =
defusechain_instr_iterator<true, true, false, false, false, true>;
- reg_bundle_iterator reg_bundle_begin(unsigned RegNo) const {
+ reg_bundle_iterator reg_bundle_begin(Register RegNo) const {
return reg_bundle_iterator(getRegUseDefListHead(RegNo));
}
static reg_bundle_iterator reg_bundle_end() {
return reg_bundle_iterator(nullptr);
}
- inline iterator_range<reg_bundle_iterator> reg_bundles(unsigned Reg) const {
+ inline iterator_range<reg_bundle_iterator> reg_bundles(Register Reg) const {
return make_range(reg_bundle_begin(Reg), reg_bundle_end());
}
/// reg_empty - Return true if there are no instructions using or defining the
/// specified register (it may be live-in).
- bool reg_empty(unsigned RegNo) const { return reg_begin(RegNo) == reg_end(); }
+ bool reg_empty(Register RegNo) const { return reg_begin(RegNo) == reg_end(); }
/// reg_nodbg_iterator/reg_nodbg_begin/reg_nodbg_end - Walk all defs and uses
/// of the specified register, skipping those marked as Debug.
@@ -334,7 +334,7 @@ public:
}
inline iterator_range<reg_nodbg_iterator>
- reg_nodbg_operands(unsigned Reg) const {
+ reg_nodbg_operands(Register Reg) const {
return make_range(reg_nodbg_begin(Reg), reg_nodbg_end());
}
@@ -343,7 +343,7 @@ public:
/// skipping those marked as Debug.
using reg_instr_nodbg_iterator =
defusechain_instr_iterator<true, true, true, false, true, false>;
- reg_instr_nodbg_iterator reg_instr_nodbg_begin(unsigned RegNo) const {
+ reg_instr_nodbg_iterator reg_instr_nodbg_begin(Register RegNo) const {
return reg_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static reg_instr_nodbg_iterator reg_instr_nodbg_end() {
@@ -351,7 +351,7 @@ public:
}
inline iterator_range<reg_instr_nodbg_iterator>
- reg_nodbg_instructions(unsigned Reg) const {
+ reg_nodbg_instructions(Register Reg) const {
return make_range(reg_instr_nodbg_begin(Reg), reg_instr_nodbg_end());
}
@@ -360,7 +360,7 @@ public:
/// skipping those marked as Debug.
using reg_bundle_nodbg_iterator =
defusechain_instr_iterator<true, true, true, false, false, true>;
- reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(unsigned RegNo) const {
+ reg_bundle_nodbg_iterator reg_bundle_nodbg_begin(Register RegNo) const {
return reg_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static reg_bundle_nodbg_iterator reg_bundle_nodbg_end() {
@@ -368,7 +368,7 @@ public:
}
inline iterator_range<reg_bundle_nodbg_iterator>
- reg_nodbg_bundles(unsigned Reg) const {
+ reg_nodbg_bundles(Register Reg) const {
return make_range(reg_bundle_nodbg_begin(Reg), reg_bundle_nodbg_end());
}
@@ -381,12 +381,12 @@ public:
/// def_iterator/def_begin/def_end - Walk all defs of the specified register.
using def_iterator =
defusechain_iterator<false, true, false, true, false, false>;
- def_iterator def_begin(unsigned RegNo) const {
+ def_iterator def_begin(Register RegNo) const {
return def_iterator(getRegUseDefListHead(RegNo));
}
static def_iterator def_end() { return def_iterator(nullptr); }
- inline iterator_range<def_iterator> def_operands(unsigned Reg) const {
+ inline iterator_range<def_iterator> def_operands(Register Reg) const {
return make_range(def_begin(Reg), def_end());
}
@@ -394,7 +394,7 @@ public:
/// specified register, stepping by MachineInst.
using def_instr_iterator =
defusechain_instr_iterator<false, true, false, false, true, false>;
- def_instr_iterator def_instr_begin(unsigned RegNo) const {
+ def_instr_iterator def_instr_begin(Register RegNo) const {
return def_instr_iterator(getRegUseDefListHead(RegNo));
}
static def_instr_iterator def_instr_end() {
@@ -402,7 +402,7 @@ public:
}
inline iterator_range<def_instr_iterator>
- def_instructions(unsigned Reg) const {
+ def_instructions(Register Reg) const {
return make_range(def_instr_begin(Reg), def_instr_end());
}
@@ -410,26 +410,26 @@ public:
/// specified register, stepping by bundle.
using def_bundle_iterator =
defusechain_instr_iterator<false, true, false, false, false, true>;
- def_bundle_iterator def_bundle_begin(unsigned RegNo) const {
+ def_bundle_iterator def_bundle_begin(Register RegNo) const {
return def_bundle_iterator(getRegUseDefListHead(RegNo));
}
static def_bundle_iterator def_bundle_end() {
return def_bundle_iterator(nullptr);
}
- inline iterator_range<def_bundle_iterator> def_bundles(unsigned Reg) const {
+ inline iterator_range<def_bundle_iterator> def_bundles(Register Reg) const {
return make_range(def_bundle_begin(Reg), def_bundle_end());
}
/// def_empty - Return true if there are no instructions defining the
/// specified register (it may be live-in).
- bool def_empty(unsigned RegNo) const { return def_begin(RegNo) == def_end(); }
+ bool def_empty(Register RegNo) const { return def_begin(RegNo) == def_end(); }
- StringRef getVRegName(unsigned Reg) const {
+ StringRef getVRegName(Register Reg) const {
return VReg2Name.inBounds(Reg) ? StringRef(VReg2Name[Reg]) : "";
}
- void insertVRegByName(StringRef Name, unsigned Reg) {
+ void insertVRegByName(StringRef Name, Register Reg) {
assert((Name.empty() || VRegNames.find(Name) == VRegNames.end()) &&
"Named VRegs Must be Unique.");
if (!Name.empty()) {
@@ -441,7 +441,7 @@ public:
/// Return true if there is exactly one operand defining the specified
/// register.
- bool hasOneDef(unsigned RegNo) const {
+ bool hasOneDef(Register RegNo) const {
def_iterator DI = def_begin(RegNo);
if (DI == def_end())
return false;
@@ -451,12 +451,12 @@ public:
/// use_iterator/use_begin/use_end - Walk all uses of the specified register.
using use_iterator =
defusechain_iterator<true, false, false, true, false, false>;
- use_iterator use_begin(unsigned RegNo) const {
+ use_iterator use_begin(Register RegNo) const {
return use_iterator(getRegUseDefListHead(RegNo));
}
static use_iterator use_end() { return use_iterator(nullptr); }
- inline iterator_range<use_iterator> use_operands(unsigned Reg) const {
+ inline iterator_range<use_iterator> use_operands(Register Reg) const {
return make_range(use_begin(Reg), use_end());
}
@@ -464,7 +464,7 @@ public:
/// specified register, stepping by MachineInstr.
using use_instr_iterator =
defusechain_instr_iterator<true, false, false, false, true, false>;
- use_instr_iterator use_instr_begin(unsigned RegNo) const {
+ use_instr_iterator use_instr_begin(Register RegNo) const {
return use_instr_iterator(getRegUseDefListHead(RegNo));
}
static use_instr_iterator use_instr_end() {
@@ -472,7 +472,7 @@ public:
}
inline iterator_range<use_instr_iterator>
- use_instructions(unsigned Reg) const {
+ use_instructions(Register Reg) const {
return make_range(use_instr_begin(Reg), use_instr_end());
}
@@ -480,24 +480,24 @@ public:
/// specified register, stepping by bundle.
using use_bundle_iterator =
defusechain_instr_iterator<true, false, false, false, false, true>;
- use_bundle_iterator use_bundle_begin(unsigned RegNo) const {
+ use_bundle_iterator use_bundle_begin(Register RegNo) const {
return use_bundle_iterator(getRegUseDefListHead(RegNo));
}
static use_bundle_iterator use_bundle_end() {
return use_bundle_iterator(nullptr);
}
- inline iterator_range<use_bundle_iterator> use_bundles(unsigned Reg) const {
+ inline iterator_range<use_bundle_iterator> use_bundles(Register Reg) const {
return make_range(use_bundle_begin(Reg), use_bundle_end());
}
/// use_empty - Return true if there are no instructions using the specified
/// register.
- bool use_empty(unsigned RegNo) const { return use_begin(RegNo) == use_end(); }
+ bool use_empty(Register RegNo) const { return use_begin(RegNo) == use_end(); }
/// hasOneUse - Return true if there is exactly one instruction using the
/// specified register.
- bool hasOneUse(unsigned RegNo) const {
+ bool hasOneUse(Register RegNo) const {
use_iterator UI = use_begin(RegNo);
if (UI == use_end())
return false;
@@ -508,7 +508,7 @@ public:
/// specified register, skipping those marked as Debug.
using use_nodbg_iterator =
defusechain_iterator<true, false, true, true, false, false>;
- use_nodbg_iterator use_nodbg_begin(unsigned RegNo) const {
+ use_nodbg_iterator use_nodbg_begin(Register RegNo) const {
return use_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_nodbg_iterator use_nodbg_end() {
@@ -516,7 +516,7 @@ public:
}
inline iterator_range<use_nodbg_iterator>
- use_nodbg_operands(unsigned Reg) const {
+ use_nodbg_operands(Register Reg) const {
return make_range(use_nodbg_begin(Reg), use_nodbg_end());
}
@@ -525,7 +525,7 @@ public:
/// those marked as Debug.
using use_instr_nodbg_iterator =
defusechain_instr_iterator<true, false, true, false, true, false>;
- use_instr_nodbg_iterator use_instr_nodbg_begin(unsigned RegNo) const {
+ use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const {
return use_instr_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_instr_nodbg_iterator use_instr_nodbg_end() {
@@ -533,7 +533,7 @@ public:
}
inline iterator_range<use_instr_nodbg_iterator>
- use_nodbg_instructions(unsigned Reg) const {
+ use_nodbg_instructions(Register Reg) const {
return make_range(use_instr_nodbg_begin(Reg), use_instr_nodbg_end());
}
@@ -542,7 +542,7 @@ public:
/// those marked as Debug.
using use_bundle_nodbg_iterator =
defusechain_instr_iterator<true, false, true, false, false, true>;
- use_bundle_nodbg_iterator use_bundle_nodbg_begin(unsigned RegNo) const {
+ use_bundle_nodbg_iterator use_bundle_nodbg_begin(Register RegNo) const {
return use_bundle_nodbg_iterator(getRegUseDefListHead(RegNo));
}
static use_bundle_nodbg_iterator use_bundle_nodbg_end() {
@@ -550,25 +550,25 @@ public:
}
inline iterator_range<use_bundle_nodbg_iterator>
- use_nodbg_bundles(unsigned Reg) const {
+ use_nodbg_bundles(Register Reg) const {
return make_range(use_bundle_nodbg_begin(Reg), use_bundle_nodbg_end());
}
/// use_nodbg_empty - Return true if there are no non-Debug instructions
/// using the specified register.
- bool use_nodbg_empty(unsigned RegNo) const {
+ bool use_nodbg_empty(Register RegNo) const {
return use_nodbg_begin(RegNo) == use_nodbg_end();
}
/// hasOneNonDBGUse - Return true if there is exactly one non-Debug
/// use of the specified register.
- bool hasOneNonDBGUse(unsigned RegNo) const;
+ bool hasOneNonDBGUse(Register RegNo) const;
/// hasOneNonDBGUse - Return true if there is exactly one non-Debug
/// instruction using the specified register. Said instruction may have
/// multiple uses.
- bool hasOneNonDBGUser(unsigned RegNo) const;
-
+ bool hasOneNonDBGUser(Register RegNo) const;
+
/// replaceRegWith - Replace all instances of FromReg with ToReg in the
/// machine function. This is like llvm-level X->replaceAllUsesWith(Y),
/// except that it also changes any definitions of the register as well.
@@ -588,33 +588,33 @@ public:
/// Note that if ToReg is a physical register the function will replace and
/// apply sub registers to ToReg in order to obtain a final/proper physical
/// register.
- void replaceRegWith(unsigned FromReg, unsigned ToReg);
+ void replaceRegWith(Register FromReg, Register ToReg);
/// getVRegDef - Return the machine instr that defines the specified virtual
/// register or null if none is found. This assumes that the code is in SSA
/// form, so there should only be one definition.
- MachineInstr *getVRegDef(unsigned Reg) const;
+ MachineInstr *getVRegDef(Register Reg) const;
/// getUniqueVRegDef - Return the unique machine instr that defines the
/// specified virtual register or null if none is found. If there are
/// multiple definitions or no definition, return null.
- MachineInstr *getUniqueVRegDef(unsigned Reg) const;
+ MachineInstr *getUniqueVRegDef(Register Reg) const;
/// clearKillFlags - Iterate over all the uses of the given register and
/// clear the kill flag from the MachineOperand. This function is used by
/// optimization passes which extend register lifetimes and need only
/// preserve conservative kill flag information.
- void clearKillFlags(unsigned Reg) const;
+ void clearKillFlags(Register Reg) const;
- void dumpUses(unsigned RegNo) const;
+ void dumpUses(Register RegNo) const;
/// Returns true if PhysReg is unallocatable and constant throughout the
/// function. Writing to a constant register has no effect.
- bool isConstantPhysReg(unsigned PhysReg) const;
+ bool isConstantPhysReg(MCRegister PhysReg) const;
/// Returns true if either isConstantPhysReg or TRI->isCallerPreservedPhysReg
/// returns true. This is a utility member function.
- bool isCallerPreservedOrConstPhysReg(unsigned PhysReg) const;
+ bool isCallerPreservedOrConstPhysReg(MCRegister PhysReg) const;
/// Get an iterator over the pressure sets affected by the given physical or
/// virtual register. If RegUnit is physical, it must be a register unit (from
@@ -645,7 +645,7 @@ public:
/// None of this condition is possible without GlobalISel for now.
/// In other words, if GlobalISel is not used or if the query happens after
/// the select pass, using getRegClass is safe.
- const TargetRegisterClass *getRegClassOrNull(unsigned Reg) const {
+ const TargetRegisterClass *getRegClassOrNull(Register Reg) const {
const RegClassOrRegBank &Val = VRegInfo[Reg].first;
return Val.dyn_cast<const TargetRegisterClass *>();
}
@@ -654,7 +654,7 @@ public:
/// a register bank or has been assigned a register class.
/// \note It is possible to get the register bank from the register class via
/// RegisterBankInfo::getRegBankFromRegClass.
- const RegisterBank *getRegBankOrNull(unsigned Reg) const {
+ const RegisterBank *getRegBankOrNull(Register Reg) const {
const RegClassOrRegBank &Val = VRegInfo[Reg].first;
return Val.dyn_cast<const RegisterBank *>();
}
@@ -662,17 +662,17 @@ public:
/// Return the register bank or register class of \p Reg.
/// \note Before the register bank gets assigned (i.e., before the
/// RegBankSelect pass) \p Reg may not have either.
- const RegClassOrRegBank &getRegClassOrRegBank(unsigned Reg) const {
+ const RegClassOrRegBank &getRegClassOrRegBank(Register Reg) const {
return VRegInfo[Reg].first;
}
/// setRegClass - Set the register class of the specified virtual register.
- void setRegClass(unsigned Reg, const TargetRegisterClass *RC);
+ void setRegClass(Register Reg, const TargetRegisterClass *RC);
/// Set the register bank to \p RegBank for \p Reg.
- void setRegBank(unsigned Reg, const RegisterBank &RegBank);
+ void setRegBank(Register Reg, const RegisterBank &RegBank);
- void setRegClassOrRegBank(unsigned Reg,
+ void setRegClassOrRegBank(Register Reg,
const RegClassOrRegBank &RCOrRB){
VRegInfo[Reg].first = RCOrRB;
}
@@ -688,7 +688,7 @@ public:
/// Use RegisterBankInfo::constrainGenericRegister in GlobalISel's
/// InstructionSelect pass and constrainRegAttrs in every other pass,
/// including non-select passes of GlobalISel, instead.
- const TargetRegisterClass *constrainRegClass(unsigned Reg,
+ const TargetRegisterClass *constrainRegClass(Register Reg,
const TargetRegisterClass *RC,
unsigned MinNumRegs = 0);
@@ -703,7 +703,7 @@ public:
/// \note Use this method instead of constrainRegClass and
/// RegisterBankInfo::constrainGenericRegister everywhere but SelectionDAG
/// ISel / FastISel and GlobalISel's InstructionSelect pass respectively.
- bool constrainRegAttrs(unsigned Reg, unsigned ConstrainingReg,
+ bool constrainRegAttrs(Register Reg, Register ConstrainingReg,
unsigned MinNumRegs = 0);
/// recomputeRegClass - Try to find a legal super-class of Reg's register
@@ -713,7 +713,7 @@ public:
/// This method can be used after constraints have been removed from a
/// virtual register, for example after removing instructions or splitting
/// the live range.
- bool recomputeRegClass(unsigned Reg);
+ bool recomputeRegClass(Register Reg);
/// createVirtualRegister - Create and return a new virtual register in the
/// function with the specified register class.
@@ -726,14 +726,14 @@ public:
/// Get the low-level type of \p Reg or LLT{} if Reg is not a generic
/// (target independent) virtual register.
- LLT getType(unsigned Reg) const {
+ LLT getType(Register Reg) const {
if (Register::isVirtualRegister(Reg) && VRegToType.inBounds(Reg))
return VRegToType[Reg];
return LLT{};
}
/// Set the low-level type of \p VReg to \p Ty.
- void setType(unsigned VReg, LLT Ty);
+ void setType(Register VReg, LLT Ty);
/// Create and return a new generic virtual register with low-level
/// type \p Ty.
@@ -748,7 +748,7 @@ public:
/// temporarily while constructing machine instructions. Most operations are
/// undefined on an incomplete register until one of setRegClass(),
/// setRegBank() or setSize() has been called on it.
- unsigned createIncompleteVirtualRegister(StringRef Name = "");
+ Register createIncompleteVirtualRegister(StringRef Name = "");
/// getNumVirtRegs - Return the number of virtual registers created.
unsigned getNumVirtRegs() const { return VRegInfo.size(); }
@@ -759,8 +759,8 @@ public:
/// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register. This is typically used by target, and in case
/// of an earlier hint it will be overwritten.
- void setRegAllocationHint(unsigned VReg, unsigned Type, unsigned PrefReg) {
- assert(Register::isVirtualRegister(VReg));
+ void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg) {
+ assert(VReg.isVirtual());
RegAllocHints[VReg].first = Type;
RegAllocHints[VReg].second.clear();
RegAllocHints[VReg].second.push_back(PrefReg);
@@ -768,19 +768,19 @@ public:
/// addRegAllocationHint - Add a register allocation hint to the hints
/// vector for VReg.
- void addRegAllocationHint(unsigned VReg, unsigned PrefReg) {
+ void addRegAllocationHint(Register VReg, Register PrefReg) {
assert(Register::isVirtualRegister(VReg));
RegAllocHints[VReg].second.push_back(PrefReg);
}
/// Specify the preferred (target independent) register allocation hint for
/// the specified virtual register.
- void setSimpleHint(unsigned VReg, unsigned PrefReg) {
+ void setSimpleHint(Register VReg, Register PrefReg) {
setRegAllocationHint(VReg, /*Type=*/0, PrefReg);
}
- void clearSimpleHint(unsigned VReg) {
- assert (RegAllocHints[VReg].first == 0 &&
+ void clearSimpleHint(Register VReg) {
+ assert (!RegAllocHints[VReg].first &&
"Expected to clear a non-target hint!");
RegAllocHints[VReg].second.clear();
}
@@ -788,12 +788,12 @@ public:
/// getRegAllocationHint - Return the register allocation hint for the
/// specified virtual register. If there are many hints, this returns the
/// one with the greatest weight.
- std::pair<unsigned, unsigned>
+ std::pair<Register, Register>
getRegAllocationHint(Register VReg) const {
assert(VReg.isVirtual());
- unsigned BestHint = (RegAllocHints[VReg.id()].second.size() ?
- RegAllocHints[VReg.id()].second[0] : 0);
- return std::pair<unsigned, unsigned>(RegAllocHints[VReg.id()].first,
+ Register BestHint = (RegAllocHints[VReg.id()].second.size() ?
+ RegAllocHints[VReg.id()].second[0] : Register());
+ return std::pair<Register, Register>(RegAllocHints[VReg.id()].first,
BestHint);
}
@@ -801,26 +801,26 @@ public:
/// a target independent hint.
Register getSimpleHint(Register VReg) const {
assert(VReg.isVirtual());
- std::pair<unsigned, unsigned> Hint = getRegAllocationHint(VReg);
- return Hint.first ? 0 : Hint.second;
+ std::pair<Register, Register> Hint = getRegAllocationHint(VReg);
+ return Hint.first ? Register() : Hint.second;
}
/// getRegAllocationHints - Return a reference to the vector of all
/// register allocation hints for VReg.
- const std::pair<unsigned, SmallVector<unsigned, 4>>
- &getRegAllocationHints(unsigned VReg) const {
- assert(Register::isVirtualRegister(VReg));
+ const std::pair<Register, SmallVector<Register, 4>>
+ &getRegAllocationHints(Register VReg) const {
+ assert(VReg.isVirtual());
return RegAllocHints[VReg];
}
/// markUsesInDebugValueAsUndef - Mark every DBG_VALUE referencing the
/// specified register as undefined which causes the DBG_VALUE to be
/// deleted during LiveDebugVariables analysis.
- void markUsesInDebugValueAsUndef(unsigned Reg) const;
+ void markUsesInDebugValueAsUndef(Register Reg) const;
/// updateDbgUsersToReg - Update a collection of DBG_VALUE instructions
/// to refer to the designated register.
- void updateDbgUsersToReg(unsigned Reg,
+ void updateDbgUsersToReg(Register Reg,
ArrayRef<MachineInstr*> Users) const {
for (MachineInstr *MI : Users) {
assert(MI->isDebugInstr());
@@ -835,13 +835,13 @@ public:
/// ignored, to consider them pass 'true' for optional parameter
/// SkipNoReturnDef. The register is also considered modified when it is set
/// in the UsedPhysRegMask.
- bool isPhysRegModified(unsigned PhysReg, bool SkipNoReturnDef = false) const;
+ bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef = false) const;
/// Return true if the specified register is modified or read in this
/// function. This checks that no machine operands exist for the register or
/// any of its aliases. The register is also considered used when it is set
/// in the UsedPhysRegMask.
- bool isPhysRegUsed(unsigned PhysReg) const;
+ bool isPhysRegUsed(MCRegister PhysReg) const;
/// addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
/// This corresponds to the bit mask attached to register mask operands.
@@ -876,7 +876,7 @@ public:
/// canReserveReg - Returns true if PhysReg can be used as a reserved
/// register. Any register can be reserved before freezeReservedRegs() is
/// called.
- bool canReserveReg(unsigned PhysReg) const {
+ bool canReserveReg(MCRegister PhysReg) const {
return !reservedRegsFrozen() || ReservedRegs.test(PhysReg);
}
@@ -912,7 +912,7 @@ public:
/// Allocatable registers may show up in the allocation order of some virtual
/// register, so a register allocator needs to track its liveness and
/// availability.
- bool isAllocatable(unsigned PhysReg) const {
+ bool isAllocatable(MCRegister PhysReg) const {
return getTargetRegisterInfo()->isInAllocatableClass(PhysReg) &&
!isReserved(PhysReg);
}
@@ -923,31 +923,31 @@ public:
/// addLiveIn - Add the specified register as a live-in. Note that it
/// is an error to add the same register to the same set more than once.
- void addLiveIn(unsigned Reg, unsigned vreg = 0) {
+ void addLiveIn(MCRegister Reg, Register vreg = Register()) {
LiveIns.push_back(std::make_pair(Reg, vreg));
}
// Iteration support for the live-ins set. It's kept in sorted order
// by register number.
using livein_iterator =
- std::vector<std::pair<unsigned,unsigned>>::const_iterator;
+ std::vector<std::pair<MCRegister,Register>>::const_iterator;
livein_iterator livein_begin() const { return LiveIns.begin(); }
livein_iterator livein_end() const { return LiveIns.end(); }
bool livein_empty() const { return LiveIns.empty(); }
- ArrayRef<std::pair<unsigned, unsigned>> liveins() const {
+ ArrayRef<std::pair<MCRegister, Register>> liveins() const {
return LiveIns;
}
- bool isLiveIn(unsigned Reg) const;
+ bool isLiveIn(Register Reg) const;
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
- unsigned getLiveInPhysReg(unsigned VReg) const;
+ MCRegister getLiveInPhysReg(Register VReg) const;
/// getLiveInVirtReg - If PReg is a live-in physical register, return the
/// corresponding live-in physical register.
- unsigned getLiveInVirtReg(unsigned PReg) const;
+ Register getLiveInVirtReg(MCRegister PReg) const;
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
/// into the given entry block.
@@ -957,7 +957,7 @@ public:
/// Returns a mask covering all bits that can appear in lane masks of
/// subregisters of the virtual register @p Reg.
- LaneBitmask getMaxLaneMaskForVReg(unsigned Reg) const;
+ LaneBitmask getMaxLaneMaskForVReg(Register Reg) const;
/// defusechain_iterator - This class provides iterator support for machine
/// operands in the function that use or define a specific register. If
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSSAUpdater.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
index 0319ec774671..df972e12d461 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSSAUpdater.h
@@ -13,6 +13,8 @@
#ifndef LLVM_CODEGEN_MACHINESSAUPDATER_H
#define LLVM_CODEGEN_MACHINESSAUPDATER_H
+#include "llvm/CodeGen/Register.h"
+
namespace llvm {
class MachineBasicBlock;
@@ -35,11 +37,11 @@ class MachineSSAUpdater {
private:
/// AvailableVals - This keeps track of which value to use on a per-block
/// basis. When we insert PHI nodes, we keep track of them here.
- //typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
+ //typedef DenseMap<MachineBasicBlock*, Register> AvailableValsTy;
void *AV = nullptr;
/// VR - Current virtual register whose uses are being updated.
- unsigned VR;
+ Register VR;
/// VRC - Register class of the current virtual register.
const TargetRegisterClass *VRC;
@@ -62,11 +64,11 @@ public:
/// Initialize - Reset this object to get ready for a new set of SSA
/// updates.
- void Initialize(unsigned V);
+ void Initialize(Register V);
/// AddAvailableValue - Indicate that a rewritten value is available at the
/// end of the specified block with the specified value.
- void AddAvailableValue(MachineBasicBlock *BB, unsigned V);
+ void AddAvailableValue(MachineBasicBlock *BB, Register V);
/// HasValueForBlock - Return true if the MachineSSAUpdater already has a
/// value for the specified block.
@@ -74,7 +76,7 @@ public:
/// GetValueAtEndOfBlock - Construct SSA form, materializing a value that is
/// live at the end of the specified block.
- unsigned GetValueAtEndOfBlock(MachineBasicBlock *BB);
+ Register GetValueAtEndOfBlock(MachineBasicBlock *BB);
/// GetValueInMiddleOfBlock - Construct SSA form, materializing a value that
/// is live in the middle of the specified block.
@@ -94,7 +96,7 @@ public:
/// their respective blocks. However, the use of X happens in the *middle* of
/// a block. Because of this, we need to insert a new PHI node in SomeBB to
/// merge the appropriate values, and this value isn't live out of the block.
- unsigned GetValueInMiddleOfBlock(MachineBasicBlock *BB);
+ Register GetValueInMiddleOfBlock(MachineBasicBlock *BB);
/// RewriteUse - Rewrite a use of the symbolic value. This handles PHI nodes,
/// which use their value in the corresponding predecessor. Note that this
@@ -104,7 +106,7 @@ public:
void RewriteUse(MachineOperand &U);
private:
- unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
+ Register GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineScheduler.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineScheduler.h
index 6cebaa47fe6a..a7edaaa90673 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineScheduler.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineScheduler.h
@@ -80,7 +80,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/RegisterPressure.h"
@@ -102,6 +101,7 @@ extern cl::opt<bool> ForceTopDown;
extern cl::opt<bool> ForceBottomUp;
extern cl::opt<bool> VerifyScheduling;
+class AAResults;
class LiveIntervals;
class MachineDominatorTree;
class MachineFunction;
@@ -121,7 +121,7 @@ struct MachineSchedContext {
const MachineLoopInfo *MLI = nullptr;
const MachineDominatorTree *MDT = nullptr;
const TargetPassConfig *PassConfig = nullptr;
- AliasAnalysis *AA = nullptr;
+ AAResults *AA = nullptr;
LiveIntervals *LIS = nullptr;
RegisterClassInfo *RegClassInfo;
@@ -186,6 +186,9 @@ struct MachineSchedPolicy {
// first.
bool DisableLatencyHeuristic = false;
+ // Compute DFSResult for use in scheduling heuristics.
+ bool ComputeDFSResult = false;
+
MachineSchedPolicy() = default;
};
@@ -261,7 +264,7 @@ public:
/// PreRA and PostRA MachineScheduler.
class ScheduleDAGMI : public ScheduleDAGInstrs {
protected:
- AliasAnalysis *AA;
+ AAResults *AA;
LiveIntervals *LIS;
std::unique_ptr<MachineSchedStrategy> SchedImpl;
@@ -1061,7 +1064,7 @@ public:
}
protected:
- void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
+ virtual void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand);
void pickNodeFromQueue(SchedCandidate &Cand);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSizeOpts.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSizeOpts.h
index 3b02d0860ea1..07bbbad8d9c9 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSizeOpts.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/MachineSizeOpts.h
@@ -21,6 +21,7 @@ class ProfileSummaryInfo;
class MachineBasicBlock;
class MachineBlockFrequencyInfo;
class MachineFunction;
+class MBFIWrapper;
/// Returns true if machine function \p MF is suggested to be size-optimized
/// based on the profile.
@@ -33,6 +34,12 @@ bool shouldOptimizeForSize(const MachineBasicBlock *MBB,
ProfileSummaryInfo *PSI,
const MachineBlockFrequencyInfo *MBFI,
PGSOQueryType QueryType = PGSOQueryType::Other);
+/// Returns true if machine basic block \p MBB is suggested to be size-optimized
+/// based on the profile.
+bool shouldOptimizeForSize(const MachineBasicBlock *MBB,
+ ProfileSummaryInfo *PSI,
+ MBFIWrapper *MBFIWrapper,
+ PGSOQueryType QueryType = PGSOQueryType::Other);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ModuloSchedule.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ModuloSchedule.h
index 55c52f3447b0..1aa23208cfb9 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ModuloSchedule.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ModuloSchedule.h
@@ -141,6 +141,12 @@ public:
return I == Cycle.end() ? -1 : I->second;
}
+ /// Set the stage of a newly created instruction.
+ void setStage(MachineInstr *MI, int MIStage) {
+ assert(Stage.count(MI) == 0);
+ Stage[MI] = MIStage;
+ }
+
/// Return the rescheduled instructions in order.
ArrayRef<MachineInstr *> getInstructions() { return ScheduledInstrs; }
@@ -271,6 +277,19 @@ public:
/// A reimplementation of ModuloScheduleExpander. It works by generating a
/// standalone kernel loop and peeling out the prologs and epilogs.
class PeelingModuloScheduleExpander {
+public:
+ PeelingModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S,
+ LiveIntervals *LIS)
+ : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
+ TII(ST.getInstrInfo()), LIS(LIS) {}
+
+ void expand();
+
+ /// Runs ModuloScheduleExpander and treats it as a golden input to validate
+ /// aspects of the code generated by PeelingModuloScheduleExpander.
+ void validateAgainstModuloScheduleExpander();
+
+protected:
ModuloSchedule &Schedule;
MachineFunction &MF;
const TargetSubtargetInfo &ST;
@@ -305,24 +324,10 @@ class PeelingModuloScheduleExpander {
/// Illegal phis that need to be deleted once we re-link stages.
SmallVector<MachineInstr *, 4> IllegalPhisToDelete;
-public:
- PeelingModuloScheduleExpander(MachineFunction &MF, ModuloSchedule &S,
- LiveIntervals *LIS)
- : Schedule(S), MF(MF), ST(MF.getSubtarget()), MRI(MF.getRegInfo()),
- TII(ST.getInstrInfo()), LIS(LIS) {}
-
- void expand();
-
- /// Runs ModuloScheduleExpander and treats it as a golden input to validate
- /// aspects of the code generated by PeelingModuloScheduleExpander.
- void validateAgainstModuloScheduleExpander();
-
-protected:
/// Converts BB from the original loop body to the rewritten, pipelined
/// steady-state.
void rewriteKernel();
-private:
/// Peels one iteration of the rewritten kernel (BB) in the specified
/// direction.
MachineBasicBlock *peelKernel(LoopPeelDirection LPD);
@@ -358,7 +363,7 @@ private:
/// coming from a peeled out prologue.
Register getPhiCanonicalReg(MachineInstr* CanonicalPhi, MachineInstr* Phi);
/// Target loop info before kernel peeling.
- std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> Info;
+ std::unique_ptr<TargetInstrInfo::PipelinerLoopInfo> LoopInfo;
};
/// Expander that simply annotates each scheduled instruction with a post-instr
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ParallelCG.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ParallelCG.h
index b4c761c2269e..5504baa6225c 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ParallelCG.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ParallelCG.h
@@ -14,15 +14,14 @@
#define LLVM_CODEGEN_PARALLELCG_H
#include "llvm/Support/CodeGen.h"
-#include "llvm/Target/TargetMachine.h"
-
#include <functional>
+#include <memory>
namespace llvm {
template <typename T> class ArrayRef;
class Module;
-class TargetOptions;
+class TargetMachine;
class raw_pwrite_stream;
/// Split M into OSs.size() partitions, and generate code for each. Takes a
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/Passes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/Passes.h
index 4e3451d80572..9e5b4446c195 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/Passes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/Passes.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CODEGEN_PASSES_H
#define LLVM_CODEGEN_PASSES_H
+#include "llvm/Support/CodeGen.h"
#include <functional>
#include <string>
@@ -22,6 +23,7 @@ namespace llvm {
class FunctionPass;
class MachineFunction;
class MachineFunctionPass;
+class MemoryBuffer;
class ModulePass;
class Pass;
class TargetMachine;
@@ -42,6 +44,12 @@ namespace llvm {
/// the entry block.
FunctionPass *createUnreachableBlockEliminationPass();
+ /// createBBSectionsPrepare Pass - This pass assigns sections to machine basic
+ /// blocks and is enabled with -fbasic-block-sections.
+ /// Buf is a memory buffer that contains the list of functions and basic
+ /// block ids to selectively enable basic block sections.
+ MachineFunctionPass *createBBSectionsPreparePass(const MemoryBuffer *Buf);
+
/// MachineFunctionPrinter pass - This pass prints out the machine function to
/// the given stream as a debugging tool.
MachineFunctionPass *
@@ -185,11 +193,11 @@ namespace llvm {
/// register allocation.
extern char &ExpandPostRAPseudosID;
- /// createPostRAHazardRecognizer - This pass runs the post-ra hazard
+ /// PostRAHazardRecognizer - This pass runs the post-ra hazard
/// recognizer.
extern char &PostRAHazardRecognizerID;
- /// createPostRAScheduler - This pass performs post register allocation
+ /// PostRAScheduler - This pass performs post register allocation
/// scheduling.
extern char &PostRASchedulerID;
@@ -333,7 +341,7 @@ namespace llvm {
/// createDwarfEHPass - This pass mulches exception handling code into a form
/// adapted to code generation. Required if using dwarf exception handling.
- FunctionPass *createDwarfEHPass();
+ FunctionPass *createDwarfEHPass(CodeGenOpt::Level OptLevel);
/// createWinEHPass - Prepares personality functions used by MSVC on Windows,
/// in addition to the Itanium LSDA based personalities.
@@ -342,7 +350,7 @@ namespace llvm {
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
///
- FunctionPass *createSjLjEHPreparePass();
+ FunctionPass *createSjLjEHPreparePass(const TargetMachine *TM);
/// createWasmEHPass - This pass adapts exception handling code to use
/// WebAssembly's exception handling scheme.
@@ -466,6 +474,18 @@ namespace llvm {
/// Create IR Type Promotion pass. \see TypePromotion.cpp
FunctionPass *createTypePromotionPass();
+ /// Creates MIR Debugify pass. \see MachineDebugify.cpp
+ ModulePass *createDebugifyMachineModulePass();
+
+ /// Creates MIR Strip Debug pass. \see MachineStripDebug.cpp
+ /// If OnlyDebugified is true then it will only strip debug info if it was
+ /// added by a Debugify pass. The module will be left unchanged if the debug
+ /// info was generated by another source such as clang.
+ ModulePass *createStripDebugMachineModulePass(bool OnlyDebugified);
+
+ /// The pass fixups statepoint machine instruction to replace usage of
+ /// caller saved registers with stack slots.
+ extern char &FixupStatepointCallerSavedID;
} // End llvm namespace
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/PseudoSourceValue.h
index 593a865ea545..f1487017f205 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/PseudoSourceValue.h
@@ -14,20 +14,19 @@
#define LLVM_CODEGEN_PSEUDOSOURCEVALUE_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/ValueMap.h"
#include <map>
namespace llvm {
+class GlobalValue;
class MachineFrameInfo;
class MachineMemOperand;
class MIRFormatter;
+class PseudoSourceValue;
class raw_ostream;
class TargetInstrInfo;
-raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MMO);
-class PseudoSourceValue;
raw_ostream &operator<<(raw_ostream &OS, const PseudoSourceValue* PSV);
/// Special value supplied for machine level alias analysis. It indicates that
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
index 5a747245a62e..a8a436337e07 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/CodeGen/LoopTraversal.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/InitializePasses.h"
@@ -32,11 +33,44 @@ namespace llvm {
class MachineBasicBlock;
class MachineInstr;
+/// Thin wrapper around "int" used to store reaching definitions,
+/// using an encoding that makes it compatible with TinyPtrVector.
+/// The 0th LSB is forced zero (and will be used for pointer union tagging),
+/// The 1st LSB is forced one (to make sure the value is non-zero).
+class ReachingDef {
+ uintptr_t Encoded;
+ friend struct PointerLikeTypeTraits<ReachingDef>;
+ explicit ReachingDef(uintptr_t Encoded) : Encoded(Encoded) {}
+
+public:
+ ReachingDef(std::nullptr_t) : Encoded(0) {}
+ ReachingDef(int Instr) : Encoded(((uintptr_t) Instr << 2) | 2) {}
+ operator int() const { return ((int) Encoded) >> 2; }
+};
+
+template<>
+struct PointerLikeTypeTraits<ReachingDef> {
+ static constexpr int NumLowBitsAvailable = 1;
+
+ static inline void *getAsVoidPointer(const ReachingDef &RD) {
+ return reinterpret_cast<void *>(RD.Encoded);
+ }
+
+ static inline ReachingDef getFromVoidPointer(void *P) {
+ return ReachingDef(reinterpret_cast<uintptr_t>(P));
+ }
+
+ static inline ReachingDef getFromVoidPointer(const void *P) {
+ return ReachingDef(reinterpret_cast<uintptr_t>(P));
+ }
+};
+
/// This class provides the reaching def analysis.
class ReachingDefAnalysis : public MachineFunctionPass {
private:
MachineFunction *MF;
const TargetRegisterInfo *TRI;
+ LoopTraversal::TraversalOrder TraversedMBBOrder;
unsigned NumRegUnits;
/// Instruction that defined each register, relative to the beginning of the
/// current basic block. When a LiveRegsDefInfo is used to represent a
@@ -55,12 +89,12 @@ private:
/// The first instruction in each basic block is 0.
int CurInstr;
- /// Maps instructions to their instruction Ids, relative to the begining of
+ /// Maps instructions to their instruction Ids, relative to the beginning of
/// their basic blocks.
DenseMap<MachineInstr *, int> InstIds;
/// All reaching defs of a given RegUnit for a given MBB.
- using MBBRegUnitDefs = SmallVector<int, 1>;
+ using MBBRegUnitDefs = TinyPtrVector<ReachingDef>;
/// All reaching defs of all reg units for a given MBB
using MBBDefsInfo = std::vector<MBBRegUnitDefs>;
/// All reaching defs of all reg units for a all MBBs
@@ -70,6 +104,9 @@ private:
/// Default values are 'nothing happened a long time ago'.
const int ReachingDefDefaultVal = -(1 << 20);
+ using InstSet = SmallPtrSetImpl<MachineInstr*>;
+ using BlockSet = SmallPtrSetImpl<MachineBasicBlock*>;
+
public:
static char ID; // Pass identification, replacement for typeid
@@ -91,67 +128,143 @@ public:
MachineFunctionProperties::Property::TracksLiveness);
}
- /// Provides the instruction id of the closest reaching def instruction of
- /// PhysReg that reaches MI, relative to the begining of MI's basic block.
- int getReachingDef(MachineInstr *MI, int PhysReg);
+ /// Re-run the analysis.
+ void reset();
- /// Provides the instruction of the closest reaching def instruction of
- /// PhysReg that reaches MI, relative to the begining of MI's basic block.
- MachineInstr *getReachingMIDef(MachineInstr *MI, int PhysReg);
+ /// Initialize data structures.
+ void init();
- /// Provides the MI, from the given block, corresponding to the Id or a
- /// nullptr if the id does not refer to the block.
- MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId);
+ /// Traverse the machine function, mapping definitions.
+ void traverse();
+
+ /// Provides the instruction id of the closest reaching def instruction of
+ /// PhysReg that reaches MI, relative to the begining of MI's basic block.
+ int getReachingDef(MachineInstr *MI, int PhysReg) const;
/// Return whether A and B use the same def of PhysReg.
- bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, int PhysReg);
+ bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, int PhysReg) const;
/// Return whether the reaching def for MI also is live out of its parent
/// block.
- bool isReachingDefLiveOut(MachineInstr *MI, int PhysReg);
+ bool isReachingDefLiveOut(MachineInstr *MI, int PhysReg) const;
/// Return the local MI that produces the live out value for PhysReg, or
/// nullptr for a non-live out or non-local def.
MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
- int PhysReg);
+ int PhysReg) const;
+
+ /// If a single MachineInstr creates the reaching definition, then return it.
+ /// Otherwise return null.
+ MachineInstr *getUniqueReachingMIDef(MachineInstr *MI, int PhysReg) const;
+
+ /// If a single MachineInstr creates the reaching definition, for MIs operand
+ /// at Idx, then return it. Otherwise return null.
+ MachineInstr *getMIOperand(MachineInstr *MI, unsigned Idx) const;
+
+ /// If a single MachineInstr creates the reaching definition, for MIs MO,
+ /// then return it. Otherwise return null.
+ MachineInstr *getMIOperand(MachineInstr *MI, MachineOperand &MO) const;
+
+ /// Provide whether the register has been defined in the same basic block as,
+ /// and before, MI.
+ bool hasLocalDefBefore(MachineInstr *MI, int PhysReg) const;
/// Return whether the given register is used after MI, whether it's a local
/// use or a live out.
- bool isRegUsedAfter(MachineInstr *MI, int PhysReg);
+ bool isRegUsedAfter(MachineInstr *MI, int PhysReg) const;
- /// Provides the first instruction before MI that uses PhysReg
- MachineInstr *getInstWithUseBefore(MachineInstr *MI, int PhysReg);
-
- /// Provides all instructions before MI that uses PhysReg
- void getAllInstWithUseBefore(MachineInstr *MI, int PhysReg,
- SmallVectorImpl<MachineInstr*> &Uses);
+ /// Return whether the given register is defined after MI.
+ bool isRegDefinedAfter(MachineInstr *MI, int PhysReg) const;
/// Provides the clearance - the number of instructions since the closest
/// reaching def instuction of PhysReg that reaches MI.
- int getClearance(MachineInstr *MI, MCPhysReg PhysReg);
+ int getClearance(MachineInstr *MI, MCPhysReg PhysReg) const;
/// Provides the uses, in the same block as MI, of register that MI defines.
/// This does not consider live-outs.
void getReachingLocalUses(MachineInstr *MI, int PhysReg,
- SmallVectorImpl<MachineInstr*> &Uses);
-
- /// Provide the number of uses, in the same block as MI, of the register that
- /// MI defines.
- unsigned getNumUses(MachineInstr *MI, int PhysReg);
+ InstSet &Uses) const;
+
+ /// Search MBB for a definition of PhysReg and insert it into Defs. If no
+ /// definition is found, recursively search the predecessor blocks for them.
+ void getLiveOuts(MachineBasicBlock *MBB, int PhysReg, InstSet &Defs,
+ BlockSet &VisitedBBs) const;
+ void getLiveOuts(MachineBasicBlock *MBB, int PhysReg, InstSet &Defs) const;
+
+ /// For the given block, collect the instructions that use the live-in
+ /// value of the provided register. Return whether the value is still
+ /// live on exit.
+ bool getLiveInUses(MachineBasicBlock *MBB, int PhysReg,
+ InstSet &Uses) const;
+
+ /// Collect the users of the value stored in PhysReg, which is defined
+ /// by MI.
+ void getGlobalUses(MachineInstr *MI, int PhysReg,
+ InstSet &Uses) const;
+
+ /// Return whether From can be moved forwards to just before To.
+ bool isSafeToMoveForwards(MachineInstr *From, MachineInstr *To) const;
+
+ /// Return whether From can be moved backwards to just after To.
+ bool isSafeToMoveBackwards(MachineInstr *From, MachineInstr *To) const;
+
+ /// Assuming MI is dead, recursively search the incoming operands which are
+ /// killed by MI and collect those that would become dead.
+ void collectKilledOperands(MachineInstr *MI, InstSet &Dead) const;
+
+ /// Return whether removing this instruction will have no effect on the
+ /// program, returning the redundant use-def chain.
+ bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove) const;
+
+ /// Return whether removing this instruction will have no effect on the
+ /// program, ignoring the possible effects on some instructions, returning
+ /// the redundant use-def chain.
+ bool isSafeToRemove(MachineInstr *MI, InstSet &ToRemove,
+ InstSet &Ignore) const;
+
+ /// Return whether a MachineInstr could be inserted at MI and safely define
+ /// the given register without affecting the program.
+ bool isSafeToDefRegAt(MachineInstr *MI, int PhysReg) const;
+
+ /// Return whether a MachineInstr could be inserted at MI and safely define
+ /// the given register without affecting the program, ignoring any effects
+ /// on the provided instructions.
+ bool isSafeToDefRegAt(MachineInstr *MI, int PhysReg, InstSet &Ignore) const;
private:
/// Set up LiveRegs by merging predecessor live-out values.
- void enterBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
+ void enterBasicBlock(MachineBasicBlock *MBB);
/// Update live-out values.
- void leaveBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
+ void leaveBasicBlock(MachineBasicBlock *MBB);
/// Process he given basic block.
void processBasicBlock(const LoopTraversal::TraversedMBBInfo &TraversedMBB);
+ /// Process block that is part of a loop again.
+ void reprocessBasicBlock(MachineBasicBlock *MBB);
+
/// Update def-ages for registers defined by MI.
/// Also break dependencies on partial defs and undef uses.
void processDefs(MachineInstr *);
+
+ /// Utility function for isSafeToMoveForwards/Backwards.
+ template<typename Iterator>
+ bool isSafeToMove(MachineInstr *From, MachineInstr *To) const;
+
+ /// Return whether removing this instruction will have no effect on the
+ /// program, ignoring the possible effects on some instructions, returning
+ /// the redundant use-def chain.
+ bool isSafeToRemove(MachineInstr *MI, InstSet &Visited,
+ InstSet &ToRemove, InstSet &Ignore) const;
+
+ /// Provides the MI, from the given block, corresponding to the Id or a
+ /// nullptr if the id does not refer to the block.
+ MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
+
+ /// Provides the instruction of the closest reaching def instruction of
+ /// PhysReg that reaches MI, relative to the begining of MI's basic block.
+ MachineInstr *getReachingLocalMIDef(MachineInstr *MI, int PhysReg) const;
};
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/Register.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/Register.h
index aa5173684e24..054040cd29a1 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/Register.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/Register.h
@@ -20,8 +20,8 @@ class Register {
unsigned Reg;
public:
- Register(unsigned Val = 0): Reg(Val) {}
- Register(MCRegister Val): Reg(Val) {}
+ constexpr Register(unsigned Val = 0): Reg(Val) {}
+ constexpr Register(MCRegister Val): Reg(Val) {}
// Register numbers can represent physical registers, virtual registers, and
// sometimes stack slots. The unsigned values are divided into these ranges:
@@ -33,6 +33,8 @@ public:
//
// Further sentinels can be allocated from the small negative integers.
// DenseMapInfo<unsigned> uses -1u and -2u.
+ static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF,
+ "Reg isn't large enough to hold full range.");
/// isStackSlot - Sometimes it is useful the be able to store a non-negative
/// frame index in a variable that normally holds a register. isStackSlot()
@@ -49,13 +51,13 @@ public:
/// Compute the frame index from a register value representing a stack slot.
static int stackSlot2Index(unsigned Reg) {
assert(isStackSlot(Reg) && "Not a stack slot");
- return int(Reg - (1u << 30));
+ return int(Reg - MCRegister::FirstStackSlot);
}
/// Convert a non-negative frame index to a stack slot register value.
static unsigned index2StackSlot(int FI) {
assert(FI >= 0 && "Cannot hold a negative frame index.");
- return FI + (1u << 30);
+ return FI + MCRegister::FirstStackSlot;
}
/// Return true if the specified register number is in
@@ -68,20 +70,21 @@ public:
/// the virtual register namespace.
static bool isVirtualRegister(unsigned Reg) {
assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
- return int(Reg) < 0;
+ return Reg & MCRegister::VirtualRegFlag;
}
/// Convert a virtual register number to a 0-based index.
/// The first virtual register in a function will get the index 0.
static unsigned virtReg2Index(unsigned Reg) {
assert(isVirtualRegister(Reg) && "Not a virtual register");
- return Reg & ~(1u << 31);
+ return Reg & ~MCRegister::VirtualRegFlag;
}
/// Convert a 0-based index to a virtual register number.
/// This is the inverse operation of VirtReg2IndexFunctor below.
static unsigned index2VirtReg(unsigned Index) {
- return Index | (1u << 31);
+ assert(Index < (1u << 31) && "Index too large for virtual register range.");
+ return Index | MCRegister::VirtualRegFlag;
}
/// Return true if the specified register number is in the virtual register
@@ -102,7 +105,7 @@ public:
return virtReg2Index(Reg);
}
- operator unsigned() const {
+ constexpr operator unsigned() const {
return Reg;
}
@@ -112,9 +115,7 @@ public:
return MCRegister(Reg);
}
- bool isValid() const {
- return Reg != 0;
- }
+ bool isValid() const { return Reg != MCRegister::NoRegister; }
/// Comparisons between register objects
bool operator==(const Register &Other) const { return Reg == Other.Reg; }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h
index 81587a3170ce..b38cd4924174 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -16,15 +16,15 @@
#ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
#define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
-#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/CodeGen/SelectionDAGISel.h"
-#include "llvm/CodeGen/TargetInstrInfo.h"
-#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/MC/MCInstrItineraries.h"
namespace llvm {
+ class DFAPacketizer;
+ class InstrItineraryData;
class ResourcePriorityQueue;
+ class SelectionDAGISel;
+ class TargetInstrInfo;
+ class TargetRegisterInfo;
/// Sorting functions for the Available queue.
struct resource_sort {
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDAG.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDAG.h
index e004f3bf2cc1..4c8d047727ce 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDAG.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDAG.h
@@ -724,6 +724,10 @@ class TargetRegisterInfo;
public:
ScheduleDAGTopologicalSort(std::vector<SUnit> &SUnits, SUnit *ExitSU);
+ /// Add a SUnit without predecessors to the end of the topological order. It
+ /// also must be the first new node added to the DAG.
+ void AddSUnitWithoutPredecessors(const SUnit *SU);
+
/// Creates the initial topological ordering from the DAG to be scheduled.
void InitDAGTopologicalSorting();
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDFS.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDFS.h
index d60deab95f5d..2e0a30cc56e3 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDFS.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScheduleDFS.h
@@ -13,7 +13,6 @@
#ifndef LLVM_CODEGEN_SCHEDULEDFS_H
#define LLVM_CODEGEN_SCHEDULEDFS_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include <cassert>
@@ -22,6 +21,7 @@
namespace llvm {
+template <typename T> class ArrayRef;
class raw_ostream;
/// Represent the ILP of the subDAG rooted at a DAG node.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index ac67f3008fa7..cefafe87a17d 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -16,13 +16,13 @@
#define LLVM_CODEGEN_SCOREBOARDHAZARDRECOGNIZER_H
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
+#include "llvm/MC/MCInstrItineraries.h"
#include <cassert>
#include <cstddef>
#include <cstring>
namespace llvm {
-class InstrItineraryData;
class ScheduleDAG;
class SUnit;
@@ -37,7 +37,7 @@ class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
// bottom-up scheduler, then the scoreboard cycles are the inverse of the
// scheduler's cycles.
class Scoreboard {
- unsigned *Data = nullptr;
+ InstrStage::FuncUnits *Data = nullptr;
// The maximum number of cycles monitored by the Scoreboard. This
// value is determined based on the target itineraries to ensure
@@ -56,7 +56,7 @@ class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
size_t getDepth() const { return Depth; }
- unsigned& operator[](size_t idx) const {
+ InstrStage::FuncUnits& operator[](size_t idx) const {
// Depth is expected to be a power-of-2.
assert(Depth && !(Depth & (Depth - 1)) &&
"Scoreboard was not initialized properly!");
@@ -67,7 +67,7 @@ class ScoreboardHazardRecognizer : public ScheduleHazardRecognizer {
void reset(size_t d = 1) {
if (!Data) {
Depth = d;
- Data = new unsigned[Depth];
+ Data = new InstrStage::FuncUnits[Depth];
}
memset(Data, 0, Depth * sizeof(Data[0]));
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAG.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAG.h
index 3bfde5b4ce1d..f26ab6f287a0 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAG.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAG.h
@@ -278,6 +278,7 @@ class SelectionDAG {
struct CallSiteDbgInfo {
CallSiteInfo CSInfo;
MDNode *HeapAllocSite = nullptr;
+ bool NoMerge = false;
};
DenseMap<const SDNode *, CallSiteDbgInfo> SDCallSiteDbgInfo;
@@ -432,6 +433,17 @@ public:
ProfileSummaryInfo *getPSI() const { return PSI; }
BlockFrequencyInfo *getBFI() const { return BFI; }
+ /// Just dump dot graph to a user-provided path and title.
+ /// This doesn't open the dot viewer program and
+ /// helps visualization when outside debugging session.
+ /// FileName expects absolute path. If provided
+ /// without any path separators then the file
+ /// will be created in the current directory.
+ /// Error will be emitted if the path is insane.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dumpDotGraph(const Twine &FileName, const Twine &Title);
+#endif
+
/// Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
void viewGraph(const std::string &Title);
void viewGraph();
@@ -600,6 +612,8 @@ public:
bool isTarget = false);
SDValue getShiftAmountConstant(uint64_t Val, EVT VT, const SDLoc &DL,
bool LegalTypes = true);
+ SDValue getVectorIdxConstant(uint64_t Val, const SDLoc &DL,
+ bool isTarget = false);
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT,
bool isOpaque = false) {
@@ -660,18 +674,19 @@ public:
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags = 0) {
return getJumpTable(JTI, VT, true, TargetFlags);
}
- SDValue getConstantPool(const Constant *C, EVT VT, unsigned Align = 0,
+ SDValue getConstantPool(const Constant *C, EVT VT, MaybeAlign Align = None,
int Offs = 0, bool isT = false,
unsigned TargetFlags = 0);
- SDValue getTargetConstantPool(const Constant *C, EVT VT, unsigned Align = 0,
- int Offset = 0, unsigned TargetFlags = 0) {
+ SDValue getTargetConstantPool(const Constant *C, EVT VT,
+ MaybeAlign Align = None, int Offset = 0,
+ unsigned TargetFlags = 0) {
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
SDValue getConstantPool(MachineConstantPoolValue *C, EVT VT,
- unsigned Align = 0, int Offs = 0, bool isT=false,
- unsigned TargetFlags = 0);
+ MaybeAlign Align = None, int Offs = 0,
+ bool isT = false, unsigned TargetFlags = 0);
SDValue getTargetConstantPool(MachineConstantPoolValue *C, EVT VT,
- unsigned Align = 0, int Offset = 0,
+ MaybeAlign Align = None, int Offset = 0,
unsigned TargetFlags = 0) {
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
}
@@ -912,6 +927,14 @@ public:
return getNode(ISD::UNDEF, SDLoc(), VT);
}
+ /// Return a node that represents the runtime scaling 'MulImm * RuntimeVL'.
+ SDValue getVScale(const SDLoc &DL, EVT VT, APInt MulImm) {
+ assert(MulImm.getMinSignedBits() <= VT.getSizeInBits() &&
+ "Immediate does not fit VT");
+ return getNode(ISD::VSCALE, DL, VT,
+ getConstant(MulImm.sextOrTrunc(VT.getSizeInBits()), DL, VT));
+ }
+
/// Return a GLOBAL_OFFSET_TABLE node. This does not have a useful SDLoc.
SDValue getGLOBAL_OFFSET_TABLE(EVT VT) {
return getNode(ISD::GLOBAL_OFFSET_TABLE, SDLoc(), VT);
@@ -926,7 +949,7 @@ public:
SDValue getNode(unsigned Opcode, const SDLoc &DL, ArrayRef<EVT> ResultTys,
ArrayRef<SDValue> Ops);
SDValue getNode(unsigned Opcode, const SDLoc &DL, SDVTList VTList,
- ArrayRef<SDValue> Ops);
+ ArrayRef<SDValue> Ops, const SDNodeFlags Flags = SDNodeFlags());
// Specialize based on number of operands.
SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT);
@@ -960,18 +983,50 @@ public:
/// stack arguments from being clobbered.
SDValue getStackArgumentTokenFactor(SDValue Chain);
+ LLVM_ATTRIBUTE_DEPRECATED(SDValue getMemcpy(SDValue Chain, const SDLoc &dl,
+ SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align,
+ bool isVol, bool AlwaysInline,
+ bool isTailCall,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo),
+ "Use the version that takes Align instead") {
+ return getMemcpy(Chain, dl, Dst, Src, Size, llvm::Align(Align), isVol,
+ AlwaysInline, isTailCall, DstPtrInfo, SrcPtrInfo);
+ }
+
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
- SDValue Size, unsigned Align, bool isVol, bool AlwaysInline,
- bool isTailCall, MachinePointerInfo DstPtrInfo,
+ SDValue Size, Align Alignment, bool isVol,
+ bool AlwaysInline, bool isTailCall,
+ MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo);
+ LLVM_ATTRIBUTE_DEPRECATED(SDValue getMemmove(SDValue Chain, const SDLoc &dl,
+ SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align,
+ bool isVol, bool isTailCall,
+ MachinePointerInfo DstPtrInfo,
+ MachinePointerInfo SrcPtrInfo),
+ "Use the version that takes Align instead") {
+ return getMemmove(Chain, dl, Dst, Src, Size, llvm::Align(Align), isVol,
+ isTailCall, DstPtrInfo, SrcPtrInfo);
+ }
SDValue getMemmove(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
- SDValue Size, unsigned Align, bool isVol, bool isTailCall,
+ SDValue Size, Align Alignment, bool isVol, bool isTailCall,
MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo);
+ LLVM_ATTRIBUTE_DEPRECATED(SDValue getMemset(SDValue Chain, const SDLoc &dl,
+ SDValue Dst, SDValue Src,
+ SDValue Size, unsigned Align,
+ bool isVol, bool isTailCall,
+ MachinePointerInfo DstPtrInfo),
+ "Use the version that takes Align instead") {
+ return getMemset(Chain, dl, Dst, Src, Size, llvm::Align(Align), isVol,
+ isTailCall, DstPtrInfo);
+ }
SDValue getMemset(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src,
- SDValue Size, unsigned Align, bool isVol, bool isTailCall,
+ SDValue Size, Align Alignment, bool isVol, bool isTailCall,
MachinePointerInfo DstPtrInfo);
SDValue getAtomicMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst,
@@ -1036,7 +1091,8 @@ public:
/// Try to simplify a floating-point binary operation into 1 of its operands
/// or a constant.
- SDValue simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y);
+ SDValue simplifyFPBinop(unsigned Opcode, SDValue X, SDValue Y,
+ SDNodeFlags Flags);
/// VAArg produces a result and token chain, and takes a pointer
/// and a source value as input.
@@ -1072,14 +1128,36 @@ public:
/// INTRINSIC_W_CHAIN, or a target-specific opcode with a value not
/// less than FIRST_TARGET_MEMORY_OPCODE.
SDValue getMemIntrinsicNode(
- unsigned Opcode, const SDLoc &dl, SDVTList VTList,
- ArrayRef<SDValue> Ops, EVT MemVT,
- MachinePointerInfo PtrInfo,
- unsigned Align = 0,
- MachineMemOperand::Flags Flags
- = MachineMemOperand::MOLoad | MachineMemOperand::MOStore,
- uint64_t Size = 0,
- const AAMDNodes &AAInfo = AAMDNodes());
+ unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
+ EVT MemVT, MachinePointerInfo PtrInfo, Align Alignment,
+ MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad |
+ MachineMemOperand::MOStore,
+ uint64_t Size = 0, const AAMDNodes &AAInfo = AAMDNodes());
+
+ inline SDValue getMemIntrinsicNode(
+ unsigned Opcode, const SDLoc &dl, SDVTList VTList, ArrayRef<SDValue> Ops,
+ EVT MemVT, MachinePointerInfo PtrInfo, MaybeAlign Alignment = None,
+ MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad |
+ MachineMemOperand::MOStore,
+ uint64_t Size = 0, const AAMDNodes &AAInfo = AAMDNodes()) {
+ // Ensure that codegen never sees alignment 0
+ return getMemIntrinsicNode(Opcode, dl, VTList, Ops, MemVT, PtrInfo,
+ Alignment.getValueOr(getEVTAlign(MemVT)), Flags,
+ Size, AAInfo);
+ }
+
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline SDValue getMemIntrinsicNode(
+ unsigned Opcode, const SDLoc &dl, SDVTList VTList,
+ ArrayRef<SDValue> Ops, EVT MemVT, MachinePointerInfo PtrInfo,
+ unsigned Alignment,
+ MachineMemOperand::Flags Flags = MachineMemOperand::MOLoad |
+ MachineMemOperand::MOStore,
+ uint64_t Size = 0, const AAMDNodes &AAInfo = AAMDNodes()),
+ "") {
+ return getMemIntrinsicNode(Opcode, dl, VTList, Ops, MemVT, PtrInfo,
+ MaybeAlign(Alignment), Flags, Size, AAInfo);
+ }
SDValue getMemIntrinsicNode(unsigned Opcode, const SDLoc &dl, SDVTList VTList,
ArrayRef<SDValue> Ops, EVT MemVT,
@@ -1100,18 +1178,38 @@ public:
/// This function will set the MOLoad flag on MMOFlags, but you can set it if
/// you want. The MOStore flag must not be set.
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
- MachinePointerInfo PtrInfo, unsigned Alignment = 0,
+ MachinePointerInfo PtrInfo, MaybeAlign Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr);
+ /// FIXME: Remove once transition to Align is over.
+ inline SDValue
+ getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
+ MachinePointerInfo PtrInfo, unsigned Alignment = 0,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes(),
+ const MDNode *Ranges = nullptr) {
+ return getLoad(VT, dl, Chain, Ptr, PtrInfo, MaybeAlign(Alignment), MMOFlags,
+ AAInfo, Ranges);
+ }
SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr,
MachineMemOperand *MMO);
SDValue
getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain,
SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT,
- unsigned Alignment = 0,
+ MaybeAlign Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes());
+ /// FIXME: Remove once transition to Align is over.
+ inline SDValue
+ getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT, SDValue Chain,
+ SDValue Ptr, MachinePointerInfo PtrInfo, EVT MemVT,
+ unsigned Alignment = 0,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes()) {
+ return getExtLoad(ExtType, dl, VT, Chain, Ptr, PtrInfo, MemVT,
+ MaybeAlign(Alignment), MMOFlags, AAInfo);
+ }
SDValue getExtLoad(ISD::LoadExtType ExtType, const SDLoc &dl, EVT VT,
SDValue Chain, SDValue Ptr, EVT MemVT,
MachineMemOperand *MMO);
@@ -1119,10 +1217,33 @@ public:
SDValue Offset, ISD::MemIndexedMode AM);
SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
- MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment = 0,
+ MachinePointerInfo PtrInfo, EVT MemVT, Align Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes(),
const MDNode *Ranges = nullptr);
+ inline SDValue
+ getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
+ const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
+ MachinePointerInfo PtrInfo, EVT MemVT, MaybeAlign Alignment,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes(),
+ const MDNode *Ranges = nullptr) {
+ // Ensures that codegen never sees a None Alignment.
+ return getLoad(AM, ExtType, VT, dl, Chain, Ptr, Offset, PtrInfo, MemVT,
+ Alignment.getValueOr(getEVTAlign(MemVT)), MMOFlags, AAInfo,
+ Ranges);
+ }
+ /// FIXME: Remove once transition to Align is over.
+ inline SDValue
+ getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
+ const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
+ MachinePointerInfo PtrInfo, EVT MemVT, unsigned Alignment = 0,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes(),
+ const MDNode *Ranges = nullptr) {
+ return getLoad(AM, ExtType, VT, dl, Chain, Ptr, Offset, PtrInfo, MemVT,
+ MaybeAlign(Alignment), MMOFlags, AAInfo, Ranges);
+ }
SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, EVT VT,
const SDLoc &dl, SDValue Chain, SDValue Ptr, SDValue Offset,
EVT MemVT, MachineMemOperand *MMO);
@@ -1131,18 +1252,55 @@ public:
///
/// This function will set the MOStore flag on MMOFlags, but you can set it if
/// you want. The MOLoad and MOInvariant flags must not be set.
+
SDValue
getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, unsigned Alignment = 0,
+ MachinePointerInfo PtrInfo, Align Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes());
+ inline SDValue
+ getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, MaybeAlign Alignment,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes()) {
+ return getStore(Chain, dl, Val, Ptr, PtrInfo,
+ Alignment.getValueOr(getEVTAlign(Val.getValueType())),
+ MMOFlags, AAInfo);
+ }
+ /// FIXME: Remove once transition to Align is over.
+ inline SDValue
+ getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, unsigned Alignment = 0,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes()) {
+ return getStore(Chain, dl, Val, Ptr, PtrInfo, MaybeAlign(Alignment),
+ MMOFlags, AAInfo);
+ }
SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
MachineMemOperand *MMO);
SDValue
getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
- MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment = 0,
+ MachinePointerInfo PtrInfo, EVT SVT, Align Alignment,
MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
const AAMDNodes &AAInfo = AAMDNodes());
+ inline SDValue
+ getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, EVT SVT, MaybeAlign Alignment,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes()) {
+ return getTruncStore(Chain, dl, Val, Ptr, PtrInfo, SVT,
+ Alignment.getValueOr(getEVTAlign(SVT)), MMOFlags,
+ AAInfo);
+ }
+ /// FIXME: Remove once transition to Align is over.
+ inline SDValue
+ getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr,
+ MachinePointerInfo PtrInfo, EVT SVT, unsigned Alignment = 0,
+ MachineMemOperand::Flags MMOFlags = MachineMemOperand::MONone,
+ const AAMDNodes &AAInfo = AAMDNodes()) {
+ return getTruncStore(Chain, dl, Val, Ptr, PtrInfo, SVT,
+ MaybeAlign(Alignment), MMOFlags, AAInfo);
+ }
SDValue getTruncStore(SDValue Chain, const SDLoc &dl, SDValue Val,
SDValue Ptr, EVT SVT, MachineMemOperand *MMO);
SDValue getIndexedStore(SDValue OrigStore, const SDLoc &dl, SDValue Base,
@@ -1168,13 +1326,6 @@ public:
ArrayRef<SDValue> Ops, MachineMemOperand *MMO,
ISD::MemIndexType IndexType);
- /// Return (create a new or find existing) a target-specific node.
- /// TargetMemSDNode should be derived class from MemSDNode.
- template <class TargetMemSDNode>
- SDValue getTargetMemSDNode(SDVTList VTs, ArrayRef<SDValue> Ops,
- const SDLoc &dl, EVT MemVT,
- MachineMemOperand *MMO);
-
/// Construct a node to track a Value* through the backend.
SDValue getSrcValue(const Value *v);
@@ -1189,6 +1340,12 @@ public:
SDValue getAddrSpaceCast(const SDLoc &dl, EVT VT, SDValue Ptr, unsigned SrcAS,
unsigned DestAS);
+ /// Return a freeze using the SDLoc of the value operand.
+ SDValue getFreeze(SDValue V);
+
+ /// Return an AssertAlignSDNode.
+ SDValue getAssertAlign(const SDLoc &DL, SDValue V, Align A);
+
/// Return the specified value casted to
/// the target's desired shift amount type.
SDValue getShiftAmountOperand(EVT LHSTy, SDValue Op);
@@ -1406,6 +1563,7 @@ public:
switch (VT.getScalarType().getSimpleVT().SimpleTy) {
default: llvm_unreachable("Unknown FP format");
case MVT::f16: return APFloat::IEEEhalf();
+ case MVT::bf16: return APFloat::BFloat();
case MVT::f32: return APFloat::IEEEsingle();
case MVT::f64: return APFloat::IEEEdouble();
case MVT::f80: return APFloat::x87DoubleExtended();
@@ -1454,6 +1612,15 @@ public:
void dump() const;
+ /// In most cases this function returns the ABI alignment for a given type,
+ /// except for illegal vector types where the alignment exceeds that of the
+ /// stack. In such cases we attempt to break the vector down to a legal type
+ /// and return the ABI alignment for that instead.
+ Align getReducedAlign(EVT VT, bool UseABI);
+
+ /// Create a stack temporary based on the size in bytes and the alignment
+ SDValue CreateStackTemporary(TypeSize Bytes, Align Alignment);
+
/// Create a stack temporary, suitable for holding the specified value type.
/// If minAlign is specified, the slot size will have at least that alignment.
SDValue CreateStackTemporary(EVT VT, unsigned minAlign = 1);
@@ -1467,11 +1634,7 @@ public:
const SDNode *N2);
SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
- SDNode *N1, SDNode *N2);
-
- SDValue FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
- const ConstantSDNode *C1,
- const ConstantSDNode *C2);
+ ArrayRef<SDValue> Ops);
SDValue FoldConstantVectorArithmetic(unsigned Opcode, const SDLoc &DL, EVT VT,
ArrayRef<SDValue> Ops,
@@ -1630,6 +1793,23 @@ public:
/// that element from the source vector.
SDValue getSplatValue(SDValue V);
+ /// If a SHL/SRA/SRL node \p V has a constant or splat constant shift amount
+ /// that is less than the element bit-width of the shift node, return it.
+ const APInt *getValidShiftAmountConstant(SDValue V,
+ const APInt &DemandedElts) const;
+
+ /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less
+ /// than the element bit-width of the shift node, return the minimum value.
+ const APInt *
+ getValidMinimumShiftAmountConstant(SDValue V,
+ const APInt &DemandedElts) const;
+
+ /// If a SHL/SRA/SRL node \p V has constant shift amounts that are all less
+ /// than the element bit-width of the shift node, return the maximum value.
+ const APInt *
+ getValidMaximumShiftAmountConstant(SDValue V,
+ const APInt &DemandedElts) const;
+
/// Match a binop + shuffle pyramid that represents a horizontal reduction
/// over the elements of a vector starting from the EXTRACT_VECTOR_ELT node /p
/// Extract. The reduction must use one of the opcodes listed in /p
@@ -1662,14 +1842,28 @@ public:
bool areNonVolatileConsecutiveLoads(LoadSDNode *LD, LoadSDNode *Base,
unsigned Bytes, int Dist) const;
- /// Infer alignment of a load / store address. Return 0 if
- /// it cannot be inferred.
- unsigned InferPtrAlignment(SDValue Ptr) const;
+ /// Infer alignment of a load / store address. Return None if it cannot be
+ /// inferred.
+ MaybeAlign InferPtrAlign(SDValue Ptr) const;
+
+ LLVM_ATTRIBUTE_DEPRECATED(inline unsigned InferPtrAlignment(SDValue Ptr)
+ const,
+ "Use InferPtrAlign instead") {
+ if (auto A = InferPtrAlign(Ptr))
+ return A->value();
+ return 0;
+ }
/// Compute the VTs needed for the low/hi parts of a type
/// which is split (or expanded) into two not necessarily identical pieces.
std::pair<EVT, EVT> GetSplitDestVTs(const EVT &VT) const;
+ /// Compute the VTs needed for the low/hi parts of a type, dependent on an
+ /// enveloping VT that has been split into two identical pieces. Sets the
+ /// HisIsEmpty flag when hi type has zero storage size.
+ std::pair<EVT, EVT> GetDependentSplitDestVTs(const EVT &VT, const EVT &EnvVT,
+ bool *HiIsEmpty) const;
+
/// Split the vector with EXTRACT_SUBVECTOR using the provides
/// VTs and return the low/high part.
std::pair<SDValue, SDValue> SplitVector(const SDValue &N, const SDLoc &DL,
@@ -1692,13 +1886,21 @@ public:
/// Widen the vector up to the next power of two using INSERT_SUBVECTOR.
SDValue WidenVector(const SDValue &N, const SDLoc &DL);
- /// Append the extracted elements from Start to Count out of the vector Op
- /// in Args. If Count is 0, all of the elements will be extracted.
+ /// Append the extracted elements from Start to Count out of the vector Op in
+ /// Args. If Count is 0, all of the elements will be extracted. The extracted
+ /// elements will have type EVT if it is provided, and otherwise their type
+ /// will be Op's element type.
void ExtractVectorElements(SDValue Op, SmallVectorImpl<SDValue> &Args,
- unsigned Start = 0, unsigned Count = 0);
+ unsigned Start = 0, unsigned Count = 0,
+ EVT EltVT = EVT());
/// Compute the default alignment value for the given type.
- unsigned getEVTAlignment(EVT MemoryVT) const;
+ Align getEVTAlign(EVT MemoryVT) const;
+ /// Compute the default alignment value for the given type.
+ /// FIXME: Remove once transition to Align is over.
+ inline unsigned getEVTAlignment(EVT MemoryVT) const {
+ return getEVTAlign(MemoryVT).value();
+ }
/// Test whether the given value is a constant int or similar node.
SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N);
@@ -1736,6 +1938,18 @@ public:
return It->second.HeapAllocSite;
}
+ void addNoMergeSiteInfo(const SDNode *Node, bool NoMerge) {
+ if (NoMerge)
+ SDCallSiteDbgInfo[Node].NoMerge = NoMerge;
+ }
+
+ bool getNoMergeSiteInfo(const SDNode *Node) {
+ auto I = SDCallSiteDbgInfo.find(Node);
+ if (I == SDCallSiteDbgInfo.end())
+ return false;
+ return I->second.NoMerge;
+ }
+
/// Return the current function's default denormal handling kind for the given
/// floating point type.
DenormalMode getDenormalMode(EVT VT) const {
@@ -1798,41 +2012,6 @@ template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
}
};
-template <class TargetMemSDNode>
-SDValue SelectionDAG::getTargetMemSDNode(SDVTList VTs,
- ArrayRef<SDValue> Ops,
- const SDLoc &dl, EVT MemVT,
- MachineMemOperand *MMO) {
- /// Compose node ID and try to find an existing node.
- FoldingSetNodeID ID;
- unsigned Opcode =
- TargetMemSDNode(dl.getIROrder(), DebugLoc(), VTs, MemVT, MMO).getOpcode();
- ID.AddInteger(Opcode);
- ID.AddPointer(VTs.VTs);
- for (auto& Op : Ops) {
- ID.AddPointer(Op.getNode());
- ID.AddInteger(Op.getResNo());
- }
- ID.AddInteger(MemVT.getRawBits());
- ID.AddInteger(MMO->getPointerInfo().getAddrSpace());
- ID.AddInteger(getSyntheticNodeSubclassData<TargetMemSDNode>(
- dl.getIROrder(), VTs, MemVT, MMO));
-
- void *IP = nullptr;
- if (SDNode *E = FindNodeOrInsertPos(ID, dl, IP)) {
- cast<TargetMemSDNode>(E)->refineAlignment(MMO);
- return SDValue(E, 0);
- }
-
- /// Existing node was not found. Create a new one.
- auto *N = newSDNode<TargetMemSDNode>(dl.getIROrder(), dl.getDebugLoc(), VTs,
- MemVT, MMO);
- createOperands(N, Ops);
- CSEMap.InsertNode(N, IP);
- InsertNode(N);
- return SDValue(N, 0);
-}
-
} // end namespace llvm
#endif // LLVM_CODEGEN_SELECTIONDAG_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGISel.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGISel.h
index 9874d782c782..3bfbf3765e4f 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGISel.h
@@ -18,29 +18,21 @@
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/Pass.h"
#include <memory>
namespace llvm {
class AAResults;
-class FastISel;
class SelectionDAGBuilder;
class SDValue;
class MachineRegisterInfo;
-class MachineBasicBlock;
class MachineFunction;
-class MachineInstr;
class OptimizationRemarkEmitter;
class TargetLowering;
class TargetLibraryInfo;
class FunctionLoweringInfo;
-class ScheduleHazardRecognizer;
class SwiftErrorValueTracking;
class GCFunctionInfo;
class ScheduleDAGSDNodes;
-class LoadInst;
-class ProfileSummaryInfo;
-class BlockFrequencyInfo;
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
/// pattern-matching instruction selectors.
@@ -78,7 +70,7 @@ public:
bool runOnMachineFunction(MachineFunction &MF) override;
- virtual void EmitFunctionEntryCode() {}
+ virtual void emitFunctionEntryCode() {}
/// PreprocessISelDAG - This hook allows targets to hack on the graph before
/// instruction selection starts.
@@ -318,12 +310,14 @@ public:
private:
// Calls to these functions are generated by tblgen.
- void Select_INLINEASM(SDNode *N, bool Branch);
+ void Select_INLINEASM(SDNode *N);
void Select_READ_REGISTER(SDNode *Op);
void Select_WRITE_REGISTER(SDNode *Op);
void Select_UNDEF(SDNode *N);
void CannotYetSelect(SDNode *N);
+ void Select_FREEZE(SDNode *N);
+
private:
void DoInstructionSelection();
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index d81a4a8fd43f..7c2b49087edd 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -30,6 +30,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/Register.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugLoc.h"
@@ -368,7 +369,6 @@ private:
bool NoInfs : 1;
bool NoSignedZeros : 1;
bool AllowReciprocal : 1;
- bool VectorReduction : 1;
bool AllowContract : 1;
bool ApproximateFuncs : 1;
bool AllowReassociation : 1;
@@ -385,7 +385,7 @@ public:
SDNodeFlags()
: AnyDefined(false), NoUnsignedWrap(false), NoSignedWrap(false),
Exact(false), NoNaNs(false), NoInfs(false),
- NoSignedZeros(false), AllowReciprocal(false), VectorReduction(false),
+ NoSignedZeros(false), AllowReciprocal(false),
AllowContract(false), ApproximateFuncs(false),
AllowReassociation(false), NoFPExcept(false) {}
@@ -434,10 +434,6 @@ public:
setDefined();
AllowReciprocal = b;
}
- void setVectorReduction(bool b) {
- setDefined();
- VectorReduction = b;
- }
void setAllowContract(bool b) {
setDefined();
AllowContract = b;
@@ -463,17 +459,11 @@ public:
bool hasNoInfs() const { return NoInfs; }
bool hasNoSignedZeros() const { return NoSignedZeros; }
bool hasAllowReciprocal() const { return AllowReciprocal; }
- bool hasVectorReduction() const { return VectorReduction; }
bool hasAllowContract() const { return AllowContract; }
bool hasApproximateFuncs() const { return ApproximateFuncs; }
bool hasAllowReassociation() const { return AllowReassociation; }
bool hasNoFPExcept() const { return NoFPExcept; }
- bool isFast() const {
- return NoSignedZeros && AllowReciprocal && NoNaNs && NoInfs && NoFPExcept &&
- AllowContract && ApproximateFuncs && AllowReassociation;
- }
-
/// Clear any flags in this flag set that aren't also set in Flags.
/// If the given Flags are undefined then don't do anything.
void intersectWith(const SDNodeFlags Flags) {
@@ -486,7 +476,6 @@ public:
NoInfs &= Flags.NoInfs;
NoSignedZeros &= Flags.NoSignedZeros;
AllowReciprocal &= Flags.AllowReciprocal;
- VectorReduction &= Flags.VectorReduction;
AllowContract &= Flags.AllowContract;
ApproximateFuncs &= Flags.ApproximateFuncs;
AllowReassociation &= Flags.AllowReassociation;
@@ -701,7 +690,9 @@ public:
switch (NodeType) {
default:
return false;
-#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
+ case ISD::STRICT_FP16_TO_FP:
+ case ISD::STRICT_FP_TO_FP16:
+#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
case ISD::STRICT_##DAGN:
#include "llvm/IR/ConstrainedOps.def"
return true;
@@ -988,7 +979,6 @@ public:
const SDNodeFlags getFlags() const { return Flags; }
void setFlags(SDNodeFlags NewFlags) { Flags = NewFlags; }
- bool isFast() { return Flags.isFast(); }
/// Clear any flags in this node that aren't also set in Flags.
/// If Flags is not in a defined state then this has no effect.
@@ -1021,6 +1011,9 @@ public:
value_iterator value_begin() const { return ValueList; }
value_iterator value_end() const { return ValueList+NumValues; }
+ iterator_range<value_iterator> values() const {
+ return llvm::make_range(value_begin(), value_end());
+ }
/// Return the opcode of this operation for printing.
std::string getOperationName(const SelectionDAG *G = nullptr) const;
@@ -1300,12 +1293,14 @@ public:
bool writeMem() const { return MMO->isStore(); }
/// Returns alignment and volatility of the memory access
- unsigned getOriginalAlignment() const {
- return MMO->getBaseAlignment();
- }
- unsigned getAlignment() const {
- return MMO->getAlignment();
+ Align getOriginalAlign() const { return MMO->getBaseAlign(); }
+ Align getAlign() const { return MMO->getAlign(); }
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getOriginalAlignment() const,
+ "Use getOriginalAlign() instead") {
+ return MMO->getBaseAlign().value();
}
+ // FIXME: Remove once transition to getAlign is over.
+ unsigned getAlignment() const { return MMO->getAlign().value(); }
/// Return the SubclassData value, without HasDebugValue. This contains an
/// encoding of the volatile flag, as well as bits used by subclasses. This
@@ -1581,6 +1576,8 @@ public:
uint64_t getLimitedValue(uint64_t Limit = UINT64_MAX) {
return Value->getLimitedValue(Limit);
}
+ MaybeAlign getMaybeAlignValue() const { return Value->getMaybeAlignValue(); }
+ Align getAlignValue() const { return Value->getAlignValue(); }
bool isOne() const { return Value->isOne(); }
bool isNullValue() const { return Value->isZero(); }
@@ -1816,23 +1813,23 @@ class ConstantPoolSDNode : public SDNode {
MachineConstantPoolValue *MachineCPVal;
} Val;
int Offset; // It's a MachineConstantPoolValue if top bit is set.
- unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
+ Align Alignment; // Minimum alignment requirement of CP.
unsigned TargetFlags;
ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
- unsigned Align, unsigned TF)
- : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
- DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align),
- TargetFlags(TF) {
+ Align Alignment, unsigned TF)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
+ DebugLoc(), getSDVTList(VT)),
+ Offset(o), Alignment(Alignment), TargetFlags(TF) {
assert(Offset >= 0 && "Offset is too large");
Val.ConstVal = c;
}
- ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
- EVT VT, int o, unsigned Align, unsigned TF)
- : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
- DebugLoc(), getSDVTList(VT)), Offset(o), Alignment(Align),
- TargetFlags(TF) {
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v, EVT VT, int o,
+ Align Alignment, unsigned TF)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool, 0,
+ DebugLoc(), getSDVTList(VT)),
+ Offset(o), Alignment(Alignment), TargetFlags(TF) {
assert(Offset >= 0 && "Offset is too large");
Val.MachineCPVal = v;
Offset |= 1 << (sizeof(unsigned)*CHAR_BIT-1);
@@ -1859,7 +1856,7 @@ public:
// Return the alignment of this constant pool object, which is either 0 (for
// default alignment) or the desired value.
- unsigned getAlignment() const { return Alignment; }
+ Align getAlign() const { return Alignment; }
unsigned getTargetFlags() const { return TargetFlags; }
Type *getType() const;
@@ -2040,13 +2037,13 @@ public:
class RegisterSDNode : public SDNode {
friend class SelectionDAG;
- unsigned Reg;
+ Register Reg;
- RegisterSDNode(unsigned reg, EVT VT)
+ RegisterSDNode(Register reg, EVT VT)
: SDNode(ISD::Register, 0, DebugLoc(), getSDVTList(VT)), Reg(reg) {}
public:
- unsigned getReg() const { return Reg; }
+ Register getReg() const { return Reg; }
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::Register;
@@ -2531,6 +2528,22 @@ public:
}
};
+/// An SDNode that records if a register contains a value that is guaranteed to
+/// be aligned accordingly.
+class AssertAlignSDNode : public SDNode {
+ Align Alignment;
+
+public:
+ AssertAlignSDNode(unsigned Order, const DebugLoc &DL, EVT VT, Align A)
+ : SDNode(ISD::AssertAlign, Order, DL, getSDVTList(VT)), Alignment(A) {}
+
+ Align getAlign() const { return Alignment; }
+
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::AssertAlign;
+ }
+};
+
class SDNodeIterator : public std::iterator<std::forward_iterator_tag,
SDNode, ptrdiff_t> {
const SDNode *Node;
@@ -2675,6 +2688,16 @@ namespace ISD {
SDValue LHS, SDValue RHS,
std::function<bool(ConstantSDNode *, ConstantSDNode *)> Match,
bool AllowUndefs = false, bool AllowTypeMismatch = false);
+
+ /// Returns true if the specified value is the overflow result from one
+ /// of the overflow intrinsic nodes.
+ inline bool isOverflowIntrOpRes(SDValue Op) {
+ unsigned Opc = Op.getOpcode();
+ return (Op.getResNo() == 1 &&
+ (Opc == ISD::SADDO || Opc == ISD::UADDO || Opc == ISD::SSUBO ||
+ Opc == ISD::USUBO || Opc == ISD::SMULO || Opc == ISD::UMULO));
+ }
+
} // end namespace ISD
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
index 6f6a9a5ae269..014523f1af6a 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/SelectionDAGTargetInfo.h
@@ -51,7 +51,7 @@ public:
virtual SDValue EmitTargetCodeForMemcpy(SelectionDAG &DAG, const SDLoc &dl,
SDValue Chain, SDValue Op1,
SDValue Op2, SDValue Op3,
- unsigned Align, bool isVolatile,
+ Align Alignment, bool isVolatile,
bool AlwaysInline,
MachinePointerInfo DstPtrInfo,
MachinePointerInfo SrcPtrInfo) const {
@@ -66,7 +66,7 @@ public:
/// lowering strategy should be used.
virtual SDValue EmitTargetCodeForMemmove(
SelectionDAG &DAG, const SDLoc &dl, SDValue Chain, SDValue Op1,
- SDValue Op2, SDValue Op3, unsigned Align, bool isVolatile,
+ SDValue Op2, SDValue Op3, Align Alignment, bool isVolatile,
MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo) const {
return SDValue();
}
@@ -80,7 +80,7 @@ public:
virtual SDValue EmitTargetCodeForMemset(SelectionDAG &DAG, const SDLoc &dl,
SDValue Chain, SDValue Op1,
SDValue Op2, SDValue Op3,
- unsigned Align, bool isVolatile,
+ Align Alignment, bool isVolatile,
MachinePointerInfo DstPtrInfo) const {
return SDValue();
}
@@ -160,6 +160,11 @@ public:
virtual bool generateFMAsInMachineCombiner(CodeGenOpt::Level OptLevel) const {
return false;
}
+
+ // Return true if the DAG Combiner should disable generic combines.
+ virtual bool disableGenericCombines(CodeGenOpt::Level OptLevel) const {
+ return false;
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/SlotIndexes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/SlotIndexes.h
index fb833806ca8e..19eab7ae5e35 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/SlotIndexes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/SlotIndexes.h
@@ -382,13 +382,15 @@ class raw_ostream;
}
/// Returns the base index for the given instruction.
- SlotIndex getInstructionIndex(const MachineInstr &MI) const {
+ SlotIndex getInstructionIndex(const MachineInstr &MI,
+ bool IgnoreBundle = false) const {
// Instructions inside a bundle have the same number as the bundle itself.
auto BundleStart = getBundleStart(MI.getIterator());
auto BundleEnd = getBundleEnd(MI.getIterator());
// Use the first non-debug instruction in the bundle to get SlotIndex.
const MachineInstr &BundleNonDebug =
- *skipDebugInstructionsForward(BundleStart, BundleEnd);
+ IgnoreBundle ? MI
+ : *skipDebugInstructionsForward(BundleStart, BundleEnd);
assert(!BundleNonDebug.isDebugInstr() &&
"Could not use a debug instruction to query mi2iMap.");
Mi2IndexMap::const_iterator itr = mi2iMap.find(&BundleNonDebug);
@@ -573,7 +575,11 @@ class raw_ostream;
/// Removes machine instruction (bundle) \p MI from the mapping.
/// This should be called before MachineInstr::eraseFromParent() is used to
/// remove a whole bundle or an unbundled instruction.
- void removeMachineInstrFromMaps(MachineInstr &MI);
+ /// If \p AllowBundled is set then this can be used on a bundled
+ /// instruction; however, this exists to support handleMoveIntoBundle,
+ /// and in general removeSingleMachineInstrFromMaps should be used instead.
+ void removeMachineInstrFromMaps(MachineInstr &MI,
+ bool AllowBundled = false);
/// Removes a single machine instruction \p MI from the mapping.
/// This should be called before MachineInstr::eraseFromBundle() is used to
@@ -598,14 +604,22 @@ class raw_ostream;
}
/// Add the given MachineBasicBlock into the maps.
- void insertMBBInMaps(MachineBasicBlock *mbb) {
+ /// If \p InsertionPoint is specified then the block will be placed
+ /// before the given machine instr, otherwise it will be placed
+ /// before the next block in MachineFunction insertion order.
+ void insertMBBInMaps(MachineBasicBlock *mbb,
+ MachineInstr *InsertionPoint = nullptr) {
MachineFunction::iterator nextMBB =
std::next(MachineFunction::iterator(mbb));
IndexListEntry *startEntry = nullptr;
IndexListEntry *endEntry = nullptr;
IndexList::iterator newItr;
- if (nextMBB == mbb->getParent()->end()) {
+ if (InsertionPoint) {
+ startEntry = createEntry(nullptr, 0);
+ endEntry = getInstructionIndex(*InsertionPoint).listEntry();
+ newItr = indexList.insert(endEntry->getIterator(), startEntry);
+ } else if (nextMBB == mbb->getParent()->end()) {
startEntry = &indexList.back();
endEntry = createEntry(nullptr, 0);
newItr = indexList.insertAfter(startEntry->getIterator(), endEntry);
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/Spiller.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/Spiller.h
new file mode 100644
index 000000000000..a693d64858f9
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/Spiller.h
@@ -0,0 +1,42 @@
+//===- llvm/CodeGen/Spiller.h - Spiller -------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_CODEGEN_SPILLER_H
+#define LLVM_LIB_CODEGEN_SPILLER_H
+
+namespace llvm {
+
+class LiveRangeEdit;
+class MachineFunction;
+class MachineFunctionPass;
+class VirtRegMap;
+
+/// Spiller interface.
+///
+/// Implementations are utility classes which insert spill or remat code on
+/// demand.
+class Spiller {
+ virtual void anchor();
+
+public:
+ virtual ~Spiller() = 0;
+
+ /// spill - Spill the LRE.getParent() live interval.
+ virtual void spill(LiveRangeEdit &LRE) = 0;
+
+ virtual void postOptimization() {}
+};
+
+/// Create and return a spiller that will insert spill code directly instead
+/// of deferring though VirtRegMap.
+Spiller *createInlineSpiller(MachineFunctionPass &pass, MachineFunction &mf,
+ VirtRegMap &vrm);
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_SPILLER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/StackMaps.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/StackMaps.h
index 63547e5b7c3e..e33ee226e41a 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/StackMaps.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/StackMaps.h
@@ -156,23 +156,44 @@ class StatepointOpers {
// Flags should be part of meta operands, with args and deopt operands, and
// gc operands all prefixed by their length and a type code. This would be
// much more consistent.
-public:
- // These values are aboolute offsets into the operands of the statepoint
+
+ // These values are absolute offsets into the operands of the statepoint
// instruction.
enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
- // These values are relative offests from the start of the statepoint meta
+ // These values are relative offsets from the start of the statepoint meta
// arguments (i.e. the end of the call arguments).
enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
+public:
explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
+ /// Get index of statepoint ID operand.
+ unsigned getIDPos() const { return IDPos; }
+
+ /// Get index of Num Patch Bytes operand.
+ unsigned getNBytesPos() const { return NBytesPos; }
+
+ /// Get index of Num Call Arguments operand.
+ unsigned getNCallArgsPos() const { return NCallArgsPos; }
+
/// Get starting index of non call related arguments
/// (calling convention, statepoint flags, vm state and gc state).
unsigned getVarIdx() const {
return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
}
+ /// Get index of Calling Convention operand.
+ unsigned getCCIdx() const { return getVarIdx() + CCOffset; }
+
+ /// Get index of Flags operand.
+ unsigned getFlagsIdx() const { return getVarIdx() + FlagsOffset; }
+
+ /// Get index of Number Deopt Arguments operand.
+ unsigned getNumDeoptArgsIdx() const {
+ return getVarIdx() + NumDeoptOperandsOffset;
+ }
+
/// Return the ID for the given statepoint.
uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
@@ -181,11 +202,19 @@ public:
return MI->getOperand(NBytesPos).getImm();
}
- /// Returns the target of the underlying call.
+ /// Return the target of the underlying call.
const MachineOperand &getCallTarget() const {
return MI->getOperand(CallTargetPos);
}
+ /// Return the calling convention.
+ CallingConv::ID getCallingConv() const {
+ return MI->getOperand(getCCIdx()).getImm();
+ }
+
+ /// Return the statepoint flags.
+ uint64_t getFlags() const { return MI->getOperand(getFlagsIdx()).getImm(); }
+
private:
const MachineInstr *MI;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/StackProtector.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/StackProtector.h
index d2ab79cb235e..f6513e8d4ea0 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/StackProtector.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/StackProtector.h
@@ -95,7 +95,7 @@ private:
bool InStruct = false) const;
/// Check whether a stack allocation has its address taken.
- bool HasAddressTaken(const Instruction *AI);
+ bool HasAddressTaken(const Instruction *AI, uint64_t AllocSize);
/// RequiresStackProtector - Check whether or not this function needs a
/// stack protector based upon the stack protector level.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TailDuplicator.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TailDuplicator.h
index e0623a3193e5..6862bb2c3f44 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TailDuplicator.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TailDuplicator.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MBFIWrapper.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include <utility>
#include <vector>
@@ -42,20 +43,20 @@ class TailDuplicator {
const MachineModuleInfo *MMI;
MachineRegisterInfo *MRI;
MachineFunction *MF;
- const MachineBlockFrequencyInfo *MBFI;
+ MBFIWrapper *MBFI;
ProfileSummaryInfo *PSI;
bool PreRegAlloc;
bool LayoutMode;
unsigned TailDupSize;
// A list of virtual registers for which to update SSA form.
- SmallVector<unsigned, 16> SSAUpdateVRs;
+ SmallVector<Register, 16> SSAUpdateVRs;
// For each virtual register in SSAUpdateVals keep a list of source virtual
// registers.
- using AvailableValsTy = std::vector<std::pair<MachineBasicBlock *, unsigned>>;
+ using AvailableValsTy = std::vector<std::pair<MachineBasicBlock *, Register>>;
- DenseMap<unsigned, AvailableValsTy> SSAUpdateVals;
+ DenseMap<Register, AvailableValsTy> SSAUpdateVals;
public:
/// Prepare to run on a specific machine function.
@@ -69,7 +70,7 @@ public:
/// default implies using the command line value TailDupSize.
void initMF(MachineFunction &MF, bool PreRegAlloc,
const MachineBranchProbabilityInfo *MBPI,
- const MachineBlockFrequencyInfo *MBFI,
+ MBFIWrapper *MBFI,
ProfileSummaryInfo *PSI,
bool LayoutMode, unsigned TailDupSize = 0);
@@ -86,41 +87,44 @@ public:
/// of predecessors that received a copy of \p MBB.
/// If \p RemovalCallback is non-null. It will be called before MBB is
/// deleted.
+ /// If \p CandidatePtr is not null, duplicate into these blocks only.
bool tailDuplicateAndUpdate(
bool IsSimple, MachineBasicBlock *MBB,
MachineBasicBlock *ForcedLayoutPred,
SmallVectorImpl<MachineBasicBlock*> *DuplicatedPreds = nullptr,
- function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr);
+ function_ref<void(MachineBasicBlock *)> *RemovalCallback = nullptr,
+ SmallVectorImpl<MachineBasicBlock *> *CandidatePtr = nullptr);
private:
using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
- void addSSAUpdateEntry(unsigned OrigReg, unsigned NewReg,
+ void addSSAUpdateEntry(Register OrigReg, Register NewReg,
MachineBasicBlock *BB);
void processPHI(MachineInstr *MI, MachineBasicBlock *TailBB,
MachineBasicBlock *PredBB,
- DenseMap<unsigned, RegSubRegPair> &LocalVRMap,
- SmallVectorImpl<std::pair<unsigned, RegSubRegPair>> &Copies,
- const DenseSet<unsigned> &UsedByPhi, bool Remove);
+ DenseMap<Register, RegSubRegPair> &LocalVRMap,
+ SmallVectorImpl<std::pair<Register, RegSubRegPair>> &Copies,
+ const DenseSet<Register> &UsedByPhi, bool Remove);
void duplicateInstruction(MachineInstr *MI, MachineBasicBlock *TailBB,
MachineBasicBlock *PredBB,
- DenseMap<unsigned, RegSubRegPair> &LocalVRMap,
- const DenseSet<unsigned> &UsedByPhi);
+ DenseMap<Register, RegSubRegPair> &LocalVRMap,
+ const DenseSet<Register> &UsedByPhi);
void updateSuccessorsPHIs(MachineBasicBlock *FromBB, bool isDead,
SmallVectorImpl<MachineBasicBlock *> &TDBBs,
SmallSetVector<MachineBasicBlock *, 8> &Succs);
bool canCompletelyDuplicateBB(MachineBasicBlock &BB);
bool duplicateSimpleBB(MachineBasicBlock *TailBB,
SmallVectorImpl<MachineBasicBlock *> &TDBBs,
- const DenseSet<unsigned> &RegsUsedByPhi,
+ const DenseSet<Register> &RegsUsedByPhi,
SmallVectorImpl<MachineInstr *> &Copies);
bool tailDuplicate(bool IsSimple,
MachineBasicBlock *TailBB,
MachineBasicBlock *ForcedLayoutPred,
SmallVectorImpl<MachineBasicBlock *> &TDBBs,
- SmallVectorImpl<MachineInstr *> &Copies);
+ SmallVectorImpl<MachineInstr *> &Copies,
+ SmallVectorImpl<MachineBasicBlock *> *CandidatePtr);
void appendCopies(MachineBasicBlock *MBB,
- SmallVectorImpl<std::pair<unsigned,RegSubRegPair>> &CopyInfos,
+ SmallVectorImpl<std::pair<Register, RegSubRegPair>> &CopyInfos,
SmallVectorImpl<MachineInstr *> &Copies);
void removeDeadBlock(
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetCallingConv.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetCallingConv.h
index f515050efadb..347d7ff40404 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetCallingConv.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetCallingConv.h
@@ -35,6 +35,7 @@ namespace ISD {
unsigned IsReturned : 1; ///< Always returned
unsigned IsSplit : 1;
unsigned IsInAlloca : 1; ///< Passed with inalloca
+ unsigned IsPreallocated : 1; ///< ByVal without the copy
unsigned IsSplitEnd : 1; ///< Last part of a split
unsigned IsSwiftSelf : 1; ///< Swift self parameter
unsigned IsSwiftError : 1; ///< Swift error parameter
@@ -56,9 +57,9 @@ namespace ISD {
public:
ArgFlagsTy()
: IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
- IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
- IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0), IsHva(0),
- IsHvaStart(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
+ IsReturned(0), IsSplit(0), IsInAlloca(0), IsPreallocated(0),
+ IsSplitEnd(0), IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0),
+ IsHva(0), IsHvaStart(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
PointerAddrSpace(0) {
@@ -83,6 +84,9 @@ namespace ISD {
bool isInAlloca() const { return IsInAlloca; }
void setInAlloca() { IsInAlloca = 1; }
+ bool isPreallocated() const { return IsPreallocated; }
+ void setPreallocated() { IsPreallocated = 1; }
+
bool isSwiftSelf() const { return IsSwiftSelf; }
void setSwiftSelf() { IsSwiftSelf = 1; }
@@ -125,22 +129,32 @@ namespace ISD {
bool isPointer() const { return IsPointer; }
void setPointer() { IsPointer = 1; }
- unsigned getByValAlign() const {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getByValAlign() const,
+ "Use getNonZeroByValAlign() instead") {
MaybeAlign A = decodeMaybeAlign(ByValAlign);
return A ? A->value() : 0;
}
+ Align getNonZeroByValAlign() const {
+ MaybeAlign A = decodeMaybeAlign(ByValAlign);
+ assert(A && "ByValAlign must be defined");
+ return *A;
+ }
void setByValAlign(Align A) {
ByValAlign = encode(A);
- assert(getByValAlign() == A.value() && "bitfield overflow");
+ assert(getNonZeroByValAlign() == A && "bitfield overflow");
}
- unsigned getOrigAlign() const {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getOrigAlign() const,
+ "Use getNonZeroOrigAlign() instead") {
MaybeAlign A = decodeMaybeAlign(OrigAlign);
return A ? A->value() : 0;
}
+ Align getNonZeroOrigAlign() const {
+ return decodeMaybeAlign(OrigAlign).valueOrOne();
+ }
void setOrigAlign(Align A) {
OrigAlign = encode(A);
- assert(getOrigAlign() == A.value() && "bitfield overflow");
+ assert(getNonZeroOrigAlign() == A && "bitfield overflow");
}
unsigned getByValSize() const { return ByValSize; }
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h
index c7d4c4d7e5d4..c3a11b199675 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetFrameLowering.h
@@ -14,8 +14,6 @@
#define LLVM_CODEGEN_TARGETFRAMELOWERING_H
#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/ADT/StringSwitch.h"
-#include <utility>
#include <vector>
namespace llvm {
@@ -52,6 +50,21 @@ public:
unsigned Reg;
int Offset; // Offset relative to stack pointer on function entry.
};
+
+ struct DwarfFrameBase {
+ // The frame base may be either a register (the default), the CFA,
+ // or a WebAssembly-specific location description.
+ enum FrameBaseKind { Register, CFA, WasmFrameBase } Kind;
+ struct WasmFrameBase {
+ unsigned Kind; // Wasm local, global, or value stack
+ unsigned Index;
+ };
+ union {
+ unsigned Reg;
+ struct WasmFrameBase WasmLoc;
+ } Location;
+ };
+
private:
StackDirection StackDir;
Align StackAlignment;
@@ -60,7 +73,7 @@ private:
bool StackRealignable;
public:
TargetFrameLowering(StackDirection D, Align StackAl, int LAO,
- Align TransAl = Align::None(), bool StackReal = true)
+ Align TransAl = Align(1), bool StackReal = true)
: StackDir(D), StackAlignment(StackAl), TransientStackAlignment(TransAl),
LocalAreaOffset(LAO), StackRealignable(StackReal) {}
@@ -78,6 +91,11 @@ public:
/// is the largest alignment for any data object in the target.
///
unsigned getStackAlignment() const { return StackAlignment.value(); }
+ /// getStackAlignment - This method returns the number of bytes to which the
+ /// stack pointer must be aligned on entry to a function. Typically, this
+ /// is the largest alignment for any data object in the target.
+ ///
+ Align getStackAlign() const { return StackAlignment; }
/// alignSPAdjust - This method aligns the stack adjustment to the correct
/// alignment.
@@ -95,9 +113,15 @@ public:
/// which the stack pointer must be aligned at all times, even between
/// calls.
///
- unsigned getTransientStackAlignment() const {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getTransientStackAlignment() const,
+ "Use getTransientStackAlign instead") {
return TransientStackAlignment.value();
}
+ /// getTransientStackAlignment - This method returns the number of bytes to
+ /// which the stack pointer must be aligned at all times, even between
+ /// calls.
+ ///
+ Align getTransientStackAlign() const { return TransientStackAlignment; }
/// isStackRealignable - This method returns whether the stack can be
/// realigned.
@@ -178,6 +202,17 @@ public:
virtual void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const = 0;
+ /// With basic block sections, emit callee saved frame moves for basic blocks
+ /// that are in a different section.
+ virtual void
+ emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI) const {}
+
+ virtual void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ const DebugLoc &DL,
+ bool IsPrologue) const {}
+
/// Replace a StackProbe stub (if any) with the actual probe code inline
virtual void inlineStackProbe(MachineFunction &MF,
MachineBasicBlock &PrologueMBB) const {}
@@ -198,7 +233,7 @@ public:
/// storeRegToStackSlot(). Returns false otherwise.
virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- const std::vector<CalleeSavedInfo> &CSI,
+ ArrayRef<CalleeSavedInfo> CSI,
const TargetRegisterInfo *TRI) const {
return false;
}
@@ -209,10 +244,11 @@ public:
/// If it returns true, and any of the registers in CSI is not restored,
/// it sets the corresponding Restored flag in CSI to false.
/// Returns false otherwise.
- virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI,
- std::vector<CalleeSavedInfo> &CSI,
- const TargetRegisterInfo *TRI) const {
+ virtual bool
+ restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ MutableArrayRef<CalleeSavedInfo> CSI,
+ const TargetRegisterInfo *TRI) const {
return false;
}
@@ -256,7 +292,7 @@ public:
/// and offset used to reference a frame index location. The offset is
/// returned directly, and the base register is returned via FrameReg.
virtual int getFrameIndexReference(const MachineFunction &MF, int FI,
- unsigned &FrameReg) const;
+ Register &FrameReg) const;
/// Same as \c getFrameIndexReference, except that the stack pointer (as
/// opposed to the frame pointer) will be the preferred value for \p
@@ -265,7 +301,7 @@ public:
/// offset is only guaranteed to be valid with respect to the value of SP at
/// the end of the prologue.
virtual int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
- unsigned &FrameReg,
+ Register &FrameReg,
bool IgnoreSPUpdates) const {
// Always safe to dispatch to getFrameIndexReference.
return getFrameIndexReference(MF, FI, FrameReg);
@@ -278,7 +314,7 @@ public:
int FI) const {
// By default, dispatch to getFrameIndexReference. Interested targets can
// override this.
- unsigned FrameReg;
+ Register FrameReg;
return getFrameIndexReference(MF, FI, FrameReg);
}
@@ -309,6 +345,13 @@ public:
RegScavenger *RS = nullptr) const {
}
+ /// processFunctionBeforeFrameIndicesReplaced - This method is called
+ /// immediately before MO_FrameIndex operands are eliminated, but after the
+ /// frame is finalized. This method is optional.
+ virtual void
+ processFunctionBeforeFrameIndicesReplaced(MachineFunction &MF,
+ RegScavenger *RS = nullptr) const {}
+
virtual unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const {
report_fatal_error("WinEH not implemented for this target");
}
@@ -393,7 +436,11 @@ public:
/// Return initial CFA register value i.e. the one valid at the beginning of
/// the function (before any stack operations).
- virtual unsigned getInitialCFARegister(const MachineFunction &MF) const;
+ virtual Register getInitialCFARegister(const MachineFunction &MF) const;
+
+ /// Return the frame base information to be encoded in the DWARF subprogram
+ /// debug info.
+ virtual DwarfFrameBase getDwarfFrameBase(const MachineFunction &MF) const;
};
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetInstrInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetInstrInfo.h
index ec3c0a0194f6..b3b2fa218627 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetInstrInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetInstrInfo.h
@@ -17,7 +17,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/None.h"
-#include "llvm/CodeGen/LiveRegUnits.h"
#include "llvm/CodeGen/MIRFormatter.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineCombinerPattern.h"
@@ -26,7 +25,6 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOutliner.h"
-#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/Support/BranchProbability.h"
@@ -235,8 +233,8 @@ public:
/// destination. e.g. X86::MOVSX64rr32. If this returns true, then it's
/// expected the pre-extension value is available as a subreg of the result
/// register. This also returns the sub-register index in SubIdx.
- virtual bool isCoalescableExtInstr(const MachineInstr &MI, unsigned &SrcReg,
- unsigned &DstReg, unsigned &SubIdx) const {
+ virtual bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg,
+ Register &DstReg, unsigned &SubIdx) const {
return false;
}
@@ -368,7 +366,7 @@ public:
/// DestReg:SubIdx. Any existing subreg index is preserved or composed with
/// SubIdx.
virtual void reMaterialize(MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI, unsigned DestReg,
+ MachineBasicBlock::iterator MI, Register DestReg,
unsigned SubIdx, const MachineInstr &Orig,
const TargetRegisterInfo &TRI) const;
@@ -448,10 +446,10 @@ public:
/// A pair composed of a register and a sub-register index.
/// Used to give some type checking when modeling Reg:SubReg.
struct RegSubRegPair {
- unsigned Reg;
+ Register Reg;
unsigned SubReg;
- RegSubRegPair(unsigned Reg = 0, unsigned SubReg = 0)
+ RegSubRegPair(Register Reg = Register(), unsigned SubReg = 0)
: Reg(Reg), SubReg(SubReg) {}
bool operator==(const RegSubRegPair& P) const {
@@ -468,7 +466,7 @@ public:
struct RegSubRegPairAndIdx : RegSubRegPair {
unsigned SubIdx;
- RegSubRegPairAndIdx(unsigned Reg = 0, unsigned SubReg = 0,
+ RegSubRegPairAndIdx(Register Reg = Register(), unsigned SubReg = 0,
unsigned SubIdx = 0)
: RegSubRegPair(Reg, SubReg), SubIdx(SubIdx) {}
};
@@ -644,7 +642,7 @@ public:
}
/// Remove the branching code at the end of the specific MBB.
- /// This is only invoked in cases where AnalyzeBranch returns success. It
+ /// This is only invoked in cases where analyzeBranch returns success. It
/// returns the number of instructions that were removed.
/// If \p BytesRemoved is non-null, report the change in code size from the
/// removed instructions.
@@ -654,13 +652,13 @@ public:
}
/// Insert branch code into the end of the specified MachineBasicBlock. The
- /// operands to this method are the same as those returned by AnalyzeBranch.
- /// This is only invoked in cases where AnalyzeBranch returns success. It
+ /// operands to this method are the same as those returned by analyzeBranch.
+ /// This is only invoked in cases where analyzeBranch returns success. It
/// returns the number of instructions inserted. If \p BytesAdded is non-null,
/// report the change in code size from the added instructions.
///
/// It is also invoked by tail merging to add unconditional branches in
- /// cases where AnalyzeBranch doesn't apply because there was no original
+ /// cases where analyzeBranch doesn't apply because there was no original
/// branch to analyze. At least this much must be implemented, else tail
/// merging needs to be disabled.
///
@@ -837,16 +835,18 @@ public:
/// Some x86 implementations have 2-cycle cmov instructions.
///
/// @param MBB Block where select instruction would be inserted.
- /// @param Cond Condition returned by AnalyzeBranch.
+ /// @param Cond Condition returned by analyzeBranch.
+ /// @param DstReg Virtual dest register that the result should write to.
/// @param TrueReg Virtual register to select when Cond is true.
/// @param FalseReg Virtual register to select when Cond is false.
/// @param CondCycles Latency from Cond+Branch to select output.
/// @param TrueCycles Latency from TrueReg to select output.
/// @param FalseCycles Latency from FalseReg to select output.
virtual bool canInsertSelect(const MachineBasicBlock &MBB,
- ArrayRef<MachineOperand> Cond, unsigned TrueReg,
- unsigned FalseReg, int &CondCycles,
- int &TrueCycles, int &FalseCycles) const {
+ ArrayRef<MachineOperand> Cond, Register DstReg,
+ Register TrueReg, Register FalseReg,
+ int &CondCycles, int &TrueCycles,
+ int &FalseCycles) const {
return false;
}
@@ -854,7 +854,7 @@ public:
/// DstReg when Cond is true, and FalseReg to DstReg when Cond is false.
///
/// This function can only be called after canInsertSelect() returned true.
- /// The condition in Cond comes from AnalyzeBranch, and it can be assumed
+ /// The condition in Cond comes from analyzeBranch, and it can be assumed
/// that the same flags or registers required by Cond are available at the
/// insertion point.
///
@@ -862,13 +862,13 @@ public:
/// @param I Insertion point.
/// @param DL Source location for debugging.
/// @param DstReg Virtual register to be defined by select instruction.
- /// @param Cond Condition as computed by AnalyzeBranch.
+ /// @param Cond Condition as computed by analyzeBranch.
/// @param TrueReg Virtual register to copy when Cond is true.
/// @param FalseReg Virtual register to copy when Cons is false.
virtual void insertSelect(MachineBasicBlock &MBB,
MachineBasicBlock::iterator I, const DebugLoc &DL,
- unsigned DstReg, ArrayRef<MachineOperand> Cond,
- unsigned TrueReg, unsigned FalseReg) const {
+ Register DstReg, ArrayRef<MachineOperand> Cond,
+ Register TrueReg, Register FalseReg) const {
llvm_unreachable("Target didn't implement TargetInstrInfo::insertSelect!");
}
@@ -974,7 +974,7 @@ public:
/// is true, the register operand is the last use and must be marked kill.
virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- unsigned SrcReg, bool isKill, int FrameIndex,
+ Register SrcReg, bool isKill, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
llvm_unreachable("Target didn't implement "
@@ -986,7 +986,7 @@ public:
/// machine basic block before the specified machine instruction.
virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
- unsigned DestReg, int FrameIndex,
+ Register DestReg, int FrameIndex,
const TargetRegisterClass *RC,
const TargetRegisterInfo *TRI) const {
llvm_unreachable("Target didn't implement "
@@ -1093,12 +1093,17 @@ public:
SmallVectorImpl<MachineInstr *> &DelInstrs,
DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const;
+ /// The limit on resource length extension we accept in MachineCombiner Pass.
+ virtual int getExtendResourceLenLimit() const { return 0; }
+
/// This is an architecture-specific helper function of reassociateOps.
/// Set special operand attributes for new instructions after reassociation.
virtual void setSpecialOperandAttr(MachineInstr &OldMI1, MachineInstr &OldMI2,
MachineInstr &NewMI1,
MachineInstr &NewMI2) const {}
+ virtual void setSpecialOperandAttr(MachineInstr &MI, uint16_t Flags) const {}
+
/// Return true when a target supports MachineCombiner.
virtual bool useMachineCombiner() const { return false; }
@@ -1236,15 +1241,23 @@ public:
}
/// Get the base operand and byte offset of an instruction that reads/writes
+ /// memory. This is a convenience function for callers that are only prepared
+ /// to handle a single base operand.
+ bool getMemOperandWithOffset(const MachineInstr &MI,
+ const MachineOperand *&BaseOp, int64_t &Offset,
+ bool &OffsetIsScalable,
+ const TargetRegisterInfo *TRI) const;
+
+ /// Get the base operands and byte offset of an instruction that reads/writes
/// memory.
/// It returns false if MI does not read/write memory.
- /// It returns false if no base operand and offset was found.
- /// It is not guaranteed to always recognize base operand and offsets in all
+ /// It returns false if no base operands and offset was found.
+ /// It is not guaranteed to always recognize base operands and offsets in all
/// cases.
- virtual bool getMemOperandWithOffset(const MachineInstr &MI,
- const MachineOperand *&BaseOp,
- int64_t &Offset,
- const TargetRegisterInfo *TRI) const {
+ virtual bool getMemOperandsWithOffsetWidth(
+ const MachineInstr &MI, SmallVectorImpl<const MachineOperand *> &BaseOps,
+ int64_t &Offset, bool &OffsetIsScalable, unsigned &Width,
+ const TargetRegisterInfo *TRI) const {
return false;
}
@@ -1268,9 +1281,15 @@ public:
/// or
/// DAG->addMutation(createStoreClusterDAGMutation(DAG->TII, DAG->TRI));
/// to TargetPassConfig::createMachineScheduler() to have an effect.
- virtual bool shouldClusterMemOps(const MachineOperand &BaseOp1,
- const MachineOperand &BaseOp2,
- unsigned NumLoads) const {
+ ///
+ /// \p BaseOps1 and \p BaseOps2 are memory operands of two memory operations.
+ /// \p NumLoads is the number of loads that will be in the cluster if this
+ /// hook returns true.
+ /// \p NumBytes is the number of bytes that will be loaded from all the
+ /// clustered loads if this hook returns true.
+ virtual bool shouldClusterMemOps(ArrayRef<const MachineOperand *> BaseOps1,
+ ArrayRef<const MachineOperand *> BaseOps2,
+ unsigned NumLoads, unsigned NumBytes) const {
llvm_unreachable("target did not implement shouldClusterMemOps()");
}
@@ -1294,9 +1313,14 @@ public:
/// Returns true if the instruction is already predicated.
virtual bool isPredicated(const MachineInstr &MI) const { return false; }
+ // Returns a MIRPrinter comment for this machine operand.
+ virtual std::string
+ createMIROperandComment(const MachineInstr &MI, const MachineOperand &Op,
+ unsigned OpIdx, const TargetRegisterInfo *TRI) const;
+
/// Returns true if the instruction is a
/// terminator instruction that has not been predicated.
- virtual bool isUnpredicatedTerminator(const MachineInstr &MI) const;
+ bool isUnpredicatedTerminator(const MachineInstr &MI) const;
/// Returns true if MI is an unconditional tail call.
virtual bool isUnconditionalTailCall(const MachineInstr &MI) const {
@@ -1394,16 +1418,16 @@ public:
/// in SrcReg and SrcReg2 if having two register operands, and the value it
/// compares against in CmpValue. Return true if the comparison instruction
/// can be analyzed.
- virtual bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
- unsigned &SrcReg2, int &Mask, int &Value) const {
+ virtual bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
+ Register &SrcReg2, int &Mask, int &Value) const {
return false;
}
/// See if the comparison instruction can be converted
/// into something more efficient. E.g., on ARM most instructions can set the
/// flags register, obviating the need for a separate CMP.
- virtual bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
- unsigned SrcReg2, int Mask, int Value,
+ virtual bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
+ Register SrcReg2, int Mask, int Value,
const MachineRegisterInfo *MRI) const {
return false;
}
@@ -1430,7 +1454,7 @@ public:
/// block. The caller may assume that it will not be erased by this
/// function otherwise.
virtual bool FoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI,
- unsigned Reg, MachineRegisterInfo *MRI) const {
+ Register Reg, MachineRegisterInfo *MRI) const {
return false;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h
index 24daf70dc008..06f2b3ca38ea 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLowering.h
@@ -28,7 +28,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/CodeGen/DAGCombine.h"
#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/RuntimeLibcalls.h"
@@ -37,7 +36,6 @@
#include "llvm/CodeGen/TargetCallingConv.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
@@ -47,14 +45,11 @@
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Type.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Alignment.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MachineValueType.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Transforms/Utils/SizeOpts.h"
#include <algorithm>
#include <cassert>
#include <climits>
@@ -88,9 +83,12 @@ class MachineRegisterInfo;
class MCContext;
class MCExpr;
class Module;
-class TargetRegisterClass;
+class ProfileSummaryInfo;
class TargetLibraryInfo;
+class TargetMachine;
+class TargetRegisterClass;
class TargetRegisterInfo;
+class TargetTransformInfo;
class Value;
namespace Sched {
@@ -106,6 +104,85 @@ namespace Sched {
} // end namespace Sched
+// MemOp models a memory operation, either memset or memcpy/memmove.
+struct MemOp {
+private:
+ // Shared
+ uint64_t Size;
+ bool DstAlignCanChange; // true if destination alignment can satisfy any
+ // constraint.
+ Align DstAlign; // Specified alignment of the memory operation.
+
+ bool AllowOverlap;
+ // memset only
+ bool IsMemset; // If setthis memory operation is a memset.
+ bool ZeroMemset; // If set clears out memory with zeros.
+ // memcpy only
+ bool MemcpyStrSrc; // Indicates whether the memcpy source is an in-register
+ // constant so it does not need to be loaded.
+ Align SrcAlign; // Inferred alignment of the source or default value if the
+ // memory operation does not need to load the value.
+public:
+ static MemOp Copy(uint64_t Size, bool DstAlignCanChange, Align DstAlign,
+ Align SrcAlign, bool IsVolatile,
+ bool MemcpyStrSrc = false) {
+ MemOp Op;
+ Op.Size = Size;
+ Op.DstAlignCanChange = DstAlignCanChange;
+ Op.DstAlign = DstAlign;
+ Op.AllowOverlap = !IsVolatile;
+ Op.IsMemset = false;
+ Op.ZeroMemset = false;
+ Op.MemcpyStrSrc = MemcpyStrSrc;
+ Op.SrcAlign = SrcAlign;
+ return Op;
+ }
+
+ static MemOp Set(uint64_t Size, bool DstAlignCanChange, Align DstAlign,
+ bool IsZeroMemset, bool IsVolatile) {
+ MemOp Op;
+ Op.Size = Size;
+ Op.DstAlignCanChange = DstAlignCanChange;
+ Op.DstAlign = DstAlign;
+ Op.AllowOverlap = !IsVolatile;
+ Op.IsMemset = true;
+ Op.ZeroMemset = IsZeroMemset;
+ Op.MemcpyStrSrc = false;
+ return Op;
+ }
+
+ uint64_t size() const { return Size; }
+ Align getDstAlign() const {
+ assert(!DstAlignCanChange);
+ return DstAlign;
+ }
+ bool isFixedDstAlign() const { return !DstAlignCanChange; }
+ bool allowOverlap() const { return AllowOverlap; }
+ bool isMemset() const { return IsMemset; }
+ bool isMemcpy() const { return !IsMemset; }
+ bool isMemcpyWithFixedDstAlign() const {
+ return isMemcpy() && !DstAlignCanChange;
+ }
+ bool isZeroMemset() const { return isMemset() && ZeroMemset; }
+ bool isMemcpyStrSrc() const {
+ assert(isMemcpy() && "Must be a memcpy");
+ return MemcpyStrSrc;
+ }
+ Align getSrcAlign() const {
+ assert(isMemcpy() && "Must be a memcpy");
+ return SrcAlign;
+ }
+ bool isSrcAligned(Align AlignCheck) const {
+ return isMemset() || llvm::isAligned(AlignCheck, SrcAlign.value());
+ }
+ bool isDstAligned(Align AlignCheck) const {
+ return DstAlignCanChange || llvm::isAligned(AlignCheck, DstAlign.value());
+ }
+ bool isAligned(Align AlignCheck) const {
+ return isSrcAligned(AlignCheck) && isDstAligned(AlignCheck);
+ }
+};
+
/// This base class for TargetLowering contains the SelectionDAG-independent
/// parts that can be used from the rest of CodeGen.
class TargetLoweringBase {
@@ -131,7 +208,15 @@ public:
TypeScalarizeVector, // Replace this one-element vector with its element.
TypeSplitVector, // Split this vector into two of half the size.
TypeWidenVector, // This vector should be widened into a larger vector.
- TypePromoteFloat // Replace this float with a larger one.
+ TypePromoteFloat, // Replace this float with a larger one.
+ TypeSoftPromoteHalf, // Soften half to i16 and use float to do arithmetic.
+ TypeScalarizeScalableVector, // This action is explicitly left unimplemented.
+ // While it is theoretically possible to
+ // legalize operations on scalable types with a
+ // loop that handles the vscale * #lanes of the
+ // vector, this is non-trivial at SelectionDAG
+ // level and these types are better to be
+ // widened or promoted.
};
/// LegalizeKind holds the legalization kind that needs to happen to EVT
@@ -175,6 +260,13 @@ public:
// or custom.
};
+ /// Enum that specifies when a float negation is beneficial.
+ enum class NegatibleCost {
+ Cheaper = 0, // Negated expression is cheaper.
+ Neutral = 1, // Negated expression has the same cost.
+ Expensive = 2 // Negated expression is more expensive.
+ };
+
class ArgListEntry {
public:
Value *Val = nullptr;
@@ -187,23 +279,22 @@ public:
bool IsNest : 1;
bool IsByVal : 1;
bool IsInAlloca : 1;
+ bool IsPreallocated : 1;
bool IsReturned : 1;
bool IsSwiftSelf : 1;
bool IsSwiftError : 1;
bool IsCFGuardTarget : 1;
- uint16_t Alignment = 0;
+ MaybeAlign Alignment = None;
Type *ByValType = nullptr;
+ Type *PreallocatedType = nullptr;
ArgListEntry()
: IsSExt(false), IsZExt(false), IsInReg(false), IsSRet(false),
- IsNest(false), IsByVal(false), IsInAlloca(false), IsReturned(false),
- IsSwiftSelf(false), IsSwiftError(false), IsCFGuardTarget(false) {}
+ IsNest(false), IsByVal(false), IsInAlloca(false),
+ IsPreallocated(false), IsReturned(false), IsSwiftSelf(false),
+ IsSwiftError(false), IsCFGuardTarget(false) {}
void setAttributes(const CallBase *Call, unsigned ArgIdx);
-
- void setAttributes(ImmutableCallSite *CS, unsigned ArgIdx) {
- return setAttributes(cast<CallBase>(CS->getInstruction()), ArgIdx);
- }
};
using ArgListTy = std::vector<ArgListEntry>;
@@ -264,6 +355,12 @@ public:
return getPointerTy(DL, DL.getAllocaAddrSpace());
}
+ /// Return the type for code pointers, which is determined by the program
+ /// address space specified through the data layout.
+ MVT getProgramPointerTy(const DataLayout &DL) const {
+ return getPointerTy(DL, DL.getProgramAddressSpace());
+ }
+
/// Return the type for operands of fence.
/// TODO: Let fence operands be of i32 type and remove this.
virtual MVT getFenceOperandTy(const DataLayout &DL) const {
@@ -284,6 +381,20 @@ public:
return getPointerTy(DL);
}
+ /// This callback is used to inspect load/store instructions and add
+ /// target-specific MachineMemOperand flags to them. The default
+ /// implementation does nothing.
+ virtual MachineMemOperand::Flags getTargetMMOFlags(const Instruction &I) const {
+ return MachineMemOperand::MONone;
+ }
+
+ MachineMemOperand::Flags getLoadMemOperandFlags(const LoadInst &LI,
+ const DataLayout &DL) const;
+ MachineMemOperand::Flags getStoreMemOperandFlags(const StoreInst &SI,
+ const DataLayout &DL) const;
+ MachineMemOperand::Flags getAtomicMemOperandFlags(const Instruction &AI,
+ const DataLayout &DL) const;
+
virtual bool isSelectSupported(SelectSupportKind /*kind*/) const {
return true;
}
@@ -308,7 +419,7 @@ public:
virtual TargetLoweringBase::LegalizeTypeAction
getPreferredVectorAction(MVT VT) const {
// The default action for one element vectors is to scalarize
- if (VT.getVectorNumElements() == 1)
+ if (VT.getVectorElementCount() == 1)
return TypeScalarizeVector;
// The default action for an odd-width vector is to widen.
if (!VT.isPow2VectorType())
@@ -317,6 +428,12 @@ public:
return TypePromoteInteger;
}
+ // Return true if the half type should be passed around as i16, but promoted
+ // to float around arithmetic. The default behavior is to pass around as
+ // float and convert around loads/stores/bitcasts and other places where
+ // the size matters.
+ virtual bool softPromoteHalfType() const { return false; }
+
// There are two general methods for expanding a BUILD_VECTOR node:
// 1. Use SCALAR_TO_VECTOR on the defined scalar values and then shuffle
// them together.
@@ -399,6 +516,10 @@ public:
return PredictableSelectIsExpensive;
}
+ virtual bool fallBackToDAGISel(const Instruction &Inst) const {
+ return false;
+ }
+
/// If a branch or a select condition is skewed in one direction by more than
/// this factor, it is very likely to be predicted correctly.
virtual BranchProbability getPredictableBranchThreshold() const;
@@ -850,7 +971,7 @@ public:
int offset = 0; // offset off of ptrVal
uint64_t size = 0; // the size of the memory location
// (taken from memVT if zero)
- MaybeAlign align = Align::None(); // alignment
+ MaybeAlign align = Align(1); // alignment
MachineMemOperand::Flags flags = MachineMemOperand::MONone;
IntrinsicInfo() = default;
@@ -936,7 +1057,9 @@ public:
case ISD::UMULFIX:
case ISD::UMULFIXSAT:
case ISD::SDIVFIX:
+ case ISD::SDIVFIXSAT:
case ISD::UDIVFIX:
+ case ISD::UDIVFIXSAT:
Supported = isSupportedFixedPointOperation(Op, VT, Scale);
break;
}
@@ -950,7 +1073,7 @@ public:
unsigned EqOpc;
switch (Op) {
default: llvm_unreachable("Unexpected FP pseudo-opcode");
-#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
+#define DAG_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
case ISD::STRICT_##DAGN: EqOpc = ISD::DAGN; break;
#define CMP_INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
case ISD::STRICT_##DAGN: EqOpc = ISD::SETCC; break;
@@ -1349,7 +1472,7 @@ public:
/// type has the alignment requirement of another type.
virtual Align getABIAlignmentForCallingConv(Type *ArgTy,
DataLayout DL) const {
- return Align(DL.getABITypeAlignment(ArgTy));
+ return DL.getABITypeAlign(ArgTy);
}
/// If true, then instruction selection should seek to shrink the FP constant
@@ -1459,7 +1582,7 @@ public:
/// LLT handling variant.
virtual bool allowsMisalignedMemoryAccesses(
- LLT, unsigned AddrSpace = 0, unsigned Align = 1,
+ LLT, unsigned AddrSpace = 0, Align Alignment = Align(1),
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
bool * /*Fast*/ = nullptr) const {
return false;
@@ -1471,7 +1594,7 @@ public:
/// (as defined by the target).
bool allowsMemoryAccessForAlignment(
LLVMContext &Context, const DataLayout &DL, EVT VT,
- unsigned AddrSpace = 0, unsigned Alignment = 1,
+ unsigned AddrSpace = 0, Align Alignment = Align(1),
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
bool *Fast = nullptr) const;
@@ -1490,7 +1613,7 @@ public:
/// target).
virtual bool
allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT,
- unsigned AddrSpace = 0, unsigned Alignment = 1,
+ unsigned AddrSpace = 0, Align Alignment = Align(1),
MachineMemOperand::Flags Flags = MachineMemOperand::MONone,
bool *Fast = nullptr) const;
@@ -1504,29 +1627,17 @@ public:
/// Returns the target specific optimal type for load and store operations as
/// a result of memset, memcpy, and memmove lowering.
- ///
- /// If DstAlign is zero that means it's safe to destination alignment can
- /// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
- /// a need to check it against alignment requirement, probably because the
- /// source does not need to be loaded. If 'IsMemset' is true, that means it's
- /// expanding a memset. If 'ZeroMemset' is true, that means it's a memset of
- /// zero. 'MemcpyStrSrc' indicates whether the memcpy source is constant so it
- /// does not need to be loaded. It returns EVT::Other if the type should be
- /// determined using generic target-independent logic.
+ /// It returns EVT::Other if the type should be determined using generic
+ /// target-independent logic.
virtual EVT
- getOptimalMemOpType(uint64_t /*Size*/, unsigned /*DstAlign*/,
- unsigned /*SrcAlign*/, bool /*IsMemset*/,
- bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/,
+ getOptimalMemOpType(const MemOp &Op,
const AttributeList & /*FuncAttributes*/) const {
return MVT::Other;
}
-
/// LLT returning variant.
virtual LLT
- getOptimalMemOpLLT(uint64_t /*Size*/, unsigned /*DstAlign*/,
- unsigned /*SrcAlign*/, bool /*IsMemset*/,
- bool /*ZeroMemset*/, bool /*MemcpyStrSrc*/,
+ getOptimalMemOpLLT(const MemOp &Op,
const AttributeList & /*FuncAttributes*/) const {
return LLT();
}
@@ -1550,9 +1661,11 @@ public:
/// Zero if no limit.
unsigned getMaximumJumpTableSize() const;
- virtual bool isJumpTableRelative() const {
- return TM.isPositionIndependent();
- }
+ virtual bool isJumpTableRelative() const;
+
+ /// Return true if a mulh[s|u] node for a specific type is cheaper than
+ /// a multiply followed by a shift. This is false by default.
+ virtual bool isMulhCheaperThanMulShift(EVT Type) const { return false; }
/// If a physical register, this specifies the register that
/// llvm.savestack/llvm.restorestack should save and restore.
@@ -1562,18 +1675,16 @@ public:
/// If a physical register, this returns the register that receives the
/// exception address on entry to an EH pad.
- virtual unsigned
+ virtual Register
getExceptionPointerRegister(const Constant *PersonalityFn) const {
- // 0 is guaranteed to be the NoRegister value on all targets
- return 0;
+ return Register();
}
/// If a physical register, this returns the register that receives the
/// exception typeid on entry to a landing pad.
- virtual unsigned
+ virtual Register
getExceptionSelectorRegister(const Constant *PersonalityFn) const {
- // 0 is guaranteed to be the NoRegister value on all targets
- return 0;
+ return Register();
}
virtual bool needsFixedCatchObjects() const {
@@ -1639,6 +1750,10 @@ public:
/// Returns the name of the symbol used to emit stack probes or the empty
/// string if not applicable.
+ virtual bool hasStackProbeSymbol(MachineFunction &MF) const { return false; }
+
+ virtual bool hasInlineStackProbe(MachineFunction &MF) const { return false; }
+
virtual StringRef getStackProbeSymbolName(MachineFunction &MF) const {
return "";
}
@@ -1861,6 +1976,18 @@ public:
return ISD::ZERO_EXTEND;
}
+ /// Returns how the platform's atomic compare and swap expects its comparison
+ /// value to be extended (ZERO_EXTEND, SIGN_EXTEND, or ANY_EXTEND). This is
+ /// separate from getExtendForAtomicOps, which is concerned with the
+ /// sign-extension of the instruction's output, whereas here we are concerned
+ /// with the sign-extension of the input. For targets with compare-and-swap
+ /// instructions (or sub-word comparisons in their LL/SC loop expansions),
+ /// the input can be ANY_EXTEND, but the output will still have a specific
+ /// extension.
+ virtual ISD::NodeType getExtendForAtomicCmpSwapArg() const {
+ return ISD::ANY_EXTEND;
+ }
+
/// @}
/// Returns true if we should normalize
@@ -1949,7 +2076,7 @@ protected:
/// If set to a physical register, this specifies the register that
/// llvm.savestack/llvm.restorestack should save and restore.
- void setStackPointerRegisterToSaveRestore(unsigned R) {
+ void setStackPointerRegisterToSaveRestore(Register R) {
StackPointerRegisterToSaveRestore = R;
}
@@ -2224,13 +2351,31 @@ public:
}
/// Return true if it's significantly cheaper to shift a vector by a uniform
- /// scalar than by an amount which will vary across each lane. On x86, for
- /// example, there is a "psllw" instruction for the former case, but no simple
- /// instruction for a general "a << b" operation on vectors.
+ /// scalar than by an amount which will vary across each lane. On x86 before
+ /// AVX2 for example, there is a "psllw" instruction for the former case, but
+ /// no simple instruction for a general "a << b" operation on vectors.
+ /// This should also apply to lowering for vector funnel shifts (rotates).
virtual bool isVectorShiftByScalarCheap(Type *Ty) const {
return false;
}
+ /// Given a shuffle vector SVI representing a vector splat, return a new
+ /// scalar type of size equal to SVI's scalar type if the new type is more
+ /// profitable. Returns nullptr otherwise. For example under MVE float splats
+ /// are converted to integer to prevent the need to move from SPR to GPR
+ /// registers.
+ virtual Type* shouldConvertSplatType(ShuffleVectorInst* SVI) const {
+ return nullptr;
+ }
+
+ /// Given a set in interconnected phis of type 'From' that are loaded/stored
+ /// or bitcast to type 'To', return true if the set should be converted to
+ /// 'To'.
+ virtual bool shouldConvertPhiType(Type *From, Type *To) const {
+ return (From->isIntegerTy() || From->isFloatingPointTy()) &&
+ (To->isIntegerTy() || To->isFloatingPointTy());
+ }
+
/// Returns true if the opcode is a commutative binary operation.
virtual bool isCommutativeBinOp(unsigned Opcode) const {
// FIXME: This should get its info from the td file.
@@ -2427,7 +2572,7 @@ public:
/// this information should not be provided because it will generate more
/// loads.
virtual bool hasPairedLoad(EVT /*LoadedType*/,
- unsigned & /*RequiredAlignment*/) const {
+ Align & /*RequiredAlignment*/) const {
return false;
}
@@ -2525,11 +2670,13 @@ public:
return false;
}
- /// Returns true if the FADD or FSUB node passed could legally be combined with
- /// an fmul to form an ISD::FMAD.
- virtual bool isFMADLegalForFAddFSub(const SelectionDAG &DAG,
- const SDNode *N) const {
- assert(N->getOpcode() == ISD::FADD || N->getOpcode() == ISD::FSUB);
+ /// Returns true if be combined with to form an ISD::FMAD. \p N may be an
+ /// ISD::FADD, ISD::FSUB, or an ISD::FMUL which will be distributed into an
+ /// fadd/fsub.
+ virtual bool isFMADLegal(const SelectionDAG &DAG, const SDNode *N) const {
+ assert((N->getOpcode() == ISD::FADD || N->getOpcode() == ISD::FSUB ||
+ N->getOpcode() == ISD::FMUL) &&
+ "unexpected node in FMAD forming combine");
return isOperationLegal(ISD::FMAD, N->getValueType(0));
}
@@ -2577,17 +2724,21 @@ public:
/// node operation. Targets may want to override this independently of whether
/// the operation is legal/custom for the given type because it may obscure
/// matching of other patterns.
- virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT) const {
+ virtual bool shouldFormOverflowOp(unsigned Opcode, EVT VT,
+ bool MathUsed) const {
// TODO: The default logic is inherited from code in CodeGenPrepare.
// The opcode should not make a difference by default?
if (Opcode != ISD::UADDO)
return false;
// Allow the transform as long as we have an integer type that is not
- // obviously illegal and unsupported.
+ // obviously illegal and unsupported and if the math result is used
+ // besides the overflow check. On some targets (e.g. SPARC), it is
+ // not profitable to form on overflow op if the math result has no
+ // concrete users.
if (VT.isVector())
return false;
- return VT.isSimple() || !isOperationExpand(Opcode, VT);
+ return MathUsed && (VT.isSimple() || !isOperationExpand(Opcode, VT));
}
// Return true if it is profitable to use a scalar input to a BUILD_VECTOR
@@ -2649,6 +2800,13 @@ public:
/// The default implementation just freezes the set of reserved registers.
virtual void finalizeLowering(MachineFunction &MF) const;
+ //===----------------------------------------------------------------------===//
+ // GlobalISel Hooks
+ //===----------------------------------------------------------------------===//
+ /// Check whether or not \p MI needs to be moved close to its uses.
+ virtual bool shouldLocalize(const MachineInstr &MI, const TargetTransformInfo *TTI) const;
+
+
private:
const TargetMachine &TM;
@@ -2719,7 +2877,7 @@ private:
/// If set to a physical register, this specifies the register that
/// llvm.savestack/llvm.restorestack should save and restore.
- unsigned StackPointerRegisterToSaveRestore;
+ Register StackPointerRegisterToSaveRestore;
/// This indicates the default register class to use for each ValueType the
/// target supports natively.
@@ -3088,27 +3246,28 @@ public:
/// Return true if the number of memory ops is below the threshold (Limit).
/// It returns the types of the sequence of memory ops to perform
/// memset / memcpy by reference.
- bool findOptimalMemOpLowering(std::vector<EVT> &MemOps,
- unsigned Limit, uint64_t Size,
- unsigned DstAlign, unsigned SrcAlign,
- bool IsMemset,
- bool ZeroMemset,
- bool MemcpyStrSrc,
- bool AllowOverlap,
- unsigned DstAS, unsigned SrcAS,
+ bool findOptimalMemOpLowering(std::vector<EVT> &MemOps, unsigned Limit,
+ const MemOp &Op, unsigned DstAS, unsigned SrcAS,
const AttributeList &FuncAttributes) const;
/// Check to see if the specified operand of the specified instruction is a
/// constant integer. If so, check to see if there are any bits set in the
/// constant that are not demanded. If so, shrink the constant and return
/// true.
- bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
+ const APInt &DemandedElts,
+ TargetLoweringOpt &TLO) const;
+
+ /// Helper wrapper around ShrinkDemandedConstant, demanding all elements.
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &DemandedBits,
TargetLoweringOpt &TLO) const;
// Target hook to do target-specific const optimization, which is called by
// ShrinkDemandedConstant. This function should return true if the target
// doesn't want ShrinkDemandedConstant to further optimize the constant.
- virtual bool targetShrinkDemandedConstant(SDValue Op, const APInt &Demanded,
+ virtual bool targetShrinkDemandedConstant(SDValue Op,
+ const APInt &DemandedBits,
+ const APInt &DemandedElts,
TargetLoweringOpt &TLO) const {
return false;
}
@@ -3146,7 +3305,7 @@ public:
/// Helper wrapper around SimplifyDemandedBits.
/// Adds Op back to the worklist upon success.
- bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedBits,
DAGCombinerInfo &DCI) const;
/// More limited version of SimplifyDemandedBits that can be used to "look
@@ -3157,6 +3316,19 @@ public:
SelectionDAG &DAG,
unsigned Depth) const;
+ /// Helper wrapper around SimplifyMultipleUseDemandedBits, demanding all
+ /// elements.
+ SDValue SimplifyMultipleUseDemandedBits(SDValue Op, const APInt &DemandedBits,
+ SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
+ /// Helper wrapper around SimplifyMultipleUseDemandedBits, demanding all
+ /// bits from only some vector elements.
+ SDValue SimplifyMultipleUseDemandedVectorElts(SDValue Op,
+ const APInt &DemandedElts,
+ SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
/// Look at Vector Op. At this point, we know that only the DemandedElts
/// elements of the result of Op are ever used downstream. If we can use
/// this information to simplify Op, create a new simplified DAG node and
@@ -3191,6 +3363,7 @@ public:
const APInt &DemandedElts,
const SelectionDAG &DAG,
unsigned Depth = 0) const;
+
/// Determine which of the bits specified in Mask are known to be either zero
/// or one and return them in the KnownZero/KnownOne bitsets. The DemandedElts
/// argument allows us to only collect the known bits that are shared by the
@@ -3201,14 +3374,21 @@ public:
const MachineRegisterInfo &MRI,
unsigned Depth = 0) const;
+ /// Determine the known alignment for the pointer value \p R. This is can
+ /// typically be inferred from the number of low known 0 bits. However, for a
+ /// pointer with a non-integral address space, the alignment value may be
+ /// independent from the known low bits.
+ virtual Align computeKnownAlignForTargetInstr(GISelKnownBits &Analysis,
+ Register R,
+ const MachineRegisterInfo &MRI,
+ unsigned Depth = 0) const;
+
/// Determine which of the bits of FrameIndex \p FIOp are known to be 0.
/// Default implementation computes low bits based on alignment
/// information. This should preserve known bits passed into it.
- virtual void computeKnownBitsForFrameIndex(const SDValue FIOp,
+ virtual void computeKnownBitsForFrameIndex(int FIOp,
KnownBits &Known,
- const APInt &DemandedElts,
- const SelectionDAG &DAG,
- unsigned Depth = 0) const;
+ const MachineFunction &MF) const;
/// This method can be implemented by targets that want to expose additional
/// information about sign bits to the DAG Combiner. The DemandedElts
@@ -3219,6 +3399,16 @@ public:
const SelectionDAG &DAG,
unsigned Depth = 0) const;
+ /// This method can be implemented by targets that want to expose additional
+ /// information about sign bits to GlobalISel combiners. The DemandedElts
+ /// argument allows us to only collect the minimum sign bits that are shared
+ /// by the requested vector elements.
+ virtual unsigned computeNumSignBitsForTargetInstr(GISelKnownBits &Analysis,
+ Register R,
+ const APInt &DemandedElts,
+ const MachineRegisterInfo &MRI,
+ unsigned Depth = 0) const;
+
/// Attempt to simplify any target nodes based on the demanded vector
/// elements, returning true on success. Otherwise, analyze the expression and
/// return a mask of KnownUndef and KnownZero elements for the expression
@@ -3346,20 +3536,6 @@ public:
return true;
}
- // Return true if it is profitable to combine a BUILD_VECTOR with a stride-pattern
- // to a shuffle and a truncate.
- // Example of such a combine:
- // v4i32 build_vector((extract_elt V, 1),
- // (extract_elt V, 3),
- // (extract_elt V, 5),
- // (extract_elt V, 7))
- // -->
- // v4i32 truncate (bitcast (shuffle<1,u,3,u,5,u,7,u> V, u) to v4i64)
- virtual bool isDesirableToCombineBuildVectorToShuffleTruncate(
- ArrayRef<int> ShuffleMask, EVT SrcVT, EVT TruncVT) const {
- return false;
- }
-
/// Return true if the target has native support for the specified value type
/// and it is 'desirable' to use the type for the given node type. e.g. On x86
/// i16 is legal, but undesirable since i16 instruction encodings are longer
@@ -3413,23 +3589,61 @@ public:
llvm_unreachable("Not Implemented");
}
- /// Return 1 if we can compute the negated form of the specified expression
- /// for the same cost as the expression itself, or 2 if we can compute the
- /// negated form more cheaply than the expression itself. Else return 0.
- virtual char isNegatibleForFree(SDValue Op, SelectionDAG &DAG,
- bool LegalOperations, bool ForCodeSize,
- unsigned Depth = 0) const;
-
- /// If isNegatibleForFree returns true, return the newly negated expression.
+ /// Return the newly negated expression if the cost is not expensive and
+ /// set the cost in \p Cost to indicate that if it is cheaper or neutral to
+ /// do the negation.
virtual SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG,
- bool LegalOperations, bool ForCodeSize,
+ bool LegalOps, bool OptForSize,
+ NegatibleCost &Cost,
unsigned Depth = 0) const;
+ /// This is the helper function to return the newly negated expression only
+ /// when the cost is cheaper.
+ SDValue getCheaperNegatedExpression(SDValue Op, SelectionDAG &DAG,
+ bool LegalOps, bool OptForSize,
+ unsigned Depth = 0) const {
+ NegatibleCost Cost = NegatibleCost::Expensive;
+ SDValue Neg =
+ getNegatedExpression(Op, DAG, LegalOps, OptForSize, Cost, Depth);
+ if (Neg && Cost == NegatibleCost::Cheaper)
+ return Neg;
+ // Remove the new created node to avoid the side effect to the DAG.
+ if (Neg && Neg.getNode()->use_empty())
+ DAG.RemoveDeadNode(Neg.getNode());
+ return SDValue();
+ }
+
+ /// This is the helper function to return the newly negated expression if
+ /// the cost is not expensive.
+ SDValue getNegatedExpression(SDValue Op, SelectionDAG &DAG, bool LegalOps,
+ bool OptForSize, unsigned Depth = 0) const {
+ NegatibleCost Cost = NegatibleCost::Expensive;
+ return getNegatedExpression(Op, DAG, LegalOps, OptForSize, Cost, Depth);
+ }
+
//===--------------------------------------------------------------------===//
// Lowering methods - These methods must be implemented by targets so that
// the SelectionDAGBuilder code knows how to lower these.
//
+ /// Target-specific splitting of values into parts that fit a register
+ /// storing a legal type
+ virtual bool splitValueIntoRegisterParts(SelectionDAG &DAG, const SDLoc &DL,
+ SDValue Val, SDValue *Parts,
+ unsigned NumParts, MVT PartVT,
+ Optional<CallingConv::ID> CC) const {
+ return false;
+ }
+
+ /// Target-specific combining of register parts into its original value
+ virtual SDValue
+ joinRegisterPartsIntoValue(SelectionDAG &DAG, const SDLoc &DL,
+ const SDValue *Parts, unsigned NumParts,
+ MVT PartVT, EVT ValueVT,
+ Optional<CallingConv::ID> CC) const {
+ return SDValue();
+ }
+
/// This hook must be implemented to lower the incoming (formal) arguments,
/// described by the Ins array, into the specified DAG. The implementation
/// should fill in the InVals array with legal-type argument values, and
@@ -3456,6 +3670,8 @@ public:
bool IsReturnValueUsed : 1;
bool IsConvergent : 1;
bool IsPatchPoint : 1;
+ bool IsPreallocated : 1;
+ bool NoMerge : 1;
// IsTailCall should be modified by implementations of
// TargetLowering::LowerCall that perform tail call conversions.
@@ -3470,7 +3686,7 @@ public:
ArgListTy Args;
SelectionDAG &DAG;
SDLoc DL;
- ImmutableCallSite CS;
+ const CallBase *CB = nullptr;
SmallVector<ISD::OutputArg, 32> Outs;
SmallVector<SDValue, 32> OutVals;
SmallVector<ISD::InputArg, 32> Ins;
@@ -3479,7 +3695,8 @@ public:
CallLoweringInfo(SelectionDAG &DAG)
: RetSExt(false), RetZExt(false), IsVarArg(false), IsInReg(false),
DoesNotReturn(false), IsReturnValueUsed(true), IsConvergent(false),
- IsPatchPoint(false), DAG(DAG) {}
+ IsPatchPoint(false), IsPreallocated(false), NoMerge(false),
+ DAG(DAG) {}
CallLoweringInfo &setDebugLoc(const SDLoc &dl) {
DL = dl;
@@ -3517,26 +3734,26 @@ public:
CallLoweringInfo &setCallee(Type *ResultType, FunctionType *FTy,
SDValue Target, ArgListTy &&ArgsList,
- ImmutableCallSite Call) {
+ const CallBase &Call) {
RetTy = ResultType;
IsInReg = Call.hasRetAttr(Attribute::InReg);
DoesNotReturn =
Call.doesNotReturn() ||
- (!Call.isInvoke() &&
- isa<UnreachableInst>(Call.getInstruction()->getNextNode()));
+ (!isa<InvokeInst>(Call) && isa<UnreachableInst>(Call.getNextNode()));
IsVarArg = FTy->isVarArg();
- IsReturnValueUsed = !Call.getInstruction()->use_empty();
+ IsReturnValueUsed = !Call.use_empty();
RetSExt = Call.hasRetAttr(Attribute::SExt);
RetZExt = Call.hasRetAttr(Attribute::ZExt);
-
+ NoMerge = Call.hasFnAttr(Attribute::NoMerge);
+
Callee = Target;
CallConv = Call.getCallingConv();
NumFixedArgs = FTy->getNumParams();
Args = std::move(ArgsList);
- CS = Call;
+ CB = &Call;
return *this;
}
@@ -3586,6 +3803,11 @@ public:
return *this;
}
+ CallLoweringInfo &setIsPreallocated(bool Value = true) {
+ IsPreallocated = Value;
+ return *this;
+ }
+
CallLoweringInfo &setIsPostTypeLegalization(bool Value=true) {
IsPostTypeLegalization = Value;
return *this;
@@ -3659,7 +3881,7 @@ public:
}
/// Target-specific cleanup for formal ByVal parameters.
- virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
+ virtual void HandleByVal(CCState *, unsigned &, Align) const {}
/// This hook should be implemented to check whether the return values
/// described by the Outs array can fit into the return registers. If false
@@ -3763,13 +3985,6 @@ public:
return Chain;
}
- /// This callback is used to inspect load/store instructions and add
- /// target-specific MachineMemOperand flags to them. The default
- /// implementation does nothing.
- virtual MachineMemOperand::Flags getMMOFlags(const Instruction &I) const {
- return MachineMemOperand::MONone;
- }
-
/// Should SelectionDAG lower an atomic store of the given kind as a normal
/// StoreSDNode (as opposed to an AtomicSDNode)? NOTE: The intention is to
/// eventually migrate all targets to the using StoreSDNodes, but porting is
@@ -3782,7 +3997,7 @@ public:
/// Should SelectionDAG lower an atomic load of the given kind as a normal
/// LoadSDNode (as opposed to an AtomicSDNode)? NOTE: The intention is to
/// eventually migrate all targets to the using LoadSDNodes, but porting is
- /// being done target at a time.
+ /// being done target at a time.
virtual bool lowerAtomicLoadAsLoadSDNode(const LoadInst &LI) const {
assert(LI.isAtomic() && "violated precondition");
return false;
@@ -3918,7 +4133,7 @@ public:
/// string itself isn't empty, there was an error parsing.
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL,
const TargetRegisterInfo *TRI,
- ImmutableCallSite CS) const;
+ const CallBase &Call) const;
/// Examine constraint type and operand type and determine a weight value.
/// The operand object must already have been set up with the operand type.
@@ -4186,7 +4401,7 @@ public:
/// method accepts integers as its arguments.
SDValue expandFixedPointMul(SDNode *Node, SelectionDAG &DAG) const;
- /// Method for building the DAG expansion of ISD::[US]DIVFIX. This
+ /// Method for building the DAG expansion of ISD::[US]DIVFIX[SAT]. This
/// method accepts integers as its arguments.
/// Note: This method may fail if the division could not be performed
/// within the type. Clients must retry with a wider type if this happens.
@@ -4213,6 +4428,10 @@ public:
/// only the first Count elements of the vector are used.
SDValue expandVecReduce(SDNode *Node, SelectionDAG &DAG) const;
+ /// Expand an SREM or UREM using SDIV/UDIV or SDIVREM/UDIVREM, if legal.
+ /// Returns true if the expansion was successful.
+ bool expandREM(SDNode *Node, SDValue &Result, SelectionDAG &DAG) const;
+
//===--------------------------------------------------------------------===//
// Instruction Emitting Hooks
//
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 4f58df93b93e..6e2c0973e354 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -15,18 +15,17 @@
#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
#include "llvm/BinaryFormat/XCOFF.h"
-#include "llvm/IR/Module.h"
-#include "llvm/MC/MCExpr.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
namespace llvm {
class GlobalValue;
class MachineModuleInfo;
-class Mangler;
class MCContext;
+class MCExpr;
class MCSection;
class MCSymbol;
+class Module;
class TargetMachine;
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
@@ -54,7 +53,7 @@ public:
/// placed in.
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
const Constant *C,
- unsigned &Align) const override;
+ Align &Alignment) const override;
MCSection *getExplicitSectionGlobal(const GlobalObject *GO, SectionKind Kind,
const TargetMachine &TM) const override;
@@ -65,6 +64,11 @@ public:
MCSection *getSectionForJumpTable(const Function &F,
const TargetMachine &TM) const override;
+ MCSection *
+ getSectionForMachineBasicBlock(const Function &F,
+ const MachineBasicBlock &MBB,
+ const TargetMachine &TM) const override;
+
bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference,
const Function &F) const override;
@@ -112,7 +116,7 @@ public:
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
const Constant *C,
- unsigned &Align) const override;
+ Align &Alignment) const override;
/// The mach-o version of this method defaults to returning a stub reference.
const MCExpr *getTTypeGlobalReference(const GlobalValue *GV,
@@ -178,7 +182,7 @@ public:
/// information, return a section that it should be placed in.
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
const Constant *C,
- unsigned &Align) const override;
+ Align &Alignment) const override;
};
class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
@@ -240,9 +244,27 @@ public:
/// placed in.
MCSection *getSectionForConstant(const DataLayout &DL, SectionKind Kind,
const Constant *C,
- unsigned &Align) const override;
+ Align &Alignment) const override;
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalObject *GO);
+
+ MCSection *
+ getSectionForFunctionDescriptor(const Function *F,
+ const TargetMachine &TM) const override;
+ MCSection *getSectionForTOCEntry(const MCSymbol *Sym) const override;
+
+ /// For external functions, this will always return a function descriptor
+ /// csect.
+ MCSection *
+ getSectionForExternalReference(const GlobalObject *GO,
+ const TargetMachine &TM) const override;
+
+ /// For functions, this will always return a function descriptor symbol.
+ MCSymbol *getTargetSymbol(const GlobalValue *GV,
+ const TargetMachine &TM) const override;
+
+ MCSymbol *getFunctionEntryPointSymbol(const Function *F,
+ const TargetMachine &TM) const override;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h
index d48fc664c1c3..a18c8b16bf1c 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h
@@ -103,6 +103,7 @@ private:
bool Started = true;
bool Stopped = false;
bool AddingMachinePasses = false;
+ bool DebugifyIsSafe = true;
/// Set the StartAfter, StartBefore and StopAfter passes to allow running only
/// a portion of the normal code-gen pass sequence.
@@ -166,8 +167,8 @@ public:
/// If hasLimitedCodeGenPipeline is true, this method
/// returns a string with the name of the options, separated
/// by \p Separator that caused this pipeline to be limited.
- std::string
- getLimitedCodeGenPipelineReason(const char *Separator = "/") const;
+ static std::string
+ getLimitedCodeGenPipelineReason(const char *Separator = "/");
void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
@@ -306,6 +307,21 @@ public:
/// verification is enabled.
void addVerifyPass(const std::string &Banner);
+ /// Add a pass to add synthesized debug info to the MIR.
+ void addDebugifyPass();
+
+ /// Add a pass to remove debug info from the MIR.
+ void addStripDebugPass();
+
+ /// Add standard passes before a pass that's about to be added. For example,
+ /// the DebugifyMachineModulePass if it is enabled.
+ void addMachinePrePasses(bool AllowDebugify = true);
+
+ /// Add standard passes after a pass that has just been added. For example,
+ /// the MachineVerifier if it is enabled.
+ void addMachinePostPasses(const std::string &Banner, bool AllowPrint = true,
+ bool AllowVerify = true, bool AllowStrip = true);
+
/// Check whether or not GlobalISel should abort on error.
/// When this is disabled, GlobalISel will fall back on SDISel instead of
/// erroring out.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index c42ca3ad6eb9..d921c4c9028b 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -40,6 +40,7 @@ class MachineInstr;
class RegScavenger;
class VirtRegMap;
class LiveIntervals;
+class LiveInterval;
class TargetRegisterClass {
public:
@@ -80,7 +81,7 @@ public:
}
/// Return the specified register in the class.
- unsigned getRegister(unsigned i) const {
+ MCRegister getRegister(unsigned i) const {
return MC->getRegister(i);
}
@@ -284,6 +285,12 @@ public:
return getRegClassInfo(RC).SpillAlignment / 8;
}
+ /// Return the minimum required alignment in bytes for a spill slot for
+ /// a register of this class.
+ Align getSpillAlign(const TargetRegisterClass &RC) const {
+ return Align(getRegClassInfo(RC).SpillAlignment / 8);
+ }
+
/// Return true if the given TargetRegisterClass has the ValueType T.
bool isTypeLegalForClass(const TargetRegisterClass &RC, MVT T) const {
for (auto I = legalclasstypes_begin(RC); *I != MVT::Other; ++I)
@@ -308,8 +315,8 @@ public:
/// Returns the Register Class of a physical register of the given type,
/// picking the most sub register class of the right type that contains this
/// physreg.
- const TargetRegisterClass *
- getMinimalPhysRegClass(unsigned Reg, MVT VT = MVT::Other) const;
+ const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
+ MVT VT = MVT::Other) const;
/// Return the maximal subclass of the given register class that is
/// allocatable or NULL.
@@ -324,12 +331,12 @@ public:
/// Return the additional cost of using this register instead
/// of other registers in its class.
- unsigned getCostPerUse(unsigned RegNo) const {
+ unsigned getCostPerUse(MCRegister RegNo) const {
return InfoDesc[RegNo].CostPerUse;
}
/// Return true if the register is in the allocation of any register class.
- bool isInAllocatableClass(unsigned RegNo) const {
+ bool isInAllocatableClass(MCRegister RegNo) const {
return InfoDesc[RegNo].inAllocatableClass;
}
@@ -394,7 +401,7 @@ public:
}
/// Returns true if Reg contains RegUnit.
- bool hasRegUnit(unsigned Reg, unsigned RegUnit) const {
+ bool hasRegUnit(MCRegister Reg, unsigned RegUnit) const {
for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units)
if (*Units == RegUnit)
return true;
@@ -405,7 +412,7 @@ public:
/// operation, in which case we chain backwards through all such operations
/// to the ultimate source register. If a physical register is encountered,
/// we stop the search.
- virtual unsigned lookThruCopyLike(unsigned SrcReg,
+ virtual Register lookThruCopyLike(Register SrcReg,
const MachineRegisterInfo *MRI) const;
/// Return a null-terminated list of all of the callee-saved registers on
@@ -478,13 +485,19 @@ public:
/// Returns false if we can't guarantee that Physreg, specified as an IR asm
/// clobber constraint, will be preserved across the statement.
virtual bool isAsmClobberable(const MachineFunction &MF,
- unsigned PhysReg) const {
+ MCRegister PhysReg) const {
return true;
}
+ /// Returns true if PhysReg cannot be written to in inline asm statements.
+ virtual bool isInlineAsmReadOnlyReg(const MachineFunction &MF,
+ unsigned PhysReg) const {
+ return false;
+ }
+
/// Returns true if PhysReg is unallocatable and constant throughout the
/// function. Used by MachineRegisterInfo::isConstantPhysReg().
- virtual bool isConstantPhysReg(unsigned PhysReg) const { return false; }
+ virtual bool isConstantPhysReg(MCRegister PhysReg) const { return false; }
/// Returns true if the register class is considered divergent.
virtual bool isDivergentRegClass(const TargetRegisterClass *RC) const {
@@ -496,14 +509,14 @@ public:
/// have call sequences where a GOT register may be updated by the caller
/// prior to a call and is guaranteed to be restored (also by the caller)
/// after the call.
- virtual bool isCallerPreservedPhysReg(unsigned PhysReg,
+ virtual bool isCallerPreservedPhysReg(MCRegister PhysReg,
const MachineFunction &MF) const {
return false;
}
/// This is a wrapper around getCallPreservedMask().
/// Return true if the register is preserved after the call.
- virtual bool isCalleeSavedPhysReg(unsigned PhysReg,
+ virtual bool isCalleeSavedPhysReg(MCRegister PhysReg,
const MachineFunction &MF) const;
/// Prior to adding the live-out mask to a stackmap or patchpoint
@@ -513,8 +526,8 @@ public:
/// Return a super-register of the specified register
/// Reg so its sub-register of index SubIdx is Reg.
- unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx,
- const TargetRegisterClass *RC) const {
+ MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx,
+ const TargetRegisterClass *RC) const {
return MCRegisterInfo::getMatchingSuperReg(Reg, SubIdx, RC->MC);
}
@@ -598,8 +611,8 @@ public:
}
/// Debugging helper: dump register in human readable form to dbgs() stream.
- static void dumpReg(unsigned Reg, unsigned SubRegIndex = 0,
- const TargetRegisterInfo* TRI = nullptr);
+ static void dumpReg(Register Reg, unsigned SubRegIndex = 0,
+ const TargetRegisterInfo *TRI = nullptr);
protected:
/// Overridden by TableGen in targets that have sub-registers.
@@ -738,7 +751,7 @@ public:
const TargetRegisterClass *RC) const = 0;
/// Returns size in bits of a phys/virtual/generic register.
- unsigned getRegSizeInBits(unsigned Reg, const MachineRegisterInfo &MRI) const;
+ unsigned getRegSizeInBits(Register Reg, const MachineRegisterInfo &MRI) const;
/// Get the weight in units of pressure for this register unit.
virtual unsigned getRegUnitWeight(unsigned RegUnit) const = 0;
@@ -777,20 +790,19 @@ public:
/// independent register allocation hints. Targets that override this
/// function should typically call this default implementation as well and
/// expect to see generic copy hints added.
- virtual bool getRegAllocationHints(unsigned VirtReg,
- ArrayRef<MCPhysReg> Order,
- SmallVectorImpl<MCPhysReg> &Hints,
- const MachineFunction &MF,
- const VirtRegMap *VRM = nullptr,
- const LiveRegMatrix *Matrix = nullptr)
- const;
+ virtual bool
+ getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,
+ SmallVectorImpl<MCPhysReg> &Hints,
+ const MachineFunction &MF,
+ const VirtRegMap *VRM = nullptr,
+ const LiveRegMatrix *Matrix = nullptr) const;
/// A callback to allow target a chance to update register allocation hints
/// when a register is "changed" (e.g. coalesced) to another register.
/// e.g. On ARM, some virtual registers should target register pairs,
/// if one of pair is coalesced to another register, the allocation hint of
/// the other half of the pair should be changed to point to the new register.
- virtual void updateRegAllocHint(unsigned Reg, unsigned NewReg,
+ virtual void updateRegAllocHint(Register Reg, Register NewReg,
MachineFunction &MF) const {
// Do nothing.
}
@@ -848,14 +860,14 @@ public:
/// spill slot. This tells PEI not to create a new stack frame
/// object for the given register. It should be called only after
/// determineCalleeSaves().
- virtual bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
+ virtual bool hasReservedSpillSlot(const MachineFunction &MF, Register Reg,
int &FrameIdx) const {
return false;
}
/// Returns true if the live-ins should be tracked after register allocation.
virtual bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const {
- return false;
+ return true;
}
/// True if the stack can be realigned for the target.
@@ -885,7 +897,7 @@ public:
/// Insert defining instruction(s) for BaseReg to be a pointer to FrameIdx
/// before insertion point I.
virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB,
- unsigned BaseReg, int FrameIdx,
+ Register BaseReg, int FrameIdx,
int64_t Offset) const {
llvm_unreachable("materializeFrameBaseRegister does not exist on this "
"target");
@@ -893,14 +905,14 @@ public:
/// Resolve a frame index operand of an instruction
/// to reference the indicated base register plus offset instead.
- virtual void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
+ virtual void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
int64_t Offset) const {
llvm_unreachable("resolveFrameIndex does not exist on this target");
}
/// Determine whether a given base register plus offset immediate is
/// encodable to resolve a frame index.
- virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
+ virtual bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
int64_t Offset) const {
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
@@ -913,7 +925,7 @@ public:
MachineBasicBlock::iterator I,
MachineBasicBlock::iterator &UseMI,
const TargetRegisterClass *RC,
- unsigned Reg) const {
+ Register Reg) const {
return false;
}
@@ -929,7 +941,7 @@ public:
RegScavenger *RS = nullptr) const = 0;
/// Return the assembly name for \p Reg.
- virtual StringRef getRegAsmName(unsigned Reg) const {
+ virtual StringRef getRegAsmName(MCRegister Reg) const {
// FIXME: We are assuming that the assembly name is equal to the TableGen
// name converted to lower case
//
@@ -952,6 +964,12 @@ public:
LiveIntervals &LIS) const
{ return true; }
+ /// Region split has a high compile time cost especially for large live range.
+ /// This method is used to decide whether or not \p VirtReg should
+ /// go through this expensive splitting heuristic.
+ virtual bool shouldRegionSplitForVirtReg(const MachineFunction &MF,
+ const LiveInterval &VirtReg) const;
+
//===--------------------------------------------------------------------===//
/// Debug information queries.
@@ -960,7 +978,7 @@ public:
virtual Register getFrameRegister(const MachineFunction &MF) const = 0;
/// Mark a register and all its aliases as reserved in the given set.
- void markSuperRegs(BitVector &RegisterSet, unsigned Reg) const;
+ void markSuperRegs(BitVector &RegisterSet, MCRegister Reg) const;
/// Returns true if for every register in the set all super registers are part
/// of the set as well.
@@ -1164,7 +1182,7 @@ Printable printVRegOrUnit(unsigned VRegOrUnit, const TargetRegisterInfo *TRI);
/// Create Printable object to print register classes or register banks
/// on a \ref raw_ostream.
-Printable printRegClassOrBank(unsigned Reg, const MachineRegisterInfo &RegInfo,
+Printable printRegClassOrBank(Register Reg, const MachineRegisterInfo &RegInfo,
const TargetRegisterInfo *TRI);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
index 6768cea89406..e0dfd9c8bbc5 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetSubtargetInfo.h
@@ -25,10 +25,10 @@
#include <memory>
#include <vector>
-
namespace llvm {
class CallLowering;
+class InlineAsmLowering;
class InstrItineraryData;
struct InstrStage;
class InstructionSelector;
@@ -41,9 +41,6 @@ struct MCWriteProcResEntry;
class RegisterBankInfo;
class SDep;
class SelectionDAGTargetInfo;
-struct SubtargetFeatureKV;
-struct SubtargetSubTypeKV;
-struct SubtargetInfoKV;
class SUnit;
class TargetFrameLowering;
class TargetInstrInfo;
@@ -102,6 +99,10 @@ public:
}
virtual const CallLowering *getCallLowering() const { return nullptr; }
+ virtual const InlineAsmLowering *getInlineAsmLowering() const {
+ return nullptr;
+ }
+
// FIXME: This lets targets specialize the selector by subtarget (which lets
// us do things like a dedicated avx512 selector). However, we might want
// to also specialize selectors by MachineFunction, which would let us be
@@ -224,9 +225,13 @@ public:
virtual void overrideSchedPolicy(MachineSchedPolicy &Policy,
unsigned NumRegionInstrs) const {}
- // Perform target specific adjustments to the latency of a schedule
+ // Perform target-specific adjustments to the latency of a schedule
// dependency.
- virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {}
+ // If a pair of operands is associated with the schedule dependency, DefOpIdx
+ // and UseOpIdx are the indices of the operands in Def and Use, respectively.
+ // Otherwise, either may be -1.
+ virtual void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use,
+ int UseOpIdx, SDep &Dep) const {}
// For use with PostRAScheduling: get the anti-dependence breaking that should
// be performed before post-RA scheduling.
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.h
index bcf417762920..db8161caf7d2 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.h
@@ -19,6 +19,7 @@
#include "llvm/Support/MachineValueType.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/TypeSize.h"
+#include "llvm/Support/WithColor.h"
#include <cassert>
#include <cstdint>
#include <string>
@@ -75,9 +76,7 @@ namespace llvm {
MVT M = MVT::getVectorVT(VT.V, NumElements, IsScalable);
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
return M;
-
- assert(!IsScalable && "We don't support extended scalable types yet");
- return getExtendedVectorVT(Context, VT, NumElements);
+ return getExtendedVectorVT(Context, VT, NumElements, IsScalable);
}
/// Returns the EVT that represents a vector EC.Min elements in length,
@@ -86,24 +85,30 @@ namespace llvm {
MVT M = MVT::getVectorVT(VT.V, EC);
if (M.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE)
return M;
- assert (!EC.Scalable && "We don't support extended scalable types yet");
- return getExtendedVectorVT(Context, VT, EC.Min);
+ return getExtendedVectorVT(Context, VT, EC);
}
/// Return a vector with the same number of elements as this vector, but
/// with the element type converted to an integer type with the same
/// bitwidth.
EVT changeVectorElementTypeToInteger() const {
- if (!isSimple()) {
- assert (!isScalableVector() &&
- "We don't support extended scalable types yet");
+ if (!isSimple())
return changeExtendedVectorElementTypeToInteger();
- }
MVT EltTy = getSimpleVT().getVectorElementType();
unsigned BitWidth = EltTy.getSizeInBits();
MVT IntTy = MVT::getIntegerVT(BitWidth);
- MVT VecTy = MVT::getVectorVT(IntTy, getVectorNumElements(),
- isScalableVector());
+ MVT VecTy = MVT::getVectorVT(IntTy, getVectorElementCount());
+ assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
+ "Simple vector VT not representable by simple integer vector VT!");
+ return VecTy;
+ }
+
+ /// Return a VT for a vector type whose attributes match ourselves
+ /// with the exception of the element type that is chosen by the caller.
+ EVT changeVectorElementType(EVT EltVT) const {
+ if (!isSimple())
+ return changeExtendedVectorElementType(EltVT);
+ MVT VecTy = MVT::getVectorVT(EltVT.V, getVectorElementCount());
assert(VecTy.SimpleTy != MVT::INVALID_SIMPLE_VALUE_TYPE &&
"Simple vector VT not representable by simple integer vector VT!");
return VecTy;
@@ -155,12 +160,12 @@ namespace llvm {
/// Return true if this is a vector type where the runtime
/// length is machine dependent
bool isScalableVector() const {
- // FIXME: We don't support extended scalable types yet, because the
- // matching IR type doesn't exist. Once it has been added, this can
- // be changed to call isExtendedScalableVector.
- if (!isSimple())
- return false;
- return V.isScalableVector();
+ return isSimple() ? V.isScalableVector() : isExtendedScalableVector();
+ }
+
+ bool isFixedLengthVector() const {
+ return isSimple() ? V.isFixedLengthVector()
+ : isExtendedFixedLengthVector();
}
/// Return true if this is a 16-bit vector type.
@@ -273,7 +278,16 @@ namespace llvm {
/// Given a vector type, return the number of elements it contains.
unsigned getVectorNumElements() const {
+#ifdef STRICT_FIXED_SIZE_VECTORS
+ assert(isFixedLengthVector() && "Invalid vector type!");
+#else
assert(isVector() && "Invalid vector type!");
+ if (isScalableVector())
+ WithColor::warning()
+ << "Possible incorrect use of EVT::getVectorNumElements() for "
+ "scalable vector. Scalable flag may be dropped, use"
+ "EVT::getVectorElementCount() instead\n";
+#endif
if (isSimple())
return V.getVectorNumElements();
return getExtendedVectorNumElements();
@@ -285,9 +299,12 @@ namespace llvm {
if (isSimple())
return V.getVectorElementCount();
- assert(!isScalableVector() &&
- "We don't support extended scalable types yet");
- return {getExtendedVectorNumElements(), false};
+ return getExtendedVectorElementCount();
+ }
+
+ /// Given a vector type, return the minimum number of elements it contains.
+ unsigned getVectorMinNumElements() const {
+ return getVectorElementCount().Min;
}
/// Return the size of the specified value type in bits.
@@ -372,7 +389,7 @@ namespace llvm {
/// Returns true if the given vector is a power of 2.
bool isPow2VectorType() const {
- unsigned NElts = getVectorNumElements();
+ unsigned NElts = getVectorMinNumElements();
return !(NElts & (NElts - 1));
}
@@ -380,10 +397,9 @@ namespace llvm {
/// and returns that type.
EVT getPow2VectorType(LLVMContext &Context) const {
if (!isPow2VectorType()) {
- unsigned NElts = getVectorNumElements();
- unsigned Pow2NElts = 1 << Log2_32_Ceil(NElts);
- return EVT::getVectorVT(Context, getVectorElementType(), Pow2NElts,
- isScalableVector());
+ ElementCount NElts = getVectorElementCount();
+ NElts.Min = 1 << Log2_32_Ceil(NElts.Min);
+ return EVT::getVectorVT(Context, getVectorElementType(), NElts);
}
else {
return *this;
@@ -426,10 +442,13 @@ namespace llvm {
// These are all out-of-line to prevent users of this header file
// from having a dependency on Type.h.
EVT changeExtendedTypeToInteger() const;
+ EVT changeExtendedVectorElementType(EVT EltVT) const;
EVT changeExtendedVectorElementTypeToInteger() const;
static EVT getExtendedIntegerVT(LLVMContext &C, unsigned BitWidth);
- static EVT getExtendedVectorVT(LLVMContext &C, EVT VT,
- unsigned NumElements);
+ static EVT getExtendedVectorVT(LLVMContext &C, EVT VT, unsigned NumElements,
+ bool IsScalable);
+ static EVT getExtendedVectorVT(LLVMContext &Context, EVT VT,
+ ElementCount EC);
bool isExtendedFloatingPoint() const LLVM_READONLY;
bool isExtendedInteger() const LLVM_READONLY;
bool isExtendedScalarInteger() const LLVM_READONLY;
@@ -442,8 +461,11 @@ namespace llvm {
bool isExtended512BitVector() const LLVM_READONLY;
bool isExtended1024BitVector() const LLVM_READONLY;
bool isExtended2048BitVector() const LLVM_READONLY;
+ bool isExtendedFixedLengthVector() const LLVM_READONLY;
+ bool isExtendedScalableVector() const LLVM_READONLY;
EVT getExtendedVectorElementType() const;
unsigned getExtendedVectorNumElements() const LLVM_READONLY;
+ ElementCount getExtendedVectorElementCount() const LLVM_READONLY;
TypeSize getExtendedSizeInBits() const LLVM_READONLY;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.td b/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.td
index 16df565bc8b8..c5eb87cf1d34 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.td
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/ValueTypes.td
@@ -25,147 +25,170 @@ def i16 : ValueType<16 , 4>; // 16-bit integer value
def i32 : ValueType<32 , 5>; // 32-bit integer value
def i64 : ValueType<64 , 6>; // 64-bit integer value
def i128 : ValueType<128, 7>; // 128-bit integer value
-def f16 : ValueType<16 , 8>; // 16-bit floating point value
-def f32 : ValueType<32 , 9>; // 32-bit floating point value
-def f64 : ValueType<64 , 10>; // 64-bit floating point value
-def f80 : ValueType<80 , 11>; // 80-bit floating point value
-def f128 : ValueType<128, 12>; // 128-bit floating point value
-def ppcf128: ValueType<128, 13>; // PPC 128-bit floating point value
-
-def v1i1 : ValueType<1 , 14>; // 1 x i1 vector value
-def v2i1 : ValueType<2 , 15>; // 2 x i1 vector value
-def v4i1 : ValueType<4 , 16>; // 4 x i1 vector value
-def v8i1 : ValueType<8 , 17>; // 8 x i1 vector value
-def v16i1 : ValueType<16, 18>; // 16 x i1 vector value
-def v32i1 : ValueType<32 , 19>; // 32 x i1 vector value
-def v64i1 : ValueType<64 , 20>; // 64 x i1 vector value
-def v128i1 : ValueType<128, 21>; // 128 x i1 vector value
-def v256i1 : ValueType<256, 22>; // 256 x i1 vector value
-def v512i1 : ValueType<512, 23>; // 512 x i1 vector value
-def v1024i1: ValueType<1024,24>; //1024 x i1 vector value
-
-def v1i8 : ValueType<8, 25>; // 1 x i8 vector value
-def v2i8 : ValueType<16 , 26>; // 2 x i8 vector value
-def v4i8 : ValueType<32 , 27>; // 4 x i8 vector value
-def v8i8 : ValueType<64 , 28>; // 8 x i8 vector value
-def v16i8 : ValueType<128, 29>; // 16 x i8 vector value
-def v32i8 : ValueType<256, 30>; // 32 x i8 vector value
-def v64i8 : ValueType<512, 31>; // 64 x i8 vector value
-def v128i8 : ValueType<1024,32>; //128 x i8 vector value
-def v256i8 : ValueType<2048,33>; //256 x i8 vector value
-
-def v1i16 : ValueType<16 , 34>; // 1 x i16 vector value
-def v2i16 : ValueType<32 , 35>; // 2 x i16 vector value
-def v3i16 : ValueType<48 , 36>; // 3 x i16 vector value
-def v4i16 : ValueType<64 , 37>; // 4 x i16 vector value
-def v8i16 : ValueType<128, 38>; // 8 x i16 vector value
-def v16i16 : ValueType<256, 39>; // 16 x i16 vector value
-def v32i16 : ValueType<512, 40>; // 32 x i16 vector value
-def v64i16 : ValueType<1024,41>; // 64 x i16 vector value
-def v128i16: ValueType<2048,42>; //128 x i16 vector value
-
-def v1i32 : ValueType<32 , 43>; // 1 x i32 vector value
-def v2i32 : ValueType<64 , 44>; // 2 x i32 vector value
-def v3i32 : ValueType<96 , 45>; // 3 x i32 vector value
-def v4i32 : ValueType<128, 46>; // 4 x i32 vector value
-def v5i32 : ValueType<160, 47>; // 5 x i32 vector value
-def v8i32 : ValueType<256, 48>; // 8 x i32 vector value
-def v16i32 : ValueType<512, 49>; // 16 x i32 vector value
-def v32i32 : ValueType<1024,50>; // 32 x i32 vector value
-def v64i32 : ValueType<2048,51>; // 64 x i32 vector value
-def v128i32 : ValueType<4096,52>; // 128 x i32 vector value
-def v256i32 : ValueType<8182,53>; // 256 x i32 vector value
-def v512i32 : ValueType<16384,54>; // 512 x i32 vector value
-def v1024i32 : ValueType<32768,55>; // 1024 x i32 vector value
-def v2048i32 : ValueType<65536,56>; // 2048 x i32 vector value
-
-def v1i64 : ValueType<64 , 57>; // 1 x i64 vector value
-def v2i64 : ValueType<128, 58>; // 2 x i64 vector value
-def v4i64 : ValueType<256, 59>; // 4 x i64 vector value
-def v8i64 : ValueType<512, 60>; // 8 x i64 vector value
-def v16i64 : ValueType<1024,61>; // 16 x i64 vector value
-def v32i64 : ValueType<2048,62>; // 32 x i64 vector value
-
-def v1i128 : ValueType<128, 63>; // 1 x i128 vector value
-
-def v2f16 : ValueType<32 , 64>; // 2 x f16 vector value
-def v3f16 : ValueType<48 , 65>; // 3 x f16 vector value
-def v4f16 : ValueType<64 , 66>; // 4 x f16 vector value
-def v8f16 : ValueType<128, 67>; // 8 x f16 vector value
-def v16f16 : ValueType<256, 68>; // 8 x f16 vector value
-def v32f16 : ValueType<512, 69>; // 8 x f16 vector value
-def v1f32 : ValueType<32 , 70>; // 1 x f32 vector value
-def v2f32 : ValueType<64 , 71>; // 2 x f32 vector value
-def v3f32 : ValueType<96 , 72>; // 3 x f32 vector value
-def v4f32 : ValueType<128, 73>; // 4 x f32 vector value
-def v5f32 : ValueType<160, 74>; // 5 x f32 vector value
-def v8f32 : ValueType<256, 75>; // 8 x f32 vector value
-def v16f32 : ValueType<512, 76>; // 16 x f32 vector value
-def v32f32 : ValueType<1024, 77>; // 32 x f32 vector value
-def v64f32 : ValueType<2048, 78>; // 64 x f32 vector value
-def v128f32 : ValueType<4096, 79>; // 128 x f32 vector value
-def v256f32 : ValueType<8182, 80>; // 256 x f32 vector value
-def v512f32 : ValueType<16384, 81>; // 512 x f32 vector value
-def v1024f32 : ValueType<32768, 82>; // 1024 x f32 vector value
-def v2048f32 : ValueType<65536, 83>; // 2048 x f32 vector value
-def v1f64 : ValueType<64, 84>; // 1 x f64 vector value
-def v2f64 : ValueType<128, 85>; // 2 x f64 vector value
-def v4f64 : ValueType<256, 86>; // 4 x f64 vector value
-def v8f64 : ValueType<512, 87>; // 8 x f64 vector value
-
-def nxv1i1 : ValueType<1, 88>; // n x 1 x i1 vector value
-def nxv2i1 : ValueType<2, 89>; // n x 2 x i1 vector value
-def nxv4i1 : ValueType<4, 90>; // n x 4 x i1 vector value
-def nxv8i1 : ValueType<8, 91>; // n x 8 x i1 vector value
-def nxv16i1 : ValueType<16, 92>; // n x 16 x i1 vector value
-def nxv32i1 : ValueType<32, 93>; // n x 32 x i1 vector value
-
-def nxv1i8 : ValueType<8, 94>; // n x 1 x i8 vector value
-def nxv2i8 : ValueType<16, 95>; // n x 2 x i8 vector value
-def nxv4i8 : ValueType<32, 96>; // n x 4 x i8 vector value
-def nxv8i8 : ValueType<64, 97>; // n x 8 x i8 vector value
-def nxv16i8 : ValueType<128, 98>; // n x 16 x i8 vector value
-def nxv32i8 : ValueType<256, 99>; // n x 32 x i8 vector value
-
-def nxv1i16 : ValueType<16, 100>; // n x 1 x i16 vector value
-def nxv2i16 : ValueType<32, 101>; // n x 2 x i16 vector value
-def nxv4i16 : ValueType<64, 102>; // n x 4 x i16 vector value
-def nxv8i16 : ValueType<128, 103>; // n x 8 x i16 vector value
-def nxv16i16: ValueType<256, 104>; // n x 16 x i16 vector value
-def nxv32i16: ValueType<512, 105>; // n x 32 x i16 vector value
-
-def nxv1i32 : ValueType<32, 106>; // n x 1 x i32 vector value
-def nxv2i32 : ValueType<64, 107>; // n x 2 x i32 vector value
-def nxv4i32 : ValueType<128, 108>; // n x 4 x i32 vector value
-def nxv8i32 : ValueType<256, 109>; // n x 8 x i32 vector value
-def nxv16i32: ValueType<512, 110>; // n x 16 x i32 vector value
-def nxv32i32: ValueType<1024,111>; // n x 32 x i32 vector value
-
-def nxv1i64 : ValueType<64, 112>; // n x 1 x i64 vector value
-def nxv2i64 : ValueType<128, 113>; // n x 2 x i64 vector value
-def nxv4i64 : ValueType<256, 114>; // n x 4 x i64 vector value
-def nxv8i64 : ValueType<512, 115>; // n x 8 x i64 vector value
-def nxv16i64: ValueType<1024,116>; // n x 16 x i64 vector value
-def nxv32i64: ValueType<2048,117>; // n x 32 x i64 vector value
-
-def nxv2f16 : ValueType<32 , 118>; // n x 2 x f16 vector value
-def nxv4f16 : ValueType<64 , 119>; // n x 4 x f16 vector value
-def nxv8f16 : ValueType<128, 120>; // n x 8 x f16 vector value
-def nxv1f32 : ValueType<32 , 121>; // n x 1 x f32 vector value
-def nxv2f32 : ValueType<64 , 122>; // n x 2 x f32 vector value
-def nxv4f32 : ValueType<128, 123>; // n x 4 x f32 vector value
-def nxv8f32 : ValueType<256, 124>; // n x 8 x f32 vector value
-def nxv16f32 : ValueType<512, 125>; // n x 16 x f32 vector value
-def nxv1f64 : ValueType<64, 126>; // n x 1 x f64 vector value
-def nxv2f64 : ValueType<128, 127>; // n x 2 x f64 vector value
-def nxv4f64 : ValueType<256, 128>; // n x 4 x f64 vector value
-def nxv8f64 : ValueType<512, 129>; // n x 8 x f64 vector value
-
-def x86mmx : ValueType<64 , 130>; // X86 MMX value
-def FlagVT : ValueType<0 , 131>; // Pre-RA sched glue
-def isVoid : ValueType<0 , 132>; // Produces no value
-def untyped: ValueType<8 , 133>; // Produces an untyped value
-def exnref: ValueType<0, 134>; // WebAssembly's exnref type
+
+def bf16 : ValueType<16 , 8>; // 16-bit brain floating point value
+def f16 : ValueType<16 , 9>; // 16-bit floating point value
+def f32 : ValueType<32 , 10>; // 32-bit floating point value
+def f64 : ValueType<64 , 11>; // 64-bit floating point value
+def f80 : ValueType<80 , 12>; // 80-bit floating point value
+def f128 : ValueType<128, 13>; // 128-bit floating point value
+def ppcf128: ValueType<128, 14>; // PPC 128-bit floating point value
+
+def v1i1 : ValueType<1 , 15>; // 1 x i1 vector value
+def v2i1 : ValueType<2 , 16>; // 2 x i1 vector value
+def v4i1 : ValueType<4 , 17>; // 4 x i1 vector value
+def v8i1 : ValueType<8 , 18>; // 8 x i1 vector value
+def v16i1 : ValueType<16, 19>; // 16 x i1 vector value
+def v32i1 : ValueType<32 , 20>; // 32 x i1 vector value
+def v64i1 : ValueType<64 , 21>; // 64 x i1 vector value
+def v128i1 : ValueType<128, 22>; // 128 x i1 vector value
+def v256i1 : ValueType<256, 23>; // 256 x i1 vector value
+def v512i1 : ValueType<512, 24>; // 512 x i1 vector value
+def v1024i1: ValueType<1024,25>; //1024 x i1 vector value
+
+def v1i8 : ValueType<8, 26>; // 1 x i8 vector value
+def v2i8 : ValueType<16 , 27>; // 2 x i8 vector value
+def v4i8 : ValueType<32 , 28>; // 4 x i8 vector value
+def v8i8 : ValueType<64 , 29>; // 8 x i8 vector value
+def v16i8 : ValueType<128, 30>; // 16 x i8 vector value
+def v32i8 : ValueType<256, 31>; // 32 x i8 vector value
+def v64i8 : ValueType<512, 32>; // 64 x i8 vector value
+def v128i8 : ValueType<1024,33>; //128 x i8 vector value
+def v256i8 : ValueType<2048,34>; //256 x i8 vector value
+
+def v1i16 : ValueType<16 , 35>; // 1 x i16 vector value
+def v2i16 : ValueType<32 , 36>; // 2 x i16 vector value
+def v3i16 : ValueType<48 , 37>; // 3 x i16 vector value
+def v4i16 : ValueType<64 , 38>; // 4 x i16 vector value
+def v8i16 : ValueType<128, 39>; // 8 x i16 vector value
+def v16i16 : ValueType<256, 40>; // 16 x i16 vector value
+def v32i16 : ValueType<512, 41>; // 32 x i16 vector value
+def v64i16 : ValueType<1024,42>; // 64 x i16 vector value
+def v128i16: ValueType<2048,43>; //128 x i16 vector value
+
+def v1i32 : ValueType<32 , 44>; // 1 x i32 vector value
+def v2i32 : ValueType<64 , 45>; // 2 x i32 vector value
+def v3i32 : ValueType<96 , 46>; // 3 x i32 vector value
+def v4i32 : ValueType<128, 47>; // 4 x i32 vector value
+def v5i32 : ValueType<160, 48>; // 5 x i32 vector value
+def v8i32 : ValueType<256, 49>; // 8 x i32 vector value
+def v16i32 : ValueType<512, 50>; // 16 x i32 vector value
+def v32i32 : ValueType<1024,51>; // 32 x i32 vector value
+def v64i32 : ValueType<2048,52>; // 64 x i32 vector value
+def v128i32 : ValueType<4096,53>; // 128 x i32 vector value
+def v256i32 : ValueType<8182,54>; // 256 x i32 vector value
+def v512i32 : ValueType<16384,55>; // 512 x i32 vector value
+def v1024i32 : ValueType<32768,56>; // 1024 x i32 vector value
+def v2048i32 : ValueType<65536,57>; // 2048 x i32 vector value
+
+def v1i64 : ValueType<64 , 58>; // 1 x i64 vector value
+def v2i64 : ValueType<128, 59>; // 2 x i64 vector value
+def v4i64 : ValueType<256, 60>; // 4 x i64 vector value
+def v8i64 : ValueType<512, 61>; // 8 x i64 vector value
+def v16i64 : ValueType<1024,62>; // 16 x i64 vector value
+def v32i64 : ValueType<2048,63>; // 32 x i64 vector value
+
+def v1i128 : ValueType<128, 64>; // 1 x i128 vector value
+
+def v2f16 : ValueType<32 , 65>; // 2 x f16 vector value
+def v3f16 : ValueType<48 , 66>; // 3 x f16 vector value
+def v4f16 : ValueType<64 , 67>; // 4 x f16 vector value
+def v8f16 : ValueType<128, 68>; // 8 x f16 vector value
+def v16f16 : ValueType<256, 69>; // 16 x f16 vector value
+def v32f16 : ValueType<512, 70>; // 32 x f16 vector value
+def v64f16 : ValueType<1024, 71>; // 64 x f16 vector value
+def v128f16 : ValueType<2048, 72>; // 128 x f16 vector value
+def v2bf16 : ValueType<32 , 73>; // 2 x bf16 vector value
+def v3bf16 : ValueType<48 , 74>; // 3 x bf16 vector value
+def v4bf16 : ValueType<64 , 75>; // 4 x bf16 vector value
+def v8bf16 : ValueType<128, 76>; // 8 x bf16 vector value
+def v16bf16 : ValueType<256, 77>; // 16 x bf16 vector value
+def v32bf16 : ValueType<512, 78>; // 32 x bf16 vector value
+def v64bf16 : ValueType<1024, 79>; // 64 x bf16 vector value
+def v128bf16 : ValueType<2048, 80>; // 128 x bf16 vector value
+def v1f32 : ValueType<32 , 81>; // 1 x f32 vector value
+def v2f32 : ValueType<64 , 82>; // 2 x f32 vector value
+def v3f32 : ValueType<96 , 83>; // 3 x f32 vector value
+def v4f32 : ValueType<128, 84>; // 4 x f32 vector value
+def v5f32 : ValueType<160, 85>; // 5 x f32 vector value
+def v8f32 : ValueType<256, 86>; // 8 x f32 vector value
+def v16f32 : ValueType<512, 87>; // 16 x f32 vector value
+def v32f32 : ValueType<1024, 88>; // 32 x f32 vector value
+def v64f32 : ValueType<2048, 89>; // 64 x f32 vector value
+def v128f32 : ValueType<4096, 90>; // 128 x f32 vector value
+def v256f32 : ValueType<8182, 91>; // 256 x f32 vector value
+def v512f32 : ValueType<16384, 92>; // 512 x f32 vector value
+def v1024f32 : ValueType<32768, 93>; // 1024 x f32 vector value
+def v2048f32 : ValueType<65536, 94>; // 2048 x f32 vector value
+def v1f64 : ValueType<64, 95>; // 1 x f64 vector value
+def v2f64 : ValueType<128, 96>; // 2 x f64 vector value
+def v4f64 : ValueType<256, 97>; // 4 x f64 vector value
+def v8f64 : ValueType<512, 98>; // 8 x f64 vector value
+def v16f64 : ValueType<1024, 99>; // 16 x f64 vector value
+def v32f64 : ValueType<2048, 100>; // 32 x f64 vector value
+
+def nxv1i1 : ValueType<1, 101>; // n x 1 x i1 vector value
+def nxv2i1 : ValueType<2, 102>; // n x 2 x i1 vector value
+def nxv4i1 : ValueType<4, 103>; // n x 4 x i1 vector value
+def nxv8i1 : ValueType<8, 104>; // n x 8 x i1 vector value
+def nxv16i1 : ValueType<16, 105>; // n x 16 x i1 vector value
+def nxv32i1 : ValueType<32, 106>; // n x 32 x i1 vector value
+def nxv64i1 : ValueType<64,107>; // n x 64 x i1 vector value
+
+def nxv1i8 : ValueType<8, 108>; // n x 1 x i8 vector value
+def nxv2i8 : ValueType<16, 109>; // n x 2 x i8 vector value
+def nxv4i8 : ValueType<32, 110>; // n x 4 x i8 vector value
+def nxv8i8 : ValueType<64, 111>; // n x 8 x i8 vector value
+def nxv16i8 : ValueType<128, 112>; // n x 16 x i8 vector value
+def nxv32i8 : ValueType<256, 113>; // n x 32 x i8 vector value
+def nxv64i8 : ValueType<512, 114>; // n x 64 x i8 vector value
+
+def nxv1i16 : ValueType<16, 115>; // n x 1 x i16 vector value
+def nxv2i16 : ValueType<32, 116>; // n x 2 x i16 vector value
+def nxv4i16 : ValueType<64, 117>; // n x 4 x i16 vector value
+def nxv8i16 : ValueType<128, 118>; // n x 8 x i16 vector value
+def nxv16i16: ValueType<256, 119>; // n x 16 x i16 vector value
+def nxv32i16: ValueType<512, 120>; // n x 32 x i16 vector value
+
+def nxv1i32 : ValueType<32, 121>; // n x 1 x i32 vector value
+def nxv2i32 : ValueType<64, 122>; // n x 2 x i32 vector value
+def nxv4i32 : ValueType<128, 123>; // n x 4 x i32 vector value
+def nxv8i32 : ValueType<256, 124>; // n x 8 x i32 vector value
+def nxv16i32: ValueType<512, 125>; // n x 16 x i32 vector value
+def nxv32i32: ValueType<1024,126>; // n x 32 x i32 vector value
+
+def nxv1i64 : ValueType<64, 127>; // n x 1 x i64 vector value
+def nxv2i64 : ValueType<128, 128>; // n x 2 x i64 vector value
+def nxv4i64 : ValueType<256, 129>; // n x 4 x i64 vector value
+def nxv8i64 : ValueType<512, 130>; // n x 8 x i64 vector value
+def nxv16i64: ValueType<1024,131>; // n x 16 x i64 vector value
+def nxv32i64: ValueType<2048,132>; // n x 32 x i64 vector value
+
+def nxv1f16 : ValueType<32, 133>; // n x 1 x f16 vector value
+def nxv2f16 : ValueType<32 , 134>; // n x 2 x f16 vector value
+def nxv4f16 : ValueType<64 , 135>; // n x 4 x f16 vector value
+def nxv8f16 : ValueType<128, 136>; // n x 8 x f16 vector value
+def nxv16f16 : ValueType<256,137>; // n x 16 x f16 vector value
+def nxv32f16 : ValueType<512,138>; // n x 32 x f16 vector value
+def nxv2bf16 : ValueType<32 , 139>; // n x 2 x bf16 vector value
+def nxv4bf16 : ValueType<64 , 140>; // n x 4 x bf16 vector value
+def nxv8bf16 : ValueType<128, 141>; // n x 8 x bf16 vector value
+def nxv1f32 : ValueType<32 , 142>; // n x 1 x f32 vector value
+def nxv2f32 : ValueType<64 , 143>; // n x 2 x f32 vector value
+def nxv4f32 : ValueType<128, 144>; // n x 4 x f32 vector value
+def nxv8f32 : ValueType<256, 145>; // n x 8 x f32 vector value
+def nxv16f32 : ValueType<512, 146>; // n x 16 x f32 vector value
+def nxv1f64 : ValueType<64, 147>; // n x 1 x f64 vector value
+def nxv2f64 : ValueType<128, 148>; // n x 2 x f64 vector value
+def nxv4f64 : ValueType<256, 149>; // n x 4 x f64 vector value
+def nxv8f64 : ValueType<512, 150>; // n x 8 x f64 vector value
+
+def x86mmx : ValueType<64 , 151>; // X86 MMX value
+def FlagVT : ValueType<0 , 152>; // Pre-RA sched glue
+def isVoid : ValueType<0 , 153>; // Produces no value
+def untyped: ValueType<8 , 154>; // Produces an untyped value
+def exnref : ValueType<0 , 155>; // WebAssembly's exnref type
+
def token : ValueType<0 , 248>; // TokenTy
def MetadataVT: ValueType<0, 249>; // Metadata
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/VirtRegMap.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/VirtRegMap.h
index db25ed5c5116..823154318eb7 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/VirtRegMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/VirtRegMap.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/IndexedMap.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
-#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include <cassert>
diff --git a/contrib/llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h b/contrib/llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h
index 887a1467b3e4..41f8856f31f2 100644
--- a/contrib/llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/CodeGen/WasmEHFuncInfo.h
@@ -15,11 +15,13 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerUnion.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/IR/BasicBlock.h"
namespace llvm {
+class BasicBlock;
+class Function;
+class MachineBasicBlock;
+
enum EventTag { CPP_EXCEPTION = 0, C_LONGJMP = 1 };
using BBOrMBB = PointerUnion<const BasicBlock *, MachineBasicBlock *>;
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinker.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinker.h
index 80df01ca0539..be3c5ebcadae 100644
--- a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinker.h
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinker.h
@@ -21,6 +21,13 @@ namespace llvm {
enum class DwarfLinkerClient { Dsymutil, LLD, General };
+/// The kind of accelerator tables we should emit.
+enum class AccelTableKind {
+ Apple, ///< .apple_names, .apple_namespaces, .apple_types, .apple_objc.
+ Dwarf, ///< DWARF v5 .debug_names.
+ Default, ///< Dwarf for DWARF5 or later, Apple otherwise.
+};
+
/// Partial address range. Besides an offset, only the
/// HighPC is stored. The structure is stored in a map where the LowPC is the
/// key.
@@ -89,12 +96,10 @@ public:
virtual ~DwarfEmitter();
/// Emit DIE containing warnings.
- virtual void emitPaperTrailWarningsDie(const Triple &Triple, DIE &Die) = 0;
+ virtual void emitPaperTrailWarningsDie(DIE &Die) = 0;
- /// Emit section named SecName with content equals to
- /// corresponding section in Obj.
- virtual void emitSectionContents(const object::ObjectFile &Obj,
- StringRef SecName) = 0;
+ /// Emit section named SecName with data SecData.
+ virtual void emitSectionContents(StringRef SecData, StringRef SecName) = 0;
/// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
virtual void
@@ -193,6 +198,610 @@ public:
virtual uint64_t getDebugInfoSectionSize() const = 0;
};
+using UnitListTy = std::vector<std::unique_ptr<CompileUnit>>;
+
+/// this class represents DWARF information for source file
+/// and it`s address map.
+class DwarfFile {
+public:
+ DwarfFile(StringRef Name, DWARFContext *Dwarf, AddressesMap *Addresses,
+ const std::vector<std::string> &Warnings)
+ : FileName(Name), Dwarf(Dwarf), Addresses(Addresses), Warnings(Warnings) {
+ }
+
+ /// object file name.
+ StringRef FileName;
+ /// source DWARF information.
+ DWARFContext *Dwarf = nullptr;
+ /// helpful address information(list of valid address ranges, relocations).
+ AddressesMap *Addresses = nullptr;
+ /// warnings for object file.
+ const std::vector<std::string> &Warnings;
+};
+
+typedef std::function<void(const Twine &Warning, StringRef Context,
+ const DWARFDie *DIE)>
+ messageHandler;
+typedef std::function<ErrorOr<DwarfFile &>(StringRef ContainerName,
+ StringRef Path)>
+ objFileLoader;
+typedef std::map<std::string, std::string> swiftInterfacesMap;
+typedef std::map<std::string, std::string> objectPrefixMap;
+
+/// The core of the Dwarf linking logic.
+///
+/// The generation of the dwarf information from the object files will be
+/// driven by the selection of 'root DIEs', which are DIEs that
+/// describe variables or functions that resolves to the corresponding
+/// code section(and thus have entries in the Addresses map). All the debug
+/// information that will be generated(the DIEs, but also the line
+/// tables, ranges, ...) is derived from that set of root DIEs.
+///
+/// The root DIEs are identified because they contain relocations that
+/// points to code section(the low_pc for a function, the location for
+/// a variable). These relocations are called ValidRelocs in the
+/// AddressesInfo and are gathered as a very first step when we start
+/// processing a object file.
+class DWARFLinker {
+public:
+ DWARFLinker(DwarfEmitter *Emitter,
+ DwarfLinkerClient ClientID = DwarfLinkerClient::General)
+ : TheDwarfEmitter(Emitter), DwarfLinkerClientID(ClientID) {}
+
+ /// Add object file to be linked.
+ void addObjectFile(DwarfFile &File);
+
+ /// Link debug info for added objFiles. Object
+ /// files are linked all together.
+ bool link();
+
+ /// A number of methods setting various linking options:
+
+ /// Allows to generate log of linking process to the standard output.
+ void setVerbosity(bool Verbose) { Options.Verbose = Verbose; }
+
+ /// Print statistics to standard output.
+ void setStatistics(bool Statistics) { Options.Statistics = Statistics; }
+
+ /// Do not emit linked dwarf info.
+ void setNoOutput(bool NoOut) { Options.NoOutput = NoOut; }
+
+ /// Do not unique types according to ODR.
+ void setNoODR(bool NoODR) { Options.NoODR = NoODR; }
+
+ /// update existing DWARF info(for the linked binary).
+ void setUpdate(bool Update) { Options.Update = Update; }
+
+ /// Use specified number of threads for parallel files linking.
+ void setNumThreads(unsigned NumThreads) { Options.Threads = NumThreads; }
+
+ /// Set kind of accelerator tables to be generated.
+ void setAccelTableKind(AccelTableKind Kind) {
+ Options.TheAccelTableKind = Kind;
+ }
+
+ /// Set prepend path for clang modules.
+ void setPrependPath(const std::string &Ppath) { Options.PrependPath = Ppath; }
+
+ /// Set translator which would be used for strings.
+ void
+ setStringsTranslator(std::function<StringRef(StringRef)> StringsTranslator) {
+ this->StringsTranslator = StringsTranslator;
+ }
+
+ /// Set estimated objects files amount, for preliminary data allocation.
+ void setEstimatedObjfilesAmount(unsigned ObjFilesNum) {
+ ObjectContexts.reserve(ObjFilesNum);
+ }
+
+ /// Set warning handler which would be used to report warnings.
+ void setWarningHandler(messageHandler Handler) {
+ Options.WarningHandler = Handler;
+ }
+
+ /// Set error handler which would be used to report errors.
+ void setErrorHandler(messageHandler Handler) {
+ Options.ErrorHandler = Handler;
+ }
+
+ /// Set object files loader which would be used to load
+ /// additional objects for splitted dwarf.
+ void setObjFileLoader(objFileLoader Loader) {
+ Options.ObjFileLoader = Loader;
+ }
+
+ /// Set map for Swift interfaces.
+ void setSwiftInterfacesMap(swiftInterfacesMap *Map) {
+ Options.ParseableSwiftInterfaces = Map;
+ }
+
+ /// Set prefix map for objects.
+ void setObjectPrefixMap(objectPrefixMap *Map) {
+ Options.ObjectPrefixMap = Map;
+ }
+
+private:
+ /// Flags passed to DwarfLinker::lookForDIEsToKeep
+ enum TraversalFlags {
+ TF_Keep = 1 << 0, ///< Mark the traversed DIEs as kept.
+ TF_InFunctionScope = 1 << 1, ///< Current scope is a function scope.
+ TF_DependencyWalk = 1 << 2, ///< Walking the dependencies of a kept DIE.
+ TF_ParentWalk = 1 << 3, ///< Walking up the parents of a kept DIE.
+ TF_ODR = 1 << 4, ///< Use the ODR while keeping dependents.
+ TF_SkipPC = 1 << 5, ///< Skip all location attributes.
+ };
+
+ /// The distinct types of work performed by the work loop.
+ enum class WorklistItemType {
+ /// Given a DIE, look for DIEs to be kept.
+ LookForDIEsToKeep,
+ /// Given a DIE, look for children of this DIE to be kept.
+ LookForChildDIEsToKeep,
+ /// Given a DIE, look for DIEs referencing this DIE to be kept.
+ LookForRefDIEsToKeep,
+ /// Given a DIE, look for parent DIEs to be kept.
+ LookForParentDIEsToKeep,
+ /// Given a DIE, update its incompleteness based on whether its children are
+ /// incomplete.
+ UpdateChildIncompleteness,
+ /// Given a DIE, update its incompleteness based on whether the DIEs it
+ /// references are incomplete.
+ UpdateRefIncompleteness,
+ };
+
+ /// This class represents an item in the work list. The type defines what kind
+ /// of work needs to be performed when processing the current item. The flags
+ /// and info fields are optional based on the type.
+ struct WorklistItem {
+ WorklistItemType Type;
+ DWARFDie Die;
+ CompileUnit &CU;
+ unsigned Flags;
+ unsigned AncestorIdx = 0;
+ CompileUnit::DIEInfo *OtherInfo = nullptr;
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, unsigned Flags,
+ WorklistItemType T = WorklistItemType::LookForDIEsToKeep)
+ : Type(T), Die(Die), CU(CU), Flags(Flags) {}
+
+ WorklistItem(DWARFDie Die, CompileUnit &CU, WorklistItemType T,
+ CompileUnit::DIEInfo *OtherInfo = nullptr)
+ : Type(T), Die(Die), CU(CU), OtherInfo(OtherInfo) {}
+
+ WorklistItem(unsigned AncestorIdx, CompileUnit &CU, unsigned Flags)
+ : Type(WorklistItemType::LookForParentDIEsToKeep), CU(CU), Flags(Flags),
+ AncestorIdx(AncestorIdx) {}
+ };
+
+ /// returns true if we need to translate strings.
+ bool needToTranslateStrings() { return StringsTranslator != nullptr; }
+
+ void reportWarning(const Twine &Warning, const DwarfFile &File,
+ const DWARFDie *DIE = nullptr) const {
+ if (Options.WarningHandler != nullptr)
+ Options.WarningHandler(Warning, File.FileName, DIE);
+ }
+
+ void reportError(const Twine &Warning, const DwarfFile &File,
+ const DWARFDie *DIE = nullptr) const {
+ if (Options.ErrorHandler != nullptr)
+ Options.ErrorHandler(Warning, File.FileName, DIE);
+ }
+
+ /// Remembers the oldest and newest DWARF version we've seen in a unit.
+ void updateDwarfVersion(unsigned Version) {
+ MaxDwarfVersion = std::max(MaxDwarfVersion, Version);
+ MinDwarfVersion = std::min(MinDwarfVersion, Version);
+ }
+
+ /// Remembers the kinds of accelerator tables we've seen in a unit.
+ void updateAccelKind(DWARFContext &Dwarf);
+
+ /// Emit warnings as Dwarf compile units to leave a trail after linking.
+ bool emitPaperTrailWarnings(const DwarfFile &File,
+ OffsetsStringPool &StringPool);
+
+ void copyInvariantDebugSection(DWARFContext &Dwarf);
+
+ /// Keeps track of data associated with one object during linking.
+ struct LinkContext {
+ DwarfFile &File;
+ UnitListTy CompileUnits;
+ bool Skip = false;
+
+ LinkContext(DwarfFile &File) : File(File) {}
+
+ /// Clear part of the context that's no longer needed when we're done with
+ /// the debug object.
+ void clear() {
+ CompileUnits.clear();
+ File.Addresses->clear();
+ }
+ };
+
+ /// Called before emitting object data
+ void cleanupAuxiliarryData(LinkContext &Context);
+
+ /// Look at the parent of the given DIE and decide whether they should be
+ /// kept.
+ void lookForParentDIEsToKeep(unsigned AncestorIdx, CompileUnit &CU,
+ unsigned Flags,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// Look at the children of the given DIE and decide whether they should be
+ /// kept.
+ void lookForChildDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
+ unsigned Flags,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// Look at DIEs referenced by the given DIE and decide whether they should be
+ /// kept. All DIEs referenced though attributes should be kept.
+ void lookForRefDIEsToKeep(const DWARFDie &Die, CompileUnit &CU,
+ unsigned Flags, const UnitListTy &Units,
+ const DwarfFile &File,
+ SmallVectorImpl<WorklistItem> &Worklist);
+
+ /// \defgroup FindRootDIEs Find DIEs corresponding to Address map entries.
+ ///
+ /// @{
+ /// Recursively walk the \p DIE tree and look for DIEs to
+ /// keep. Store that information in \p CU's DIEInfo.
+ ///
+ /// The return value indicates whether the DIE is incomplete.
+ void lookForDIEsToKeep(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const UnitListTy &Units, const DWARFDie &DIE,
+ const DwarfFile &File, CompileUnit &CU,
+ unsigned Flags);
+
+ /// If this compile unit is really a skeleton CU that points to a
+ /// clang module, register it in ClangModules and return true.
+ ///
+ /// A skeleton CU is a CU without children, a DW_AT_gnu_dwo_name
+ /// pointing to the module, and a DW_AT_gnu_dwo_id with the module
+ /// hash.
+ bool registerModuleReference(DWARFDie CUDie, const DWARFUnit &Unit,
+ const DwarfFile &File,
+ OffsetsStringPool &OffsetsStringPool,
+ UniquingStringPool &UniquingStringPoolStringPool,
+ DeclContextTree &ODRContexts,
+ uint64_t ModulesEndOffset, unsigned &UnitID,
+ bool IsLittleEndian, unsigned Indent = 0,
+ bool Quiet = false);
+
+ /// Recursively add the debug info in this clang module .pcm
+ /// file (and all the modules imported by it in a bottom-up fashion)
+ /// to Units.
+ Error loadClangModule(DWARFDie CUDie, StringRef FilePath,
+ StringRef ModuleName, uint64_t DwoId,
+ const DwarfFile &File,
+ OffsetsStringPool &OffsetsStringPool,
+ UniquingStringPool &UniquingStringPool,
+ DeclContextTree &ODRContexts, uint64_t ModulesEndOffset,
+ unsigned &UnitID, bool IsLittleEndian,
+ unsigned Indent = 0, bool Quiet = false);
+
+ /// Mark the passed DIE as well as all the ones it depends on as kept.
+ void keepDIEAndDependencies(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const UnitListTy &Units, const DWARFDie &DIE,
+ CompileUnit::DIEInfo &MyInfo,
+ const DwarfFile &File, CompileUnit &CU,
+ bool UseODR);
+
+ unsigned shouldKeepDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const DWARFDie &DIE, const DwarfFile &File,
+ CompileUnit &Unit, CompileUnit::DIEInfo &MyInfo,
+ unsigned Flags);
+
+ /// Check if a variable describing DIE should be kept.
+ /// \returns updated TraversalFlags.
+ unsigned shouldKeepVariableDIE(AddressesMap &RelocMgr, const DWARFDie &DIE,
+ CompileUnit &Unit,
+ CompileUnit::DIEInfo &MyInfo, unsigned Flags);
+
+ unsigned shouldKeepSubprogramDIE(AddressesMap &RelocMgr, RangesTy &Ranges,
+ const DWARFDie &DIE, const DwarfFile &File,
+ CompileUnit &Unit,
+ CompileUnit::DIEInfo &MyInfo,
+ unsigned Flags);
+
+ /// Resolve the DIE attribute reference that has been extracted in \p
+ /// RefValue. The resulting DIE might be in another CompileUnit which is
+ /// stored into \p ReferencedCU. \returns null if resolving fails for any
+ /// reason.
+ DWARFDie resolveDIEReference(const DwarfFile &File, const UnitListTy &Units,
+ const DWARFFormValue &RefValue,
+ const DWARFDie &DIE, CompileUnit *&RefCU);
+
+ /// @}
+
+ /// \defgroup Methods used to link the debug information
+ ///
+ /// @{
+
+ struct DWARFLinkerOptions;
+
+ class DIECloner {
+ DWARFLinker &Linker;
+ DwarfEmitter *Emitter;
+ DwarfFile &ObjFile;
+
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator &DIEAlloc;
+
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits;
+
+ bool Update;
+
+ public:
+ DIECloner(DWARFLinker &Linker, DwarfEmitter *Emitter, DwarfFile &ObjFile,
+ BumpPtrAllocator &DIEAlloc,
+ std::vector<std::unique_ptr<CompileUnit>> &CompileUnits,
+ bool Update)
+ : Linker(Linker), Emitter(Emitter), ObjFile(ObjFile),
+ DIEAlloc(DIEAlloc), CompileUnits(CompileUnits), Update(Update) {}
+
+ /// Recursively clone \p InputDIE into an tree of DIE objects
+ /// where useless (as decided by lookForDIEsToKeep()) bits have been
+ /// stripped out and addresses have been rewritten according to the
+ /// address map.
+ ///
+ /// \param OutOffset is the offset the cloned DIE in the output
+ /// compile unit.
+ /// \param PCOffset (while cloning a function scope) is the offset
+ /// applied to the entry point of the function to get the linked address.
+ /// \param Die the output DIE to use, pass NULL to create one.
+ /// \returns the root of the cloned tree or null if nothing was selected.
+ DIE *cloneDIE(const DWARFDie &InputDIE, const DwarfFile &File,
+ CompileUnit &U, OffsetsStringPool &StringPool,
+ int64_t PCOffset, uint32_t OutOffset, unsigned Flags,
+ bool IsLittleEndian, DIE *Die = nullptr);
+
+ /// Construct the output DIE tree by cloning the DIEs we
+ /// chose to keep above. If there are no valid relocs, then there's
+ /// nothing to clone/emit.
+ uint64_t cloneAllCompileUnits(DWARFContext &DwarfContext,
+ const DwarfFile &File,
+ OffsetsStringPool &StringPool,
+ bool IsLittleEndian);
+
+ private:
+ using AttributeSpec = DWARFAbbreviationDeclaration::AttributeSpec;
+
+ /// Information gathered and exchanged between the various
+ /// clone*Attributes helpers about the attributes of a particular DIE.
+ struct AttributesInfo {
+ /// Names.
+ DwarfStringPoolEntryRef Name, MangledName, NameWithoutTemplate;
+
+ /// Offsets in the string pool.
+ uint32_t NameOffset = 0;
+ uint32_t MangledNameOffset = 0;
+
+ /// Value of AT_low_pc in the input DIE
+ uint64_t OrigLowPc = std::numeric_limits<uint64_t>::max();
+
+ /// Value of AT_high_pc in the input DIE
+ uint64_t OrigHighPc = 0;
+
+ /// Value of DW_AT_call_return_pc in the input DIE
+ uint64_t OrigCallReturnPc = 0;
+
+ /// Value of DW_AT_call_pc in the input DIE
+ uint64_t OrigCallPc = 0;
+
+ /// Offset to apply to PC addresses inside a function.
+ int64_t PCOffset = 0;
+
+ /// Does the DIE have a low_pc attribute?
+ bool HasLowPc = false;
+
+ /// Does the DIE have a ranges attribute?
+ bool HasRanges = false;
+
+ /// Is this DIE only a declaration?
+ bool IsDeclaration = false;
+
+ AttributesInfo() = default;
+ };
+
+ /// Helper for cloneDIE.
+ unsigned cloneAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DwarfFile &File, CompileUnit &U,
+ OffsetsStringPool &StringPool,
+ const DWARFFormValue &Val,
+ const AttributeSpec AttrSpec, unsigned AttrSize,
+ AttributesInfo &AttrInfo, bool IsLittleEndian);
+
+ /// Clone a string attribute described by \p AttrSpec and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneStringAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, const DWARFUnit &U,
+ OffsetsStringPool &StringPool,
+ AttributesInfo &Info);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneDieReferenceAttribute(DIE &Die, const DWARFDie &InputDIE,
+ AttributeSpec AttrSpec,
+ unsigned AttrSize,
+ const DWARFFormValue &Val,
+ const DwarfFile &File,
+ CompileUnit &Unit);
+
+ /// Clone a DWARF expression that may be referencing another DIE.
+ void cloneExpression(DataExtractor &Data, DWARFExpression Expression,
+ const DwarfFile &File, CompileUnit &Unit,
+ SmallVectorImpl<uint8_t> &OutputBuffer);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneBlockAttribute(DIE &Die, const DwarfFile &File,
+ CompileUnit &Unit, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, unsigned AttrSize,
+ bool IsLittleEndian);
+
+ /// Clone an attribute referencing another DIE and add
+ /// it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneAddressAttribute(DIE &Die, AttributeSpec AttrSpec,
+ const DWARFFormValue &Val,
+ const CompileUnit &Unit,
+ AttributesInfo &Info);
+
+ /// Clone a scalar attribute and add it to \p Die.
+ /// \returns the size of the new attribute.
+ unsigned cloneScalarAttribute(DIE &Die, const DWARFDie &InputDIE,
+ const DwarfFile &File, CompileUnit &U,
+ AttributeSpec AttrSpec,
+ const DWARFFormValue &Val, unsigned AttrSize,
+ AttributesInfo &Info);
+
+ /// Get the potential name and mangled name for the entity
+ /// described by \p Die and store them in \Info if they are not
+ /// already there.
+ /// \returns is a name was found.
+ bool getDIENames(const DWARFDie &Die, AttributesInfo &Info,
+ OffsetsStringPool &StringPool, bool StripTemplate = false);
+
+ /// Create a copy of abbreviation Abbrev.
+ void copyAbbrev(const DWARFAbbreviationDeclaration &Abbrev, bool hasODR);
+
+ uint32_t hashFullyQualifiedName(DWARFDie DIE, CompileUnit &U,
+ const DwarfFile &File,
+ int RecurseDepth = 0);
+
+ /// Helper for cloneDIE.
+ void addObjCAccelerator(CompileUnit &Unit, const DIE *Die,
+ DwarfStringPoolEntryRef Name,
+ OffsetsStringPool &StringPool, bool SkipPubSection);
+ };
+
+ /// Assign an abbreviation number to \p Abbrev
+ void assignAbbrev(DIEAbbrev &Abbrev);
+
+ /// Compute and emit debug_ranges section for \p Unit, and
+ /// patch the attributes referencing it.
+ void patchRangesForUnit(const CompileUnit &Unit, DWARFContext &Dwarf,
+ const DwarfFile &File) const;
+
+ /// Generate and emit the DW_AT_ranges attribute for a compile_unit if it had
+ /// one.
+ void generateUnitRanges(CompileUnit &Unit) const;
+
+ /// Extract the line tables from the original dwarf, extract the relevant
+ /// parts according to the linked function ranges and emit the result in the
+ /// debug_line section.
+ void patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf,
+ const DwarfFile &File);
+
+ /// Emit the accelerator entries for \p Unit.
+ void emitAcceleratorEntriesForUnit(CompileUnit &Unit);
+ void emitDwarfAcceleratorEntriesForUnit(CompileUnit &Unit);
+ void emitAppleAcceleratorEntriesForUnit(CompileUnit &Unit);
+
+ /// Patch the frame info for an object file and emit it.
+ void patchFrameInfoForObject(const DwarfFile &, RangesTy &Ranges,
+ DWARFContext &, unsigned AddressSize);
+
+ /// FoldingSet that uniques the abbreviations.
+ FoldingSet<DIEAbbrev> AbbreviationsSet;
+
+ /// Storage for the unique Abbreviations.
+ /// This is passed to AsmPrinter::emitDwarfAbbrevs(), thus it cannot be
+ /// changed to a vector of unique_ptrs.
+ std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
+
+ /// DIELoc objects that need to be destructed (but not freed!).
+ std::vector<DIELoc *> DIELocs;
+
+ /// DIEBlock objects that need to be destructed (but not freed!).
+ std::vector<DIEBlock *> DIEBlocks;
+
+ /// Allocator used for all the DIEValue objects.
+ BumpPtrAllocator DIEAlloc;
+ /// @}
+
+ DwarfEmitter *TheDwarfEmitter;
+ std::vector<LinkContext> ObjectContexts;
+
+ unsigned MaxDwarfVersion = 0;
+ unsigned MinDwarfVersion = std::numeric_limits<unsigned>::max();
+
+ bool AtLeastOneAppleAccelTable = false;
+ bool AtLeastOneDwarfAccelTable = false;
+
+ /// The CIEs that have been emitted in the output section. The actual CIE
+ /// data serves a the key to this StringMap, this takes care of comparing the
+ /// semantics of CIEs defined in different object files.
+ StringMap<uint32_t> EmittedCIEs;
+
+ /// Offset of the last CIE that has been emitted in the output
+ /// debug_frame section.
+ uint32_t LastCIEOffset = 0;
+
+ /// Apple accelerator tables.
+ AccelTable<DWARF5AccelTableStaticData> DebugNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNames;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleNamespaces;
+ AccelTable<AppleAccelTableStaticOffsetData> AppleObjc;
+ AccelTable<AppleAccelTableStaticTypeData> AppleTypes;
+
+ /// Mapping the PCM filename to the DwoId.
+ StringMap<uint64_t> ClangModules;
+
+ DwarfLinkerClient DwarfLinkerClientID;
+
+ std::function<StringRef(StringRef)> StringsTranslator = nullptr;
+
+ /// linking options
+ struct DWARFLinkerOptions {
+ /// Generate processing log to the standard output.
+ bool Verbose = false;
+
+ /// Print statistics.
+ bool Statistics = false;
+
+ /// Skip emitting output
+ bool NoOutput = false;
+
+ /// Do not unique types according to ODR
+ bool NoODR = false;
+
+ /// Update
+ bool Update = false;
+
+ /// Number of threads.
+ unsigned Threads = 1;
+
+ /// The accelerator table kind
+ AccelTableKind TheAccelTableKind = AccelTableKind::Default;
+
+ /// Prepend path for the clang modules.
+ std::string PrependPath;
+
+ // warning handler
+ messageHandler WarningHandler = nullptr;
+
+ // error handler
+ messageHandler ErrorHandler = nullptr;
+
+ objFileLoader ObjFileLoader = nullptr;
+
+ /// A list of all .swiftinterface files referenced by the debug
+ /// info, mapping Module name to path on disk. The entries need to
+ /// be uniqued and sorted and there are only few entries expected
+ /// per compile unit, which is why this is a std::map.
+ /// this is dsymutil specific fag.
+ swiftInterfacesMap *ParseableSwiftInterfaces = nullptr;
+
+ /// A list of remappings to apply to file paths.
+ objectPrefixMap *ObjectPrefixMap = nullptr;
+ } Options;
+};
+
} // end namespace llvm
#endif // LLVM_DWARFLINKER_DWARFLINKER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
index 7873a16fea52..944e7e3501c9 100644
--- a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerCompileUnit.h
@@ -115,6 +115,8 @@ public:
bool hasODR() const { return HasODR; }
bool isClangModule() const { return !ClangModuleName.empty(); }
uint16_t getLanguage();
+ /// Return the DW_AT_LLVM_sysroot of the compile unit or an empty StringRef.
+ StringRef getSysRoot();
const std::string &getClangModuleName() const { return ClangModuleName; }
@@ -321,6 +323,9 @@ private:
/// The DW_AT_language of this unit.
uint16_t Language = 0;
+ /// The DW_AT_LLVM_sysroot of this unit.
+ std::string SysRoot;
+
/// If this is a Clang module, this holds the module's name.
std::string ClangModuleName;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
index db40254bf600..e59e15f00a7e 100644
--- a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFLinkerDeclContext.h
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/NonRelocatableStringpool.h"
#include "llvm/DWARFLinker/DWARFLinkerCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFStreamer.h b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFStreamer.h
new file mode 100644
index 000000000000..de58f5dedf24
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DWARFLinker/DWARFStreamer.h
@@ -0,0 +1,219 @@
+//===- DwarfStreamer.h ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DWARFLINKER_DWARFSTREAMER_H
+#define LLVM_DWARFLINKER_DWARFSTREAMER_H
+
+#include "llvm/CodeGen/AccelTable.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/DWARFLinker/DWARFLinker.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+
+enum class OutputFileType {
+ Object,
+ Assembly,
+};
+
+/// User of DwarfStreamer should call initialization code
+/// for AsmPrinter:
+///
+/// InitializeAllTargetInfos();
+/// InitializeAllTargetMCs();
+/// InitializeAllTargets();
+/// InitializeAllAsmPrinters();
+
+class MCCodeEmitter;
+
+/// The Dwarf streaming logic.
+///
+/// All interactions with the MC layer that is used to build the debug
+/// information binary representation are handled in this class.
+class DwarfStreamer : public DwarfEmitter {
+public:
+ DwarfStreamer(OutputFileType OutFileType, raw_pwrite_stream &OutFile,
+ std::function<StringRef(StringRef Input)> Translator,
+ bool Minimize, messageHandler Error, messageHandler Warning)
+ : OutFile(OutFile), OutFileType(OutFileType), Translator(Translator),
+ Minimize(Minimize), ErrorHandler(Error), WarningHandler(Warning) {}
+
+ bool init(Triple TheTriple);
+
+ /// Dump the file to the disk.
+ void finish();
+
+ AsmPrinter &getAsmPrinter() const { return *Asm; }
+
+ /// Set the current output section to debug_info and change
+ /// the MC Dwarf version to \p DwarfVersion.
+ void switchToDebugInfoSection(unsigned DwarfVersion);
+
+ /// Emit the compilation unit header for \p Unit in the
+ /// debug_info section.
+ ///
+ /// As a side effect, this also switches the current Dwarf version
+ /// of the MC layer to the one of U.getOrigUnit().
+ void emitCompileUnitHeader(CompileUnit &Unit) override;
+
+ /// Recursively emit the DIE tree rooted at \p Die.
+ void emitDIE(DIE &Die) override;
+
+ /// Emit the abbreviation table \p Abbrevs to the debug_abbrev section.
+ void emitAbbrevs(const std::vector<std::unique_ptr<DIEAbbrev>> &Abbrevs,
+ unsigned DwarfVersion) override;
+
+ /// Emit DIE containing warnings.
+ void emitPaperTrailWarningsDie(DIE &Die) override;
+
+ /// Emit contents of section SecName From Obj.
+ void emitSectionContents(StringRef SecData, StringRef SecName) override;
+
+ /// Emit the string table described by \p Pool.
+ void emitStrings(const NonRelocatableStringpool &Pool) override;
+
+ /// Emit the swift_ast section stored in \p Buffer.
+ void emitSwiftAST(StringRef Buffer);
+
+ /// Emit debug_ranges for \p FuncRange by translating the
+ /// original \p Entries.
+ void emitRangesEntries(
+ int64_t UnitPcOffset, uint64_t OrigLowPc,
+ const FunctionIntervals::const_iterator &FuncRange,
+ const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,
+ unsigned AddressSize) override;
+
+ /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,
+ /// also emit the debug_ranges entries for the DW_TAG_compile_unit's
+ /// DW_AT_ranges attribute.
+ void emitUnitRangesEntries(CompileUnit &Unit, bool DoRangesSection) override;
+
+ uint64_t getRangesSectionSize() const override { return RangesSectionSize; }
+
+ /// Emit the debug_loc contribution for \p Unit by copying the entries from
+ /// \p Dwarf and offsetting them. Update the location attributes to point to
+ /// the new entries.
+ void emitLocationsForUnit(
+ const CompileUnit &Unit, DWARFContext &Dwarf,
+ std::function<void(StringRef, SmallVectorImpl<uint8_t> &)> ProcessExpr)
+ override;
+
+ /// Emit the line table described in \p Rows into the debug_line section.
+ void emitLineTableForUnit(MCDwarfLineTableParams Params,
+ StringRef PrologueBytes, unsigned MinInstLength,
+ std::vector<DWARFDebugLine::Row> &Rows,
+ unsigned AdddressSize) override;
+
+ /// Copy the debug_line over to the updated binary while unobfuscating the
+ /// file names and directories.
+ void translateLineTable(DataExtractor LineData, uint64_t Offset) override;
+
+ uint64_t getLineSectionSize() const override { return LineSectionSize; }
+
+ /// Emit the .debug_pubnames contribution for \p Unit.
+ void emitPubNamesForUnit(const CompileUnit &Unit) override;
+
+ /// Emit the .debug_pubtypes contribution for \p Unit.
+ void emitPubTypesForUnit(const CompileUnit &Unit) override;
+
+ /// Emit a CIE.
+ void emitCIE(StringRef CIEBytes) override;
+
+ /// Emit an FDE with data \p Bytes.
+ void emitFDE(uint32_t CIEOffset, uint32_t AddreSize, uint32_t Address,
+ StringRef Bytes) override;
+
+ /// Emit DWARF debug names.
+ void emitDebugNames(AccelTable<DWARF5AccelTableStaticData> &Table) override;
+
+ /// Emit Apple namespaces accelerator table.
+ void emitAppleNamespaces(
+ AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple names accelerator table.
+ void
+ emitAppleNames(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple Objective-C accelerator table.
+ void
+ emitAppleObjc(AccelTable<AppleAccelTableStaticOffsetData> &Table) override;
+
+ /// Emit Apple type accelerator table.
+ void
+ emitAppleTypes(AccelTable<AppleAccelTableStaticTypeData> &Table) override;
+
+ uint64_t getFrameSectionSize() const override { return FrameSectionSize; }
+
+ uint64_t getDebugInfoSectionSize() const override {
+ return DebugInfoSectionSize;
+ }
+
+private:
+ inline void error(const Twine &Error, StringRef Context = "") {
+ if (ErrorHandler)
+ ErrorHandler(Error, Context, nullptr);
+ }
+
+ inline void warn(const Twine &Warning, StringRef Context = "") {
+ if (WarningHandler)
+ WarningHandler(Warning, Context, nullptr);
+ }
+
+ /// \defgroup MCObjects MC layer objects constructed by the streamer
+ /// @{
+ std::unique_ptr<MCRegisterInfo> MRI;
+ std::unique_ptr<MCAsmInfo> MAI;
+ std::unique_ptr<MCObjectFileInfo> MOFI;
+ std::unique_ptr<MCContext> MC;
+ MCAsmBackend *MAB; // Owned by MCStreamer
+ std::unique_ptr<MCInstrInfo> MII;
+ std::unique_ptr<MCSubtargetInfo> MSTI;
+ MCInstPrinter *MIP; // Owned by AsmPrinter
+ MCCodeEmitter *MCE; // Owned by MCStreamer
+ MCStreamer *MS; // Owned by AsmPrinter
+ std::unique_ptr<TargetMachine> TM;
+ std::unique_ptr<AsmPrinter> Asm;
+ /// @}
+
+ /// The output file we stream the linked Dwarf to.
+ raw_pwrite_stream &OutFile;
+ OutputFileType OutFileType = OutputFileType::Object;
+ std::function<StringRef(StringRef Input)> Translator;
+ bool Minimize = true;
+
+ uint64_t RangesSectionSize = 0;
+ uint64_t LocSectionSize = 0;
+ uint64_t LineSectionSize = 0;
+ uint64_t FrameSectionSize = 0;
+ uint64_t DebugInfoSectionSize = 0;
+
+ /// Keep track of emitted CUs and their Unique ID.
+ struct EmittedUnit {
+ unsigned ID;
+ MCSymbol *LabelBegin;
+ };
+ std::vector<EmittedUnit> EmittedUnits;
+
+ /// Emit the pubnames or pubtypes section contribution for \p
+ /// Unit into \p Sec. The data is provided in \p Names.
+ void emitPubSectionForUnit(MCSection *Sec, StringRef Name,
+ const CompileUnit &Unit,
+ const std::vector<CompileUnit::AccelInfo> &Names);
+
+ messageHandler ErrorHandler = nullptr;
+ messageHandler WarningHandler = nullptr;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_DWARFLINKER_DWARFSTREAMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
index 0ac8b651939d..3867d78d078a 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h
@@ -38,7 +38,7 @@ public:
explicit AppendingTypeTableBuilder(BumpPtrAllocator &Storage);
~AppendingTypeTableBuilder();
- // TypeTableCollection overrides
+ // TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@@ -46,6 +46,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
+ bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index 60829a51dc25..f26e80ebe2a9 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -29,9 +29,9 @@ namespace codeview {
class CodeViewRecordStreamer {
public:
- virtual void EmitBytes(StringRef Data) = 0;
- virtual void EmitIntValue(uint64_t Value, unsigned Size) = 0;
- virtual void EmitBinaryData(StringRef Data) = 0;
+ virtual void emitBytes(StringRef Data) = 0;
+ virtual void emitIntValue(uint64_t Value, unsigned Size) = 0;
+ virtual void emitBinaryData(StringRef Data) = 0;
virtual void AddComment(const Twine &T) = 0;
virtual void AddRawComment(const Twine &T) = 0;
virtual bool isVerboseAsm() = 0;
@@ -81,7 +81,7 @@ public:
if (isStreaming()) {
StringRef BytesSR =
StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
- Streamer->EmitBytes(BytesSR);
+ Streamer->emitBytes(BytesSR);
incrStreamedLen(sizeof(T));
return Error::success();
}
@@ -99,7 +99,7 @@ public:
template <typename T> Error mapInteger(T &Value, const Twine &Comment = "") {
if (isStreaming()) {
emitComment(Comment);
- Streamer->EmitIntValue((int)Value, sizeof(T));
+ Streamer->emitIntValue((int)Value, sizeof(T));
incrStreamedLen(sizeof(T));
return Error::success();
}
@@ -114,7 +114,7 @@ public:
if (!isStreaming() && sizeof(Value) > maxFieldLength())
return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
- using U = typename std::underlying_type<T>::type;
+ using U = std::underlying_type_t<T>;
U X;
if (isWriting() || isStreaming())
@@ -145,7 +145,7 @@ public:
if (isStreaming()) {
Size = static_cast<SizeType>(Items.size());
emitComment(Comment);
- Streamer->EmitIntValue(Size, sizeof(Size));
+ Streamer->emitIntValue(Size, sizeof(Size));
incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
for (auto &X : Items) {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
index 53ab2dd04aa7..0e2f5d90e243 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h
@@ -18,7 +18,6 @@
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Error.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
index bcb379f00d68..e915d8a5830c 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h
@@ -35,44 +35,38 @@ struct DebugSubsectionHeader {
class DebugSubsectionRecord {
public:
DebugSubsectionRecord();
- DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data,
- CodeViewContainer Container);
+ DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data);
- static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info,
- CodeViewContainer Container);
+ static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info);
uint32_t getRecordLength() const;
DebugSubsectionKind kind() const;
BinaryStreamRef getRecordData() const;
private:
- CodeViewContainer Container = CodeViewContainer::ObjectFile;
DebugSubsectionKind Kind = DebugSubsectionKind::None;
BinaryStreamRef Data;
};
class DebugSubsectionRecordBuilder {
public:
- DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
- CodeViewContainer Container);
+ DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection);
/// Use this to copy existing subsections directly from source to destination.
/// For example, line table subsections in an object file only need to be
/// relocated before being copied into the PDB.
- DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
- CodeViewContainer Container);
+ DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents);
- uint32_t calculateSerializedLength();
- Error commit(BinaryStreamWriter &Writer) const;
+ uint32_t calculateSerializedLength() const;
+ Error commit(BinaryStreamWriter &Writer, CodeViewContainer Container) const;
private:
/// The subsection to build. Will be null if Contents is non-empty.
std::shared_ptr<DebugSubsection> Subsection;
/// The bytes of the subsection. Only non-empty if Subsection is null.
+ /// FIXME: Reduce the size of this.
DebugSubsectionRecord Contents;
-
- CodeViewContainer Container;
};
} // end namespace codeview
@@ -83,8 +77,7 @@ template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
// FIXME: We need to pass the container type through to this function. In
// practice this isn't super important since the subsection header describes
// its length and we can just skip it. It's more important when writing.
- if (auto EC = codeview::DebugSubsectionRecord::initialize(
- Stream, Info, codeview::CodeViewContainer::Pdb))
+ if (auto EC = codeview::DebugSubsectionRecord::initialize(Stream, Info))
return EC;
Length = alignTo(Info.getRecordLength(), 4);
return Error::success();
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
index bb8cc032e28d..8c22eaf8b2d7 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h
@@ -50,7 +50,7 @@ public:
explicit GlobalTypeTableBuilder(BumpPtrAllocator &Storage);
~GlobalTypeTableBuilder();
- // TypeTableCollection overrides
+ // TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@@ -58,6 +58,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
+ bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
index 4e03627e9580..35eeef5a327e 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h
@@ -79,6 +79,7 @@ public:
uint32_t capacity() override;
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
+ bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
private:
Error ensureTypeExists(TypeIndex Index);
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
index 1b2f6d29a9b6..2f3d7a98e989 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h
@@ -47,7 +47,7 @@ public:
explicit MergingTypeTableBuilder(BumpPtrAllocator &Storage);
~MergingTypeTableBuilder();
- // TypeTableCollection overrides
+ // TypeCollection overrides
Optional<TypeIndex> getFirst() override;
Optional<TypeIndex> getNext(TypeIndex Prev) override;
CVType getType(TypeIndex Index) override;
@@ -55,6 +55,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
+ bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
// public interface
void reset();
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
index 3ca09b445a30..fcc0452a6ae9 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SimpleTypeSerializer.h
@@ -10,25 +10,11 @@
#define LLVM_DEBUGINFO_CODEVIEW_SIMPLETYPESERIALIZER_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-#include <memory>
#include <vector>
namespace llvm {
namespace codeview {
+class FieldListRecord;
class SimpleTypeSerializer {
std::vector<uint8_t> ScratchBuffer;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 1fcef9dd06c8..4383534b0db2 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -350,6 +350,13 @@ public:
uint32_t RecordOffset = 0;
};
+struct PublicSym32Header {
+ ulittle32_t Flags;
+ ulittle32_t Offset;
+ ulittle16_t Segment;
+ // char Name[];
+};
+
// S_PUB32
class PublicSym32 : public SymbolRecord {
public:
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
index 58b1dd058c1a..102d68c3fb2a 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeCollection.h
@@ -30,6 +30,7 @@ public:
virtual bool contains(TypeIndex Index) = 0;
virtual uint32_t size() = 0;
virtual uint32_t capacity() = 0;
+ virtual bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) = 0;
template <typename TFunc> void ForEachRecord(TFunc Func) {
Optional<TypeIndex> Next = getFirst();
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
index 4f2e5deb10b4..01525d06d1cd 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeSymbolEmitter.h
@@ -9,13 +9,11 @@
#ifndef LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H
#define LLVM_DEBUGINFO_CODEVIEW_TYPESYMBOLEMITTER_H
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-
namespace llvm {
class StringRef;
namespace codeview {
+class TypeIndex;
class TypeSymbolEmitter {
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
index 5cbe3400e029..c3008742d2e1 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/TypeTableCollection.h
@@ -29,6 +29,7 @@ public:
bool contains(TypeIndex Index) override;
uint32_t size() override;
uint32_t capacity() override;
+ bool replaceType(TypeIndex &Index, CVType Data, bool Stabilize) override;
private:
BumpPtrAllocator Allocator;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DIContext.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DIContext.h
index fbebfe634b63..661d30d04c94 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DIContext.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
@@ -133,20 +134,29 @@ enum class DINameKind { None, ShortName, LinkageName };
/// Controls which fields of DILineInfo container should be filled
/// with data.
struct DILineInfoSpecifier {
- enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
+ enum class FileLineInfoKind {
+ None,
+ // RawValue is whatever the compiler stored in the filename table. Could be
+ // a full path, could be something else.
+ RawValue,
+ BaseNameOnly,
+ // Relative to the compilation directory.
+ RelativeFilePath,
+ AbsoluteFilePath
+ };
using FunctionNameKind = DINameKind;
FileLineInfoKind FLIKind;
FunctionNameKind FNKind;
- DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
+ DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::RawValue,
FunctionNameKind FNKind = FunctionNameKind::None)
: FLIKind(FLIKind), FNKind(FNKind) {}
};
/// This is just a helper to programmatically construct DIDumpType.
enum DIDumpTypeCounter {
-#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
+#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
DIDT_ID_##ENUM_NAME,
#include "llvm/BinaryFormat/Dwarf.def"
#undef HANDLE_DWARF_SECTION
@@ -159,7 +169,7 @@ static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
enum DIDumpType : unsigned {
DIDT_Null,
DIDT_All = ~0U,
-#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
+#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
#include "llvm/BinaryFormat/Dwarf.def"
#undef HANDLE_DWARF_SECTION
@@ -199,6 +209,10 @@ struct DIDumpOptions {
Opts.ParentRecurseDepth = 0;
return Opts;
}
+
+ std::function<void(Error)> RecoverableErrorHandler =
+ WithColor::defaultErrorHandler;
+ std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
};
class DIContext {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index c9042e593260..961a8d82fe9e 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -222,11 +222,16 @@ public:
/// referenced by the name table and interpreted with the help of the
/// abbreviation table.
class DWARFDebugNames : public DWARFAcceleratorTable {
- /// The fixed-size part of a DWARF v5 Name Index header
- struct HeaderPOD {
- uint32_t UnitLength;
+public:
+ class NameIndex;
+ class NameIterator;
+ class ValueIterator;
+
+ /// DWARF v5 Name Index header.
+ struct Header {
+ uint64_t UnitLength;
+ dwarf::DwarfFormat Format;
uint16_t Version;
- uint16_t Padding;
uint32_t CompUnitCount;
uint32_t LocalTypeUnitCount;
uint32_t ForeignTypeUnitCount;
@@ -234,15 +239,6 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
uint32_t NameCount;
uint32_t AbbrevTableSize;
uint32_t AugmentationStringSize;
- };
-
-public:
- class NameIndex;
- class NameIterator;
- class ValueIterator;
-
- /// DWARF v5 Name Index header.
- struct Header : public HeaderPOD {
SmallString<8> AugmentationString;
Error extract(const DWARFDataExtractor &AS, uint64_t *Offset);
@@ -461,7 +457,10 @@ public:
Error extract();
uint64_t getUnitOffset() const { return Base; }
- uint64_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
+ uint64_t getNextUnitOffset() const {
+ return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
+ Hdr.UnitLength;
+ }
void dump(ScopedPrinter &W) const;
friend class DWARFDebugNames;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
index 7a728c2508cc..154f7893aa17 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
@@ -45,6 +45,24 @@ struct DWARFAddressRange {
return LowPC < RHS.HighPC && RHS.LowPC < HighPC;
}
+ /// Union two address ranges if they intersect.
+ ///
+ /// This function will union two address ranges if they intersect by
+ /// modifying this range to be the union of both ranges. If the two ranges
+ /// don't intersect this range will be left alone.
+ ///
+ /// \param RHS Another address range to combine with.
+ ///
+ /// \returns false if the ranges don't intersect, true if they do and the
+ /// ranges were combined.
+ bool merge(const DWARFAddressRange &RHS) {
+ if (!intersects(RHS))
+ return false;
+ LowPC = std::min<uint64_t>(LowPC, RHS.LowPC);
+ HighPC = std::max<uint64_t>(HighPC, RHS.HighPC);
+ return true;
+ }
+
void dump(raw_ostream &OS, uint32_t AddressSize, DIDumpOptions DumpOpts = {},
const DWARFObject *Obj = nullptr) const;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index a2a10d23433f..97903a96b3fc 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -47,11 +47,6 @@ class MCRegisterInfo;
class MemoryBuffer;
class raw_ostream;
-/// Used as a return value for a error callback passed to DWARF context.
-/// Callback should return Halt if client application wants to stop
-/// object parsing, or should return Continue otherwise.
-enum class ErrorPolicy { Halt, Continue };
-
/// DWARFContext
/// This data structure is the top level entity that deals with dwarf debug
/// information parsing. The actual data is supplied through DWARFObj.
@@ -67,6 +62,7 @@ class DWARFContext : public DIContext {
std::unique_ptr<DWARFDebugFrame> DebugFrame;
std::unique_ptr<DWARFDebugFrame> EHFrame;
std::unique_ptr<DWARFDebugMacro> Macro;
+ std::unique_ptr<DWARFDebugMacro> Macinfo;
std::unique_ptr<DWARFDebugNames> Names;
std::unique_ptr<AppleAcceleratorTable> AppleNames;
std::unique_ptr<AppleAcceleratorTable> AppleTypes;
@@ -75,6 +71,7 @@ class DWARFContext : public DIContext {
DWARFUnitVector DWOUnits;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
+ std::unique_ptr<DWARFDebugMacro> MacinfoDWO;
std::unique_ptr<DWARFDebugMacro> MacroDWO;
/// The maximum DWARF version of all units.
@@ -91,6 +88,10 @@ class DWARFContext : public DIContext {
std::unique_ptr<MCRegisterInfo> RegInfo;
+ std::function<void(Error)> RecoverableErrorHandler =
+ WithColor::defaultErrorHandler;
+ std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
+
/// Read compile units from the debug_info section (if necessary)
/// and type units from the debug_types sections (if necessary)
/// and store them in NormalUnits.
@@ -105,9 +106,22 @@ class DWARFContext : public DIContext {
std::unique_ptr<const DWARFObject> DObj;
+ /// Helper enum to distinguish between macro[.dwo] and macinfo[.dwo]
+ /// section.
+ enum MacroSecType {
+ MacinfoSection,
+ MacinfoDwoSection,
+ MacroSection,
+ MacroDwoSection
+ };
+
public:
DWARFContext(std::unique_ptr<const DWARFObject> DObj,
- std::string DWPName = "");
+ std::string DWPName = "",
+ std::function<void(Error)> RecoverableErrorHandler =
+ WithColor::defaultErrorHandler,
+ std::function<void(Error)> WarningHandler =
+ WithColor::defaultWarningHandler);
~DWARFContext();
DWARFContext(DWARFContext &) = delete;
@@ -264,15 +278,21 @@ public:
const DWARFDebugAranges *getDebugAranges();
/// Get a pointer to the parsed frame information object.
- const DWARFDebugFrame *getDebugFrame();
+ Expected<const DWARFDebugFrame *> getDebugFrame();
/// Get a pointer to the parsed eh frame information object.
- const DWARFDebugFrame *getEHFrame();
+ Expected<const DWARFDebugFrame *> getEHFrame();
+
+ /// Get a pointer to the parsed DebugMacinfo information object.
+ const DWARFDebugMacro *getDebugMacinfo();
- /// Get a pointer to the parsed DebugMacro object.
+ /// Get a pointer to the parsed DebugMacinfoDWO information object.
+ const DWARFDebugMacro *getDebugMacinfoDWO();
+
+ /// Get a pointer to the parsed DebugMacro information object.
const DWARFDebugMacro *getDebugMacro();
- /// Get a pointer to the parsed DebugMacroDWO object.
+ /// Get a pointer to the parsed DebugMacroDWO information object.
const DWARFDebugMacro *getDebugMacroDWO();
/// Get a reference to the parsed accelerator table object.
@@ -295,14 +315,17 @@ public:
const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
/// Get a pointer to a parsed line table corresponding to a compile unit.
- /// Report any recoverable parsing problems using the callback.
+ /// Report any recoverable parsing problems using the handler.
Expected<const DWARFDebugLine::LineTable *>
getLineTableForUnit(DWARFUnit *U,
- function_ref<void(Error)> RecoverableErrorCallback);
+ function_ref<void(Error)> RecoverableErrorHandler);
DataExtractor getStringExtractor() const {
return DataExtractor(DObj->getStrSection(), false, 0);
}
+ DataExtractor getStringDWOExtractor() const {
+ return DataExtractor(DObj->getStrDWOSection(), false, 0);
+ }
DataExtractor getLineStringExtractor() const {
return DataExtractor(DObj->getLineStrSection(), false, 0);
}
@@ -339,21 +362,35 @@ public:
return version == 2 || version == 3 || version == 4 || version == 5;
}
+ static bool isAddressSizeSupported(unsigned AddressSize) {
+ return AddressSize == 2 || AddressSize == 4 || AddressSize == 8;
+ }
+
std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
- /// Function used to handle default error reporting policy. Prints a error
- /// message and returns Continue, so DWARF context ignores the error.
- static ErrorPolicy defaultErrorHandler(Error E);
+ function_ref<void(Error)> getRecoverableErrorHandler() {
+ return RecoverableErrorHandler;
+ }
+
+ function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
+
static std::unique_ptr<DWARFContext>
create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
- function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
- std::string DWPName = "");
+ std::string DWPName = "",
+ std::function<void(Error)> RecoverableErrorHandler =
+ WithColor::defaultErrorHandler,
+ std::function<void(Error)> WarningHandler =
+ WithColor::defaultWarningHandler);
static std::unique_ptr<DWARFContext>
create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
- uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
+ uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost,
+ std::function<void(Error)> RecoverableErrorHandler =
+ WithColor::defaultErrorHandler,
+ std::function<void(Error)> WarningHandler =
+ WithColor::defaultWarningHandler);
/// Loads register info for the architecture of the provided object file.
/// Improves readability of dumped DWARF expressions. Requires the caller to
@@ -364,19 +401,21 @@ public:
/// TODO: refactor compile_units() to make this const.
uint8_t getCUAddrSize();
- /// Dump Error as warning message to stderr.
- static void dumpWarning(Error Warning);
-
Triple::ArchType getArch() const {
return getDWARFObj().getFile()->getArch();
}
-private:
/// Return the compile unit which contains instruction with provided
/// address.
/// TODO: change input parameter from "uint64_t Address"
/// into "SectionedAddress Address"
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
+
+private:
+ /// Parse a macro[.dwo] or macinfo[.dwo] section.
+ std::unique_ptr<DWARFDebugMacro>
+ parseMacroOrMacinfo(MacroSecType SectionType);
+
void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
std::vector<DILocal> &Result);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 6f7ddb2ef421..34329ec66baa 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H
#define LLVM_DEBUGINFO_DWARFDATAEXTRACTOR_H
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/Support/DataExtractor.h"
@@ -32,12 +33,39 @@ public:
/// Constructor for cases when there are no relocations.
DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
: DataExtractor(Data, IsLittleEndian, AddressSize) {}
+ DWARFDataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian,
+ uint8_t AddressSize)
+ : DataExtractor(
+ StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()),
+ IsLittleEndian, AddressSize) {}
+
+ /// Truncating constructor
+ DWARFDataExtractor(const DWARFDataExtractor &Other, size_t Length)
+ : DataExtractor(Other.getData().substr(0, Length), Other.isLittleEndian(),
+ Other.getAddressSize()),
+ Obj(Other.Obj), Section(Other.Section) {}
+
+ /// Extracts the DWARF "initial length" field, which can either be a 32-bit
+ /// value smaller than 0xfffffff0, or the value 0xffffffff followed by a
+ /// 64-bit length. Returns the actual length, and the DWARF format which is
+ /// encoded in the field. In case of errors, it returns {0, DWARF32} and
+ /// leaves the offset unchanged.
+ std::pair<uint64_t, dwarf::DwarfFormat>
+ getInitialLength(uint64_t *Off, Error *Err = nullptr) const;
+
+ std::pair<uint64_t, dwarf::DwarfFormat> getInitialLength(Cursor &C) const {
+ return getInitialLength(&getOffset(C), &getError(C));
+ }
/// Extracts a value and applies a relocation to the result if
/// one exists for the given offset.
uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off,
uint64_t *SectionIndex = nullptr,
Error *Err = nullptr) const;
+ uint64_t getRelocatedValue(Cursor &C, uint32_t Size,
+ uint64_t *SectionIndex = nullptr) const {
+ return getRelocatedValue(Size, &getOffset(C), SectionIndex, &getError(C));
+ }
/// Extracts an address-sized value and applies a relocation to the result if
/// one exists for the given offset.
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
index 4539b9c9d581..32844ffd570f 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
@@ -27,69 +27,53 @@ class raw_ostream;
/// The table consists of a header followed by an array of address values from
/// .debug_addr section.
class DWARFDebugAddrTable {
-public:
- struct Header {
- /// The total length of the entries for this table, not including the length
- /// field itself.
- uint32_t Length = 0;
- /// The DWARF version number.
- uint16_t Version = 5;
- /// The size in bytes of an address on the target architecture. For
- /// segmented addressing, this is the size of the offset portion of the
- /// address.
- uint8_t AddrSize;
- /// The size in bytes of a segment selector on the target architecture.
- /// If the target system uses a flat address space, this value is 0.
- uint8_t SegSize = 0;
- };
-
-private:
dwarf::DwarfFormat Format;
- uint64_t HeaderOffset;
- Header HeaderData;
- uint32_t DataSize = 0;
+ uint64_t Offset;
+ /// The total length of the entries for this table, not including the length
+ /// field itself.
+ uint64_t Length = 0;
+ /// The DWARF version number.
+ uint16_t Version;
+ /// The size in bytes of an address on the target architecture. For
+ /// segmented addressing, this is the size of the offset portion of the
+ /// address.
+ uint8_t AddrSize;
+ /// The size in bytes of a segment selector on the target architecture.
+ /// If the target system uses a flat address space, this value is 0.
+ uint8_t SegSize;
std::vector<uint64_t> Addrs;
+ /// Invalidate Length field to stop further processing.
+ void invalidateLength() { Length = 0; }
+
+ Error extractAddresses(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
+ uint64_t EndOffset);
+
public:
- void clear();
- /// Extract an entire table, including all addresses.
- Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr,
- uint16_t Version, uint8_t AddrSize,
+ /// Extract the entire table, including all addresses.
+ Error extract(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
+ uint16_t CUVersion, uint8_t CUAddrSize,
std::function<void(Error)> WarnCallback);
- uint64_t getHeaderOffset() const { return HeaderOffset; }
- uint8_t getAddrSize() const { return HeaderData.AddrSize; }
+ /// Extract a DWARFv5 address table.
+ Error extractV5(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
+ uint8_t CUAddrSize, std::function<void(Error)> WarnCallback);
+
+ /// Extract a pre-DWARFv5 address table. Such tables do not have a header
+ /// and consist only of a series of addresses.
+ /// See https://gcc.gnu.org/wiki/DebugFission for details.
+ Error extractPreStandard(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
+ uint16_t CUVersion, uint8_t CUAddrSize);
+
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
/// Return the address based on a given index.
Expected<uint64_t> getAddrEntry(uint32_t Index) const;
- /// Return the size of the table header including the length
- /// but not including the addresses.
- uint8_t getHeaderSize() const {
- switch (Format) {
- case dwarf::DwarfFormat::DWARF32:
- return 8; // 4 + 2 + 1 + 1
- case dwarf::DwarfFormat::DWARF64:
- return 16; // 12 + 2 + 1 + 1
- }
- llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64)");
- }
-
- /// Returns the length of this table, including the length field, or 0 if the
- /// length has not been determined (e.g. because the table has not yet been
- /// parsed, or there was a problem in parsing).
- uint32_t getLength() const;
-
- /// Verify that the given length is valid for this table.
- bool hasValidLength() const { return getLength() != 0; }
-
- /// Invalidate Length field to stop further processing.
- void invalidateLength() { HeaderData.Length = 0; }
-
- /// Returns the length of the array of addresses.
- uint32_t getDataSize() const;
+ /// Return the full length of this table, including the length field.
+ /// Return None if the length cannot be identified reliably.
+ Optional<uint64_t> getFullLength() const;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
index ebe4ad6e24dd..0681a2e33a50 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
@@ -10,7 +10,8 @@
#define LLVM_DEBUGINFO_DWARFDEBUGARANGESET_H
#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/Support/Error.h"
#include <cstdint>
#include <vector>
@@ -23,10 +24,12 @@ public:
struct Header {
/// The total length of the entries for that set, not including the length
/// field itself.
- uint32_t Length;
+ uint64_t Length;
+ /// The DWARF format of the set.
+ dwarf::DwarfFormat Format;
/// The offset from the beginning of the .debug_info section of the
/// compilation unit entry referenced by the table.
- uint32_t CuOffset;
+ uint64_t CuOffset;
/// The DWARF version number.
uint16_t Version;
/// The size in bytes of an address on the target architecture. For segmented
@@ -57,10 +60,10 @@ public:
DWARFDebugArangeSet() { clear(); }
void clear();
- bool extract(DataExtractor data, uint64_t *offset_ptr);
+ Error extract(DWARFDataExtractor data, uint64_t *offset_ptr);
void dump(raw_ostream &OS) const;
- uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
+ uint64_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
const Header &getHeader() const { return HeaderData; }
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
index 89b15d263580..31a8b462ef71 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
@@ -10,7 +10,7 @@
#define LLVM_DEBUGINFO_DWARFDEBUGARANGES_H
#include "llvm/ADT/DenseSet.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include <cstdint>
#include <vector>
@@ -25,15 +25,15 @@ public:
private:
void clear();
- void extract(DataExtractor DebugArangesData);
+ void extract(DWARFDataExtractor DebugArangesData,
+ function_ref<void(Error)> RecoverableErrorHandler);
/// Call appendRange multiple times and then call construct.
void appendRange(uint64_t CUOffset, uint64_t LowPC, uint64_t HighPC);
void construct();
struct Range {
- explicit Range(uint64_t LowPC = -1ULL, uint64_t HighPC = -1ULL,
- uint64_t CUOffset = -1ULL)
+ explicit Range(uint64_t LowPC, uint64_t HighPC, uint64_t CUOffset)
: LowPC(LowPC), Length(HighPC - LowPC), CUOffset(CUOffset) {}
void setHighPC(uint64_t HighPC) {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index c6539df0d756..233b55cc55c1 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -132,9 +132,9 @@ class FrameEntry {
public:
enum FrameKind { FK_CIE, FK_FDE };
- FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length, uint64_t CodeAlign,
- int64_t DataAlign, Triple::ArchType Arch)
- : Kind(K), Offset(Offset), Length(Length),
+ FrameEntry(FrameKind K, bool IsDWARF64, uint64_t Offset, uint64_t Length,
+ uint64_t CodeAlign, int64_t DataAlign, Triple::ArchType Arch)
+ : Kind(K), IsDWARF64(IsDWARF64), Offset(Offset), Length(Length),
CFIs(CodeAlign, DataAlign, Arch) {}
virtual ~FrameEntry() {}
@@ -152,6 +152,8 @@ public:
protected:
const FrameKind Kind;
+ const bool IsDWARF64;
+
/// Offset of this entry in the section.
const uint64_t Offset;
@@ -166,14 +168,14 @@ class CIE : public FrameEntry {
public:
// CIEs (and FDEs) are simply container classes, so the only sensible way to
// create them is by providing the full parsed contents in the constructor.
- CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
+ CIE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint8_t Version,
SmallString<8> Augmentation, uint8_t AddressSize,
uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
uint32_t LSDAPointerEncoding, Optional<uint64_t> Personality,
Optional<uint32_t> PersonalityEnc, Triple::ArchType Arch)
- : FrameEntry(FK_CIE, Offset, Length, CodeAlignmentFactor,
+ : FrameEntry(FK_CIE, IsDWARF64, Offset, Length, CodeAlignmentFactor,
DataAlignmentFactor, Arch),
Version(Version), Augmentation(std::move(Augmentation)),
AddressSize(AddressSize), SegmentDescriptorSize(SegmentDescriptorSize),
@@ -223,17 +225,14 @@ private:
/// DWARF Frame Description Entry (FDE)
class FDE : public FrameEntry {
public:
- // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
- // an offset to the CIE (provided by parsing the FDE header). The CIE itself
- // is obtained lazily once it's actually required.
- FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
+ FDE(bool IsDWARF64, uint64_t Offset, uint64_t Length, uint64_t CIEPointer,
uint64_t InitialLocation, uint64_t AddressRange, CIE *Cie,
Optional<uint64_t> LSDAAddress, Triple::ArchType Arch)
- : FrameEntry(FK_FDE, Offset, Length,
+ : FrameEntry(FK_FDE, IsDWARF64, Offset, Length,
Cie ? Cie->getCodeAlignmentFactor() : 0,
Cie ? Cie->getDataAlignmentFactor() : 0,
Arch),
- LinkedCIEOffset(LinkedCIEOffset), InitialLocation(InitialLocation),
+ CIEPointer(CIEPointer), InitialLocation(InitialLocation),
AddressRange(AddressRange), LinkedCIE(Cie), LSDAAddress(LSDAAddress) {}
~FDE() override = default;
@@ -249,8 +248,11 @@ public:
static bool classof(const FrameEntry *FE) { return FE->getKind() == FK_FDE; }
private:
- /// The following fields are defined in section 6.4.1 of the DWARF standard v3
- const uint64_t LinkedCIEOffset;
+ /// The following fields are defined in section 6.4.1 of the DWARFv3 standard.
+ /// Note that CIE pointers in EH FDEs, unlike DWARF FDEs, contain relative
+ /// offsets to the linked CIEs. See the following link for more info:
+ /// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
+ const uint64_t CIEPointer;
const uint64_t InitialLocation;
const uint64_t AddressRange;
const CIE *LinkedCIE;
@@ -288,7 +290,7 @@ public:
/// Parse the section from raw data. \p Data is assumed to contain the whole
/// frame section contents to be parsed.
- void parse(DWARFDataExtractor Data);
+ Error parse(DWARFDataExtractor Data);
/// Return whether the section has any entries.
bool empty() const { return Entries.empty(); }
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index d5b6c72c0461..fe46d613aedd 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -108,15 +108,7 @@ public:
bool totalLengthIsValid() const;
/// Length of the prologue in bytes.
- uint32_t getLength() const {
- return PrologueLength + sizeofTotalLength() + sizeof(getVersion()) +
- sizeofPrologueLength();
- }
-
- /// Length of the line table data in bytes (not including the prologue).
- uint32_t getStatementTableLength() const {
- return TotalLength + sizeofTotalLength() - getLength();
- }
+ uint64_t getLength() const;
int32_t getMaxLineIncrementForSpecialOpcode() const {
return LineBase + (int8_t)LineRange - 1;
@@ -137,7 +129,8 @@ public:
void clear();
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
- Error parse(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+ Error parse(DWARFDataExtractor Data, uint64_t *OffsetPtr,
+ function_ref<void(Error)> RecoverableErrorHandler,
const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
};
@@ -150,7 +143,7 @@ public:
void reset(bool DefaultIsStmt);
void dump(raw_ostream &OS) const;
- static void dumpTableHeader(raw_ostream &OS);
+ static void dumpTableHeader(raw_ostream &OS, unsigned Indent);
static bool orderByAddress(const Row &LHS, const Row &RHS) {
return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) <
@@ -282,8 +275,8 @@ public:
/// Parse prologue and all rows.
Error parse(DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
const DWARFContext &Ctx, const DWARFUnit *U,
- function_ref<void(Error)> RecoverableErrorCallback,
- raw_ostream *OS = nullptr);
+ function_ref<void(Error)> RecoverableErrorHandler,
+ raw_ostream *OS = nullptr, bool Verbose = false);
using RowVector = std::vector<Row>;
using RowIter = RowVector::const_iterator;
@@ -311,7 +304,7 @@ public:
Expected<const LineTable *>
getOrParseLineTable(DWARFDataExtractor &DebugLineData, uint64_t Offset,
const DWARFContext &Ctx, const DWARFUnit *U,
- function_ref<void(Error)> RecoverableErrorCallback);
+ function_ref<void(Error)> RecoverableErrorHandler);
/// Helper to allow for parsing of an entire .debug_line section in sequence.
class SectionParser {
@@ -324,26 +317,29 @@ public:
tu_range TUs);
/// Get the next line table from the section. Report any issues via the
- /// callbacks.
+ /// handlers.
///
- /// \param RecoverableErrorCallback - any issues that don't prevent further
- /// parsing of the table will be reported through this callback.
- /// \param UnrecoverableErrorCallback - any issues that prevent further
- /// parsing of the table will be reported through this callback.
+ /// \param RecoverableErrorHandler - any issues that don't prevent further
+ /// parsing of the table will be reported through this handler.
+ /// \param UnrecoverableErrorHandler - any issues that prevent further
+ /// parsing of the table will be reported through this handler.
/// \param OS - if not null, the parser will print information about the
/// table as it parses it.
- LineTable
- parseNext(
- function_ref<void(Error)> RecoverableErrorCallback,
- function_ref<void(Error)> UnrecoverableErrorCallback,
- raw_ostream *OS = nullptr);
+ /// \param Verbose - if true, the parser will print verbose information when
+ /// printing to the output.
+ LineTable parseNext(function_ref<void(Error)> RecoverableErrorHandler,
+ function_ref<void(Error)> UnrecoverableErrorHandler,
+ raw_ostream *OS = nullptr, bool Verbose = false);
/// Skip the current line table and go to the following line table (if
/// present) immediately.
///
- /// \param ErrorCallback - report any prologue parsing issues via this
- /// callback.
- void skip(function_ref<void(Error)> ErrorCallback);
+ /// \param RecoverableErrorHandler - report any recoverable prologue
+ /// parsing issues via this handler.
+ /// \param UnrecoverableErrorHandler - report any unrecoverable prologue
+ /// parsing issues via this handler.
+ void skip(function_ref<void(Error)> RecoverableErrorHandler,
+ function_ref<void(Error)> UnrecoverableErrorHandler);
/// Indicates if the parser has parsed as much as possible.
///
@@ -368,15 +364,47 @@ public:
private:
struct ParsingState {
- ParsingState(struct LineTable *LT);
+ ParsingState(struct LineTable *LT, uint64_t TableOffset,
+ function_ref<void(Error)> ErrorHandler);
void resetRowAndSequence();
void appendRowToMatrix();
+ /// Advance the address by the \p OperationAdvance value. \returns the
+ /// amount advanced by.
+ uint64_t advanceAddr(uint64_t OperationAdvance, uint8_t Opcode,
+ uint64_t OpcodeOffset);
+
+ struct AddrAndAdjustedOpcode {
+ uint64_t AddrDelta;
+ uint8_t AdjustedOpcode;
+ };
+
+ /// Advance the address as required by the specified \p Opcode.
+ /// \returns the amount advanced by and the calculated adjusted opcode.
+ AddrAndAdjustedOpcode advanceAddrForOpcode(uint8_t Opcode,
+ uint64_t OpcodeOffset);
+
+ struct AddrAndLineDelta {
+ uint64_t Address;
+ int32_t Line;
+ };
+
+ /// Advance the line and address as required by the specified special \p
+ /// Opcode. \returns the address and line delta.
+ AddrAndLineDelta handleSpecialOpcode(uint8_t Opcode, uint64_t OpcodeOffset);
+
/// Line table we're currently parsing.
struct LineTable *LineTable;
struct Row Row;
struct Sequence Sequence;
+
+ private:
+ uint64_t LineTableOffset;
+
+ bool ReportAdvanceAddrProblem = true;
+ bool ReportBadLineRange = true;
+ function_ref<void(Error)> ErrorHandler;
};
using LineTableMapTy = std::map<uint64_t, LineTable>;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
index 7880bcdf6881..4d463d8fe6f5 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugMacro.h
@@ -10,7 +10,10 @@
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/DataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
#include <cstdint>
namespace llvm {
@@ -18,6 +21,51 @@ namespace llvm {
class raw_ostream;
class DWARFDebugMacro {
+ /// DWARFv5 section 6.3.1 Macro Information Header.
+ enum HeaderFlagMask {
+#define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ };
+ struct MacroHeader {
+ /// Macro version information number.
+ uint16_t Version = 0;
+
+ /// The bits of the flags field are interpreted as a set of flags, some of
+ /// which may indicate that additional fields follow. The following flags,
+ /// beginning with the least significant bit, are defined:
+ /// offset_size_flag:
+ /// If the offset_size_flag is zero, the header is for a 32-bit DWARF
+ /// format macro section and all offsets are 4 bytes long; if it is one,
+ /// the header is for a 64-bit DWARF format macro section and all offsets
+ /// are 8 bytes long.
+ /// debug_line_offset_flag:
+ /// If the debug_line_offset_flag is one, the debug_line_offset field (see
+ /// below) is present. If zero, that field is omitted.
+ /// opcode_operands_table_flag:
+ /// If the opcode_operands_table_flag is one, the opcode_operands_table
+ /// field (see below) is present. If zero, that field is omitted.
+ uint8_t Flags = 0;
+
+ /// debug_line_offset
+ /// An offset in the .debug_line section of the beginning of the line
+ /// number information in the containing compilation unit, encoded as a
+ /// 4-byte offset for a 32-bit DWARF format macro section and an 8-byte
+ /// offset for a 64-bit DWARF format macro section.
+ uint64_t DebugLineOffset;
+
+ /// Print the macro header from the debug_macro section.
+ void dumpMacroHeader(raw_ostream &OS) const;
+
+ /// Parse the debug_macro header.
+ Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset);
+
+ /// Get the DWARF format according to the flags.
+ dwarf::DwarfFormat getDwarfFormat() const;
+
+ /// Get the size of a reference according to the DWARF format.
+ uint8_t getOffsetByteSize() const;
+ };
+
/// A single macro entry within a macro list.
struct Entry {
/// The type of the macro entry.
@@ -27,6 +75,8 @@ class DWARFDebugMacro {
uint64_t Line;
/// Vendor extension constant value.
uint64_t ExtConstant;
+ /// Macro unit import offset.
+ uint64_t ImportOffset;
};
union {
@@ -39,7 +89,14 @@ class DWARFDebugMacro {
};
};
- using MacroList = SmallVector<Entry, 4>;
+ struct MacroList {
+ // A value 0 in the `Header.Version` field indicates that we're parsing
+ // a macinfo[.dwo] section which doesn't have header itself, hence
+ // for that case other fields in the `Header` are uninitialized.
+ MacroHeader Header;
+ SmallVector<Entry, 4> Macros;
+ uint64_t Offset;
+ };
/// A list of all the macro entries in the debug_macinfo section.
std::vector<MacroList> MacroLists;
@@ -47,14 +104,28 @@ class DWARFDebugMacro {
public:
DWARFDebugMacro() = default;
- /// Print the macro list found within the debug_macinfo section.
+ /// Print the macro list found within the debug_macinfo/debug_macro section.
void dump(raw_ostream &OS) const;
- /// Parse the debug_macinfo section accessible via the 'data' parameter.
- void parse(DataExtractor data);
+ Error parseMacro(DWARFUnitVector::iterator_range Units,
+ DataExtractor StringExtractor,
+ DWARFDataExtractor MacroData) {
+ return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true);
+ }
+
+ Error parseMacinfo(DWARFDataExtractor MacroData) {
+ return parseImpl(None, None, MacroData, /*IsMacro=*/false);
+ }
/// Return whether the section has any entries.
bool empty() const { return MacroLists.empty(); }
+
+private:
+ /// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData'
+ /// parameter.
+ Error parseImpl(Optional<DWARFUnitVector::iterator_range> Units,
+ Optional<DataExtractor> StringExtractor,
+ DWARFDataExtractor Data, bool IsMacro);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
index ae57306b90e1..cb347615868b 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
#include <cstdint>
#include <vector>
@@ -42,7 +43,10 @@ public:
struct Set {
/// The total length of the entries for that set, not including the length
/// field itself.
- uint32_t Length;
+ uint64_t Length;
+
+ /// The DWARF format of the set.
+ dwarf::DwarfFormat Format;
/// This number is specific to the name lookup table and is independent of
/// the DWARF version number.
@@ -54,7 +58,7 @@ public:
/// The size in bytes of the contents of the .debug_info section generated
/// to represent that compilation unit.
- uint32_t Size;
+ uint64_t Size;
std::vector<Entry> Entries;
};
@@ -64,11 +68,13 @@ private:
/// gnu styled tables contains additional information.
/// This flag determines whether or not section we parse is debug_gnu* table.
- bool GnuStyle;
+ bool GnuStyle = false;
public:
- DWARFDebugPubTable(const DWARFObject &Obj, const DWARFSection &Sec,
- bool LittleEndian, bool GnuStyle);
+ DWARFDebugPubTable() = default;
+
+ void extract(DWARFDataExtractor Data, bool GnuStyle,
+ function_ref<void(Error)> RecoverableErrorHandler);
void dump(raw_ostream &OS) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 158bd82edee0..05a6056e8e21 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -241,10 +241,22 @@ public:
/// Returns null if no name is found.
const char *getSubroutineName(DINameKind Kind) const;
- /// Return the DIE name resolving DW_AT_sepcification or DW_AT_abstract_origin
- /// references if necessary. Returns null if no name is found.
+ /// Return the DIE name resolving DW_AT_specification or DW_AT_abstract_origin
+ /// references if necessary. For the LinkageName case it additionaly searches
+ /// for ShortName if LinkageName is not found.
+ /// Returns null if no name is found.
const char *getName(DINameKind Kind) const;
+ /// Return the DIE short name resolving DW_AT_specification or
+ /// DW_AT_abstract_origin references if necessary. Returns null if no name
+ /// is found.
+ const char *getShortName() const;
+
+ /// Return the DIE linkage name resolving DW_AT_specification or
+ /// DW_AT_abstract_origin references if necessary. Returns null if no name
+ /// is found.
+ const char *getLinkageName() const;
+
/// Returns the declaration line (start line) for a DIE, assuming it specifies
/// a subprogram. This may be fetched from specification or abstract origin
/// for this subprogram by resolving DW_AT_sepcification or
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
index 456d9df957ad..edfa68d49a60 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFExpression.h
@@ -12,6 +12,8 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/DataExtractor.h"
namespace llvm {
@@ -42,6 +44,7 @@ public:
SizeRefAddr = 6,
SizeBlock = 7, ///< Preceding operand contains block size
BaseTypeRef = 8,
+ WasmLocationArg = 30,
SignBit = 0x80,
SignedSize1 = SignBit | Size1,
SignedSize2 = SignBit | Size2,
@@ -87,8 +90,8 @@ public:
uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
uint64_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
uint64_t getEndOffset() { return EndOffset; }
- bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
- uint64_t Offset);
+ bool extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset,
+ Optional<dwarf::DwarfFormat> Format);
bool isError() { return Error; }
bool print(raw_ostream &OS, const DWARFExpression *Expr,
const MCRegisterInfo *RegInfo, DWARFUnit *U, bool isEH);
@@ -107,7 +110,7 @@ public:
: Expr(Expr), Offset(Offset) {
Op.Error =
Offset >= Expr->Data.getData().size() ||
- !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
+ !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
}
public:
@@ -115,7 +118,7 @@ public:
Offset = Op.isError() ? Expr->Data.getData().size() : Op.EndOffset;
Op.Error =
Offset >= Expr->Data.getData().size() ||
- !Op.extract(Expr->Data, Expr->Version, Expr->AddressSize, Offset);
+ !Op.extract(Expr->Data, Expr->AddressSize, Offset, Expr->Format);
return Op;
}
@@ -123,12 +126,17 @@ public:
return Op;
}
+ iterator skipBytes(uint64_t Add) {
+ return iterator(Expr, Op.EndOffset + Add);
+ }
+
// Comparison operators are provided out of line.
friend bool operator==(const iterator &, const iterator &);
};
- DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize)
- : Data(Data), Version(Version), AddressSize(AddressSize) {
+ DWARFExpression(DataExtractor Data, uint8_t AddressSize,
+ Optional<dwarf::DwarfFormat> Format = None)
+ : Data(Data), AddressSize(AddressSize), Format(Format) {
assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
}
@@ -138,12 +146,18 @@ public:
void print(raw_ostream &OS, const MCRegisterInfo *RegInfo, DWARFUnit *U,
bool IsEH = false) const;
+ /// Print the expression in a format intended to be compact and useful to a
+ /// user, but not perfectly unambiguous, or capable of representing every
+ /// valid DWARF expression. Returns true if the expression was sucessfully
+ /// printed.
+ bool printCompact(raw_ostream &OS, const MCRegisterInfo &RegInfo);
+
bool verify(DWARFUnit *U);
private:
DataExtractor Data;
- uint16_t Version;
uint8_t AddressSize;
+ Optional<dwarf::DwarfFormat> Format;
};
inline bool operator==(const DWARFExpression::iterator &LHS,
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 6fec6fcb6b34..3f1be4e5a592 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -55,6 +55,8 @@ private:
};
dwarf::Form Form; /// Form for this value.
+ dwarf::DwarfFormat Format =
+ dwarf::DWARF32; /// Remember the DWARF format at extract time.
ValueType Value; /// Contains all data for the form.
const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
const DWARFContext *C = nullptr; /// Context for extract time.
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
index fbcde7d7cd78..60fcd3daf5b1 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h
@@ -47,6 +47,8 @@ public:
virtual StringRef getStrSection() const { return ""; }
virtual const DWARFSection &getRangesSection() const { return Dummy; }
virtual const DWARFSection &getRnglistsSection() const { return Dummy; }
+ virtual const DWARFSection &getMacroSection() const { return Dummy; }
+ virtual StringRef getMacroDWOSection() const { return ""; }
virtual StringRef getMacinfoSection() const { return ""; }
virtual StringRef getMacinfoDWOSection() const { return ""; }
virtual const DWARFSection &getPubnamesSection() const { return Dummy; }
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index b2ddb7e36b0c..5b3b46626059 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -70,10 +70,14 @@ class DWARFUnitHeader {
public:
/// Parse a unit header from \p debug_info starting at \p offset_ptr.
+ /// Note that \p SectionKind is used as a hint to guess the unit type
+ /// for DWARF formats prior to DWARFv5. In DWARFv5 the unit type is
+ /// explicitly defined in the header and the hint is ignored.
bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
- uint64_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
- const DWARFUnitIndex *Index = nullptr,
- const DWARFUnitIndex::Entry *Entry = nullptr);
+ uint64_t *offset_ptr, DWARFSectionKind SectionKind);
+ // For units in DWARF Package File, remember the index entry and update
+ // the abbreviation offset read by extract().
+ bool applyIndexEntry(const DWARFUnitIndex::Entry *Entry);
uint64_t getOffset() const { return Offset; }
const dwarf::FormParams &getFormParams() const { return FormParams; }
uint16_t getVersion() const { return FormParams.Version; }
@@ -287,6 +291,7 @@ public:
return Header.getDwarfOffsetByteSize();
}
uint64_t getLength() const { return Header.getLength(); }
+ dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
uint8_t getUnitType() const { return Header.getUnitType(); }
bool isTypeUnit() const { return Header.isTypeUnit(); }
uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
@@ -296,7 +301,7 @@ public:
return StringOffsetSection;
}
- void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
+ void setAddrOffsetSection(const DWARFSection *AOS, uint64_t Base) {
AddrOffsetSection = AOS;
AddrOffsetSectionBase = Base;
}
@@ -371,26 +376,6 @@ public:
return false;
}
- /// Return the number of bytes for the header of a unit of
- /// UnitType type.
- ///
- /// This function must be called with a valid unit type which in
- /// DWARF5 is defined as one of the following six types.
- static uint32_t getDWARF5HeaderSize(uint8_t UnitType) {
- switch (UnitType) {
- case dwarf::DW_UT_compile:
- case dwarf::DW_UT_partial:
- return 12;
- case dwarf::DW_UT_skeleton:
- case dwarf::DW_UT_split_compile:
- return 20;
- case dwarf::DW_UT_type:
- case dwarf::DW_UT_split_type:
- return 24;
- }
- llvm_unreachable("Invalid UnitType.");
- }
-
llvm::Optional<object::SectionedAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
@@ -507,7 +492,7 @@ public:
uint32_t getLineTableOffset() const {
if (auto IndexEntry = Header.getIndexEntry())
- if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
+ if (const auto *Contrib = IndexEntry->getContribution(DW_SECT_LINE))
return Contrib->Offset;
return 0;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index 684103aac2fc..edea59e474cf 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -19,17 +19,64 @@ namespace llvm {
class raw_ostream;
+/// The enum of section identifiers to be used in internal interfaces.
+///
+/// Pre-standard implementation of package files defined a number of section
+/// identifiers with values that clash definitions in the DWARFv5 standard.
+/// See https://gcc.gnu.org/wiki/DebugFissionDWP and Section 7.3.5.3 in DWARFv5.
+///
+/// The following identifiers are the same in the proposal and in DWARFv5:
+/// - DW_SECT_INFO = 1 (.debug_info.dwo)
+/// - DW_SECT_ABBREV = 3 (.debug_abbrev.dwo)
+/// - DW_SECT_LINE = 4 (.debug_line.dwo)
+/// - DW_SECT_STR_OFFSETS = 6 (.debug_str_offsets.dwo)
+///
+/// The following identifiers are defined only in DWARFv5:
+/// - DW_SECT_LOCLISTS = 5 (.debug_loclists.dwo)
+/// - DW_SECT_RNGLISTS = 8 (.debug_rnglists.dwo)
+///
+/// The following identifiers are defined only in the GNU proposal:
+/// - DW_SECT_TYPES = 2 (.debug_types.dwo)
+/// - DW_SECT_LOC = 5 (.debug_loc.dwo)
+/// - DW_SECT_MACINFO = 7 (.debug_macinfo.dwo)
+///
+/// DW_SECT_MACRO for the .debug_macro.dwo section is defined in both standards,
+/// but with different values, 8 in GNU and 7 in DWARFv5.
+///
+/// This enum defines constants to represent the identifiers of both sets.
+/// For DWARFv5 ones, the values are the same as defined in the standard.
+/// For pre-standard ones that correspond to sections being deprecated in
+/// DWARFv5, the values are chosen arbitrary and a tag "_EXT_" is added to
+/// the names.
+///
+/// The enum is for internal use only. The user should not expect the values
+/// to correspond to any input/output constants. Special conversion functions,
+/// serializeSectionKind() and deserializeSectionKind(), should be used for
+/// the translation.
enum DWARFSectionKind {
- DW_SECT_INFO = 1,
- DW_SECT_TYPES,
- DW_SECT_ABBREV,
- DW_SECT_LINE,
- DW_SECT_LOC,
- DW_SECT_STR_OFFSETS,
- DW_SECT_MACINFO,
- DW_SECT_MACRO,
+ /// Denotes a value read from an index section that does not correspond
+ /// to any of the supported standards.
+ DW_SECT_EXT_unknown = 0,
+#define HANDLE_DW_SECT(ID, NAME) DW_SECT_##NAME = ID,
+#include "llvm/BinaryFormat/Dwarf.def"
+ DW_SECT_EXT_TYPES = 2,
+ DW_SECT_EXT_LOC = 9,
+ DW_SECT_EXT_MACINFO = 10,
};
+/// Convert the internal value for a section kind to an on-disk value.
+///
+/// The conversion depends on the version of the index section.
+/// IndexVersion is expected to be either 2 for pre-standard GNU proposal
+/// or 5 for DWARFv5 package file.
+uint32_t serializeSectionKind(DWARFSectionKind Kind, unsigned IndexVersion);
+
+/// Convert a value read from an index section to the internal representation.
+///
+/// The conversion depends on the index section version, which is expected
+/// to be either 2 for pre-standard GNU proposal or 5 for DWARFv5 package file.
+DWARFSectionKind deserializeSectionKind(uint32_t Value, unsigned IndexVersion);
+
class DWARFUnitIndex {
struct Header {
uint32_t Version;
@@ -56,10 +103,10 @@ public:
friend class DWARFUnitIndex;
public:
- const SectionContribution *getOffset(DWARFSectionKind Sec) const;
- const SectionContribution *getOffset() const;
+ const SectionContribution *getContribution(DWARFSectionKind Sec) const;
+ const SectionContribution *getContribution() const;
- const SectionContribution *getOffsets() const {
+ const SectionContribution *getContributions() const {
return Contributions.get();
}
@@ -72,6 +119,10 @@ private:
DWARFSectionKind InfoColumnKind;
int InfoColumn = -1;
std::unique_ptr<DWARFSectionKind[]> ColumnKinds;
+ // This is a parallel array of section identifiers as they read from the input
+ // file. The mapping from raw values to DWARFSectionKind is not revertable in
+ // case of unknown identifiers, so we keep them here.
+ std::unique_ptr<uint32_t[]> RawSectionIds;
std::unique_ptr<Entry[]> Rows;
mutable std::vector<Entry *> OffsetLookup;
@@ -88,6 +139,8 @@ public:
bool parse(DataExtractor IndexData);
void dump(raw_ostream &OS) const;
+ uint32_t getVersion() const { return Header.Version; }
+
const Entry *getFromOffset(uint32_t Offset) const;
const Entry *getFromHash(uint64_t Offset) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index a4a3a11d441b..22b1d722fc89 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
#define LLVM_DEBUGINFO_DWARF_DWARFVERIFIER_H
+#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
@@ -56,11 +57,13 @@ public:
typedef std::set<DieRangeInfo>::const_iterator die_range_info_iterator;
/// Inserts the address range. If the range overlaps with an existing
- /// range, the range is *not* added and an iterator to the overlapping
- /// range is returned.
+ /// range, the range that it overlaps with will be returned and the two
+ /// address ranges will be unioned together in "Ranges".
///
- /// This is used for finding overlapping ranges within the same DIE.
- address_range_iterator insert(const DWARFAddressRange &R);
+ /// This is used for finding overlapping ranges in the DW_AT_ranges
+ /// attribute of a DIE. It is also used as a set of address ranges that
+ /// children address ranges must all be contained in.
+ Optional<DWARFAddressRange> insert(const DWARFAddressRange &R);
/// Finds an address range in the sorted vector of ranges.
address_range_iterator findRange(const DWARFAddressRange &R) const {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h
new file mode 100644
index 000000000000..a5d07fbeda92
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/DwarfTransformer.h
@@ -0,0 +1,91 @@
+//===- DwarfTransformer.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_DWARFTRANSFORMER_H
+#define LLVM_DEBUGINFO_GSYM_DWARFTRANSFORMER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+namespace gsym {
+
+struct CUInfo;
+struct FunctionInfo;
+class GsymCreator;
+
+/// A class that transforms the DWARF in a DWARFContext into GSYM information
+/// by populating the GsymCreator object that it is constructed with. This
+/// class supports converting all DW_TAG_subprogram DIEs into
+/// gsym::FunctionInfo objects that includes line table information and inline
+/// function information. Creating a separate class to transform this data
+/// allows this class to be unit tested.
+class DwarfTransformer {
+public:
+
+ /// Create a DWARF transformer.
+ ///
+ /// \param D The DWARF to use when converting to GSYM.
+ ///
+ /// \param OS The stream to log warnings and non fatal issues to.
+ ///
+ /// \param G The GSYM creator to populate with the function information
+ /// from the debug info.
+ DwarfTransformer(DWARFContext &D, raw_ostream &OS, GsymCreator &G) :
+ DICtx(D), Log(OS), Gsym(G) {}
+
+ /// Extract the DWARF from the supplied object file and convert it into the
+ /// Gsym format in the GsymCreator object that is passed in. Returns an
+ /// error if something fatal is encountered.
+ ///
+ /// \returns An error indicating any fatal issues that happen when parsing
+ /// the DWARF, or Error::success() if all goes well.
+ llvm::Error convert(uint32_t NumThreads);
+
+ llvm::Error verify(StringRef GsymPath);
+
+
+private:
+
+ /// Parse the DWARF in the object file and convert it into the GsymCreator.
+ Error parse();
+
+ /// Handle any DIE (debug info entry) from the DWARF.
+ ///
+ /// This function will find all DW_TAG_subprogram DIEs that convert them into
+ /// GSYM FuntionInfo objects and add them to the GsymCreator supplied during
+ /// construction. The DIE and all its children will be recursively parsed
+ /// with calls to this function.
+ ///
+ /// \param Strm The thread specific log stream for any non fatal errors and
+ /// warnings. Once a thread has finished parsing an entire compile unit, all
+ /// information in this temporary stream will be forwarded to the member
+ /// variable log. This keeps logging thread safe.
+ ///
+ /// \param CUI The compile unit specific information that contains the DWARF
+ /// line table, cached file list, and other compile unit specific
+ /// information.
+ ///
+ /// \param Die The DWARF debug info entry to parse.
+ void handleDie(raw_ostream &Strm, CUInfo &CUI, DWARFDie Die);
+
+ DWARFContext &DICtx;
+ raw_ostream &Log;
+ GsymCreator &Gsym;
+
+ friend class DwarfTransformerTest;
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_DWARFTRANSFORMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
index e61eb678c82e..f29a147d4403 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymCreator.h
@@ -16,6 +16,7 @@
#include <thread>
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringSet.h"
#include "llvm/DebugInfo/GSYM/FileEntry.h"
#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
#include "llvm/DebugInfo/GSYM/Range.h"
@@ -135,9 +136,13 @@ class GsymCreator {
mutable std::recursive_mutex Mutex;
std::vector<FunctionInfo> Funcs;
StringTableBuilder StrTab;
+ StringSet<> StringStorage;
DenseMap<llvm::gsym::FileEntry, uint32_t> FileEntryToIndex;
std::vector<llvm::gsym::FileEntry> Files;
std::vector<uint8_t> UUID;
+ Optional<AddressRanges> ValidTextRanges;
+ AddressRanges Ranges;
+ llvm::Optional<uint64_t> BaseAddress;
bool Finalized = false;
public:
@@ -162,9 +167,12 @@ public:
/// All strings used by GSYM files must be uniqued by adding them to this
/// string pool and using the returned offset for any string values.
///
- /// \param S The string to insert into the string table.
+ /// \param S The string to insert into the string table.
+ /// \param Copy If true, then make a backing copy of the string. If false,
+ /// the string is owned by another object that will stay around
+ /// long enough for the GsymCreator to save the GSYM file.
/// \returns The unique 32 bit offset into the string table.
- uint32_t insertString(StringRef S);
+ uint32_t insertString(StringRef S, bool Copy = true);
/// Insert a file into this GSYM creator.
///
@@ -221,6 +229,66 @@ public:
void forEachFunctionInfo(
std::function<bool(const FunctionInfo &)> const &Callback) const;
+ /// Get the current number of FunctionInfo objects contained in this
+ /// object.
+ size_t getNumFunctionInfos() const;
+
+ /// Check if an address has already been added as a function info.
+ ///
+ /// FunctionInfo data can come from many sources: debug info, symbol tables,
+ /// exception information, and more. Symbol tables should be added after
+ /// debug info and can use this function to see if a symbol's start address
+ /// has already been added to the GsymReader. Calling this before adding
+ /// a function info from a source other than debug info avoids clients adding
+ /// many redundant FunctionInfo objects from many sources only for them to be
+ /// removed during the finalize() call.
+ bool hasFunctionInfoForAddress(uint64_t Addr) const;
+
+ /// Set valid .text address ranges that all functions must be contained in.
+ void SetValidTextRanges(AddressRanges &TextRanges) {
+ ValidTextRanges = TextRanges;
+ }
+
+ /// Get the valid text ranges.
+ const Optional<AddressRanges> GetValidTextRanges() const {
+ return ValidTextRanges;
+ }
+
+ /// Check if an address is a valid code address.
+ ///
+ /// Any functions whose addresses do not exist within these function bounds
+ /// will not be converted into the final GSYM. This allows the object file
+ /// to figure out the valid file address ranges of all the code sections
+ /// and ensure we don't add invalid functions to the final output. Many
+ /// linkers have issues when dead stripping functions from DWARF debug info
+ /// where they set the DW_AT_low_pc to zero, but newer DWARF has the
+ /// DW_AT_high_pc as an offset from the DW_AT_low_pc and these size
+ /// attributes have no relocations that can be applied. This results in DWARF
+ /// where many functions have an DW_AT_low_pc of zero and a valid offset size
+ /// for DW_AT_high_pc. If we extract all valid ranges from an object file
+ /// that are marked with executable permissions, we can properly ensure that
+ /// these functions are removed.
+ ///
+ /// \param Addr An address to check.
+ ///
+ /// \returns True if the address is in the valid text ranges or if no valid
+ /// text ranges have been set, false otherwise.
+ bool IsValidTextAddress(uint64_t Addr) const;
+
+ /// Set the base address to use for the GSYM file.
+ ///
+ /// Setting the base address to use for the GSYM file. Object files typically
+ /// get loaded from a base address when the OS loads them into memory. Using
+ /// GSYM files for symbolication becomes easier if the base address in the
+ /// GSYM header is the same address as it allows addresses to be easily slid
+ /// and allows symbolication without needing to find the original base
+ /// address in the original object file.
+ ///
+ /// \param Addr The address to use as the base address of the GSYM file
+ /// when it is saved to disk.
+ void setBaseAddress(uint64_t Addr) {
+ BaseAddress = Addr;
+ }
};
} // namespace gsym
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
index 5ba13f846798..2a4eac77d946 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/GsymReader.h
@@ -147,7 +147,60 @@ public:
return llvm::None;
}
-protected:
+ /// Dump the entire Gsym data contained in this object.
+ ///
+ /// \param OS The output stream to dump to.
+ void dump(raw_ostream &OS);
+
+ /// Dump a FunctionInfo object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param FI The object to dump.
+ void dump(raw_ostream &OS, const FunctionInfo &FI);
+
+ /// Dump a LineTable object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param LT The object to dump.
+ void dump(raw_ostream &OS, const LineTable &LT);
+
+ /// Dump a InlineInfo object.
+ ///
+ /// This function will convert any string table indexes and file indexes
+ /// into human readable format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param II The object to dump.
+ ///
+ /// \param Indent The indentation as number of spaces. Used for recurive
+ /// dumping.
+ void dump(raw_ostream &OS, const InlineInfo &II, uint32_t Indent = 0);
+
+ /// Dump a FileEntry object.
+ ///
+ /// This function will convert any string table indexes into human readable
+ /// format.
+ ///
+ /// \param OS The output stream to dump to.
+ ///
+ /// \param FE The object to dump.
+ void dump(raw_ostream &OS, Optional<FileEntry> FE);
+
+ /// Get the number of addresses in this Gsym file.
+ uint32_t getNumAddresses() const {
+ return Hdr->NumAddresses;
+ }
+
/// Gets an address from the address table.
///
/// Addresses are stored as offsets frrom the gsym::Header::BaseAddress.
@@ -157,6 +210,8 @@ protected:
/// or llvm::None if Index is out of bounds.
Optional<uint64_t> getAddress(size_t Index) const;
+protected:
+
/// Get an appropriate address info offsets array.
///
/// The address table in the GSYM file is stored as array of 1, 2, 4 or 8
@@ -202,11 +257,15 @@ protected:
/// \returns The matching address offset index. This index will be used to
/// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
template <class T>
- uint64_t getAddressOffsetIndex(const uint64_t AddrOffset) const {
+ llvm::Optional<uint64_t> getAddressOffsetIndex(const uint64_t AddrOffset) const {
ArrayRef<T> AIO = getAddrOffsets<T>();
const auto Begin = AIO.begin();
const auto End = AIO.end();
auto Iter = std::lower_bound(Begin, End, AddrOffset);
+ // Watch for addresses that fall between the gsym::Header::BaseAddress and
+ // the first address offset.
+ if (Iter == Begin && AddrOffset < *Begin)
+ return llvm::None;
if (Iter == End || AddrOffset < *Iter)
--Iter;
return std::distance(Begin, Iter);
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/InlineInfo.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/InlineInfo.h
index 3b95e3e050bd..06126da7d007 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/InlineInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/InlineInfo.h
@@ -46,7 +46,7 @@ class GsymReader;
/// also makes any encoded addresses easy to relocate as we just need to
/// relocate the FunctionInfo's start address.
///
-/// - The AddressRanges member "Ranges" is encoded using an approriate base
+/// - The AddressRanges member "Ranges" is encoded using an appropriate base
/// address as described above.
/// - UINT8 boolean value that specifies if the InlineInfo object has children.
/// - UINT32 string table offset that points to the name of the inline
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LineTable.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LineTable.h
index 22668e39d94c..fba9b2c79735 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LineTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LineTable.h
@@ -166,6 +166,24 @@ public:
llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const;
bool empty() const { return Lines.empty(); }
void clear() { Lines.clear(); }
+ /// Return the first line entry if the line table isn't empty.
+ ///
+ /// \returns An optional line entry with the first line entry if the line
+ /// table isn't empty, or llvm::None if the line table is emtpy.
+ Optional<LineEntry> first() const {
+ if (Lines.empty())
+ return llvm::None;
+ return Lines.front();
+ }
+ /// Return the last line entry if the line table isn't empty.
+ ///
+ /// \returns An optional line entry with the last line entry if the line
+ /// table isn't empty, or llvm::None if the line table is emtpy.
+ Optional<LineEntry> last() const {
+ if (Lines.empty())
+ return llvm::None;
+ return Lines.back();
+ }
void push(const LineEntry &LE) {
Lines.push_back(LE);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LookupResult.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LookupResult.h
index 746fd36208e1..693a02c50f16 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LookupResult.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/LookupResult.h
@@ -24,11 +24,13 @@ struct SourceLocation {
StringRef Dir; ///< Line entry source file directory path.
StringRef Base; ///< Line entry source file basename.
uint32_t Line = 0; ///< Source file line number.
+ uint32_t Offset = 0; ///< Byte size offset within the named function.
};
inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
return LHS.Name == RHS.Name && LHS.Dir == RHS.Dir &&
- LHS.Base == RHS.Base && LHS.Line == RHS.Line;
+ LHS.Base == RHS.Base && LHS.Line == RHS.Line &&
+ LHS.Offset == RHS.Offset;
}
raw_ostream &operator<<(raw_ostream &OS, const SourceLocation &R);
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h
new file mode 100644
index 000000000000..84a8d98fe365
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/ObjectFileTransformer.h
@@ -0,0 +1,51 @@
+//===- ObjectFileTransformer.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H
+#define LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+class raw_ostream;
+
+namespace object {
+class ObjectFile;
+}
+
+namespace gsym {
+
+struct CUInfo;
+class GsymCreator;
+
+class ObjectFileTransformer {
+public:
+ /// Extract any object file data that is needed by the GsymCreator.
+ ///
+ /// The extracted information includes the UUID of the binary and converting
+ /// all function symbols from any symbol tables into FunctionInfo objects.
+ ///
+ /// \param Obj The object file that contains the DWARF debug info.
+ ///
+ /// \param Log The stream to log warnings and non fatal issues to.
+ ///
+ /// \param Gsym The GSYM creator to populate with the function information
+ /// from the debug info.
+ ///
+ /// \returns An error indicating any fatal issues that happen when parsing
+ /// the DWARF, or Error::success() if all goes well.
+ static llvm::Error convert(const object::ObjectFile &Obj,
+ raw_ostream &Log,
+ GsymCreator &Gsym);
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_OBJECTFILETRANSFORMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/Range.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/Range.h
index 49e316eae3cf..b3e7692543bf 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/Range.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/GSYM/Range.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_GSYM_RANGE_H
#define LLVM_DEBUGINFO_GSYM_RANGE_H
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#include <stdint.h>
@@ -89,6 +90,7 @@ public:
bool empty() const { return Ranges.empty(); }
bool contains(uint64_t Addr) const;
bool contains(AddressRange Range) const;
+ Optional<AddressRange> getRangeThatContains(uint64_t Addr) const;
void insert(AddressRange Range);
size_t size() const { return Ranges.size(); }
bool operator==(const AddressRanges &RHS) const {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 6f62e6061f56..09ab9e2861cd 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -38,13 +38,13 @@ public:
bool addressForRVA(uint32_t RVA, uint32_t &Section,
uint32_t &Offset) const override;
- std::unique_ptr<PDBSymbol>
- findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address,
+ PDB_SymType Type) override;
std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
- PDB_SymType Type) const override;
- std::unique_ptr<PDBSymbol>
- findSymbolBySectOffset(uint32_t Section, uint32_t Offset,
- PDB_SymType Type) const override;
+ PDB_SymType Type) override;
+ std::unique_ptr<PDBSymbol> findSymbolBySectOffset(uint32_t Section,
+ uint32_t Offset,
+ PDB_SymType Type) override;
std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/GenericError.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/GenericError.h
index af93be931b8e..1ef9b36cadaf 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/GenericError.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/GenericError.h
@@ -9,7 +9,6 @@
#ifndef LLVM_DEBUGINFO_PDB_ERROR_H
#define LLVM_DEBUGINFO_PDB_ERROR_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
index d5b36f9846b5..6ee6c7cc8fc1 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBInjectedSource.h
@@ -9,15 +9,11 @@
#ifndef LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
#define LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
-#include "llvm/Support/raw_ostream.h"
-#include <memory>
+#include <cstdint>
#include <string>
namespace llvm {
-class raw_ostream;
-
namespace pdb {
-
/// IPDBInjectedSource defines an interface used to represent source files
/// which were injected directly into the PDB file during the compilation
/// process. This is used, for example, to add natvis files to a PDB, but
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBLineNumber.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
index 77e88999497e..47b6397099b7 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBLineNumber.h
@@ -9,7 +9,7 @@
#ifndef LLVM_DEBUGINFO_PDB_IPDBLINENUMBER_H
#define LLVM_DEBUGINFO_PDB_IPDBLINENUMBER_H
-#include "PDBTypes.h"
+#include <cstdint>
namespace llvm {
namespace pdb {
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
index b24e712e3b78..f59e933ca575 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBRawSymbol.h
@@ -12,19 +12,15 @@
#include "PDBTypes.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include <memory>
namespace llvm {
class raw_ostream;
+class StringRef;
namespace pdb {
-class IPDBSession;
-class PDBSymbolTypeVTable;
-class PDBSymbolTypeVTableShape;
-
enum class PdbSymbolIdField : uint32_t {
None = 0,
SymIndexId = 1 << 0,
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
index aa8d9c76d63e..7e38654c6550 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/IPDBSession.h
@@ -42,13 +42,12 @@ public:
return unique_dyn_cast_or_null<T>(getSymbolById(SymbolId));
}
+ virtual std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address,
+ PDB_SymType Type) = 0;
+ virtual std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
+ PDB_SymType Type) = 0;
virtual std::unique_ptr<PDBSymbol>
- findSymbolByAddress(uint64_t Address, PDB_SymType Type) const = 0;
- virtual std::unique_ptr<PDBSymbol>
- findSymbolByRVA(uint32_t RVA, PDB_SymType Type) const = 0;
- virtual std::unique_ptr<PDBSymbol>
- findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
- PDB_SymType Type) const = 0;
+ findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type) = 0;
virtual std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
index 4f5d28bbd05a..beaaef0c5a6c 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h
@@ -93,8 +93,7 @@ private:
std::vector<std::string> SourceFiles;
std::vector<ArrayRef<uint8_t>> Symbols;
- std::vector<std::unique_ptr<codeview::DebugSubsectionRecordBuilder>>
- C13Builders;
+ std::vector<codeview::DebugSubsectionRecordBuilder> C13Builders;
ModuleInfoHeader Layout;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
index d9be238af07b..24664c31e7ca 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h
@@ -57,7 +57,6 @@ public:
void setFlags(uint16_t F);
void setMachineType(PDB_Machine M);
void setMachineType(COFF::MachineTypes M);
- void setSectionMap(ArrayRef<SecMapEntry> SecMap);
// Add given bytes as a new stream.
Error addDbgStream(pdb::DbgHeaderType Type, ArrayRef<uint8_t> Data);
@@ -84,9 +83,8 @@ public:
SectionContribs.emplace_back(SC);
}
- // A helper function to create a Section Map from a COFF section header.
- static std::vector<SecMapEntry>
- createSectionMap(ArrayRef<llvm::object::coff_section> SecHdrs);
+ // Populate the Section Map from COFF section headers.
+ void createSectionMap(ArrayRef<llvm::object::coff_section> SecHdrs);
private:
struct DebugStream {
@@ -133,7 +131,7 @@ private:
WritableBinaryStreamRef NamesBuffer;
MutableBinaryByteStream FileInfoBuffer;
std::vector<SectionContrib> SectionContribs;
- ArrayRef<SecMapEntry> SectionMap;
+ std::vector<SecMapEntry> SectionMap;
std::array<Optional<DebugStream>, (int)DbgHeaderType::Max> DbgStreams;
};
}
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h
index a49795600028..378d4cdd23e6 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_PDB_RAW_GSISTREAMBUILDER_H
#define LLVM_DEBUGINFO_PDB_RAW_GSISTREAMBUILDER_H
+#include "llvm/ADT/DenseSet.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
@@ -37,6 +38,8 @@ struct MSFLayout;
} // namespace msf
namespace pdb {
struct GSIHashStreamBuilder;
+struct BulkPublic;
+struct SymbolDenseMapInfo;
class GSIStreamBuilder {
@@ -51,29 +54,94 @@ public:
Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef Buffer);
- uint32_t getPublicsStreamIndex() const;
- uint32_t getGlobalsStreamIndex() const;
- uint32_t getRecordStreamIdx() const { return RecordStreamIdx; }
+ uint32_t getPublicsStreamIndex() const { return PublicsStreamIndex; }
+ uint32_t getGlobalsStreamIndex() const { return GlobalsStreamIndex; }
+ uint32_t getRecordStreamIndex() const { return RecordStreamIndex; }
- void addPublicSymbol(const codeview::PublicSym32 &Pub);
+ // Add public symbols in bulk.
+ void addPublicSymbols(std::vector<BulkPublic> &&PublicsIn);
void addGlobalSymbol(const codeview::ProcRefSym &Sym);
void addGlobalSymbol(const codeview::DataSym &Sym);
void addGlobalSymbol(const codeview::ConstantSym &Sym);
+
+ // Add a pre-serialized global symbol record. The caller must ensure that the
+ // symbol data remains alive until the global stream is committed to disk.
void addGlobalSymbol(const codeview::CVSymbol &Sym);
private:
+ void finalizePublicBuckets();
+ void finalizeGlobalBuckets(uint32_t RecordZeroOffset);
+
+ template <typename T> void serializeAndAddGlobal(const T &Symbol);
+
uint32_t calculatePublicsHashStreamSize() const;
uint32_t calculateGlobalsHashStreamSize() const;
Error commitSymbolRecordStream(WritableBinaryStreamRef Stream);
Error commitPublicsHashStream(WritableBinaryStreamRef Stream);
Error commitGlobalsHashStream(WritableBinaryStreamRef Stream);
- uint32_t RecordStreamIdx = kInvalidStreamIndex;
+ uint32_t PublicsStreamIndex = kInvalidStreamIndex;
+ uint32_t GlobalsStreamIndex = kInvalidStreamIndex;
+ uint32_t RecordStreamIndex = kInvalidStreamIndex;
msf::MSFBuilder &Msf;
std::unique_ptr<GSIHashStreamBuilder> PSH;
std::unique_ptr<GSIHashStreamBuilder> GSH;
+
+ // List of all of the public records. These are stored unserialized so that we
+ // can defer copying the names until we are ready to commit the PDB.
+ std::vector<BulkPublic> Publics;
+
+ // List of all of the global records.
+ std::vector<codeview::CVSymbol> Globals;
+
+ // Hash table for deduplicating global typedef and constant records. Only used
+ // for globals.
+ llvm::DenseSet<codeview::CVSymbol, SymbolDenseMapInfo> GlobalsSeen;
};
+
+/// This struct is equivalent to codeview::PublicSym32, but it has been
+/// optimized for size to speed up bulk serialization and sorting operations
+/// during PDB writing.
+struct BulkPublic {
+ BulkPublic() : Flags(0), BucketIdx(0) {}
+
+ const char *Name = nullptr;
+ uint32_t NameLen = 0;
+
+ // Offset of the symbol record in the publics stream.
+ uint32_t SymOffset = 0;
+
+ // Section offset of the symbol in the image.
+ uint32_t Offset = 0;
+
+ // Section index of the section containing the symbol.
+ uint16_t Segment = 0;
+
+ // PublicSymFlags.
+ uint16_t Flags : 4;
+
+ // GSI hash table bucket index. The maximum value is IPHR_HASH.
+ uint16_t BucketIdx : 12;
+ static_assert(IPHR_HASH <= 1 << 12, "bitfield too small");
+
+ void setFlags(codeview::PublicSymFlags F) {
+ Flags = uint32_t(F);
+ assert(Flags == uint32_t(F) && "truncated");
+ }
+
+ void setBucketIdx(uint16_t B) {
+ assert(B < IPHR_HASH);
+ BucketIdx = B;
+ }
+
+ StringRef getName() const { return StringRef(Name, NameLen); }
+};
+
+static_assert(sizeof(BulkPublic) <= 24, "unexpected size increase");
+static_assert(std::is_trivially_copyable<BulkPublic>::value,
+ "should be trivial");
+
} // namespace pdb
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
new file mode 100644
index 000000000000..32a4515d557e
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h
@@ -0,0 +1,39 @@
+//==- NativeEnumLineNumbers.h - Native Line Number Enumerator ------------*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMLINENUMBERS_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMLINENUMBERS_H
+
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+
+namespace llvm {
+namespace pdb {
+class IPDBLineNumber;
+
+class NativeEnumLineNumbers : public IPDBEnumChildren<IPDBLineNumber> {
+public:
+ explicit NativeEnumLineNumbers(std::vector<NativeLineNumber> LineNums);
+
+ uint32_t getChildCount() const override;
+ ChildTypePtr getChildAtIndex(uint32_t Index) const override;
+ ChildTypePtr getNext() override;
+ void reset() override;
+
+private:
+ std::vector<NativeLineNumber> Lines;
+ uint32_t Index;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h
new file mode 100644
index 000000000000..4adf89f0d69a
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h
@@ -0,0 +1,45 @@
+//===- NativeFunctionSymbol.h - info about function symbols -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEFUNCTIONSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEFUNCTIONSYMBOL_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativeFunctionSymbol : public NativeRawSymbol {
+public:
+ NativeFunctionSymbol(NativeSession &Session, SymIndexId Id,
+ const codeview::ProcSym &Sym);
+
+ ~NativeFunctionSymbol() override;
+
+ void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const override;
+
+ uint32_t getAddressOffset() const override;
+ uint32_t getAddressSection() const override;
+ std::string getName() const override;
+ PDB_SymType getSymTag() const override;
+ uint64_t getLength() const override;
+ uint32_t getRelativeVirtualAddress() const override;
+ uint64_t getVirtualAddress() const override;
+
+protected:
+ const codeview::ProcSym Sym;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEFUNCTIONSYMBOL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
new file mode 100644
index 000000000000..a7ce82c70b08
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeLineNumber.h
@@ -0,0 +1,51 @@
+//===- NativeLineNumber.h - Native line number implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVELINENUMBER_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVELINENUMBER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+class NativeLineNumber : public IPDBLineNumber {
+public:
+ explicit NativeLineNumber(const NativeSession &Session,
+ const codeview::LineInfo Line,
+ uint32_t ColumnNumber, uint32_t Length,
+ uint32_t Section, uint32_t Offset,
+ uint32_t SrcFileId);
+
+ uint32_t getLineNumber() const override;
+ uint32_t getLineNumberEnd() const override;
+ uint32_t getColumnNumber() const override;
+ uint32_t getColumnNumberEnd() const override;
+ uint32_t getAddressSection() const override;
+ uint32_t getAddressOffset() const override;
+ uint32_t getRelativeVirtualAddress() const override;
+ uint64_t getVirtualAddress() const override;
+ uint32_t getLength() const override;
+ uint32_t getSourceFileId() const override;
+ uint32_t getCompilandId() const override;
+ bool isStatement() const override;
+
+private:
+ const NativeSession &Session;
+ const codeview::LineInfo Line;
+ uint32_t ColumnNumber;
+ uint32_t Section;
+ uint32_t Offset;
+ uint32_t Length;
+ uint32_t SrcFileId;
+};
+} // namespace pdb
+} // namespace llvm
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativePublicSymbol.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativePublicSymbol.h
new file mode 100644
index 000000000000..0a1451530f18
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativePublicSymbol.h
@@ -0,0 +1,44 @@
+//===- NativePublicSymbol.h - info about public symbols ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEPUBLICSYMBOL_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEPUBLICSYMBOL_H
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+namespace llvm {
+namespace pdb {
+
+class NativePublicSymbol : public NativeRawSymbol {
+public:
+ NativePublicSymbol(NativeSession &Session, SymIndexId Id,
+ const codeview::PublicSym32 &Sym);
+
+ ~NativePublicSymbol() override;
+
+ void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const override;
+
+ uint32_t getAddressOffset() const override;
+ uint32_t getAddressSection() const override;
+ std::string getName() const override;
+ PDB_SymType getSymTag() const override;
+ uint32_t getRelativeVirtualAddress() const override;
+ uint64_t getVirtualAddress() const override;
+
+protected:
+ const codeview::PublicSym32 Sym;
+};
+
+} // namespace pdb
+} // namespace llvm
+
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVEPUBLICSYMBOL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
index ee7d8cdec93b..342e63599e66 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSession.h
@@ -26,6 +26,11 @@ class PDBFile;
class NativeExeSymbol;
class NativeSession : public IPDBSession {
+ struct PdbSearchOptions {
+ StringRef ExePath;
+ // FIXME: Add other PDB search options (_NT_SYMBOL_PATH, symsrv)
+ };
+
public:
NativeSession(std::unique_ptr<PDBFile> PdbFile,
std::unique_ptr<BumpPtrAllocator> Allocator);
@@ -33,8 +38,11 @@ public:
static Error createFromPdb(std::unique_ptr<MemoryBuffer> MB,
std::unique_ptr<IPDBSession> &Session);
+ static Error createFromPdbPath(StringRef PdbPath,
+ std::unique_ptr<IPDBSession> &Session);
static Error createFromExe(StringRef Path,
std::unique_ptr<IPDBSession> &Session);
+ static Expected<std::string> searchForPdb(const PdbSearchOptions &Opts);
uint64_t getLoadAddress() const override;
bool setLoadAddress(uint64_t Address) override;
@@ -46,13 +54,13 @@ public:
bool addressForRVA(uint32_t RVA, uint32_t &Section,
uint32_t &Offset) const override;
- std::unique_ptr<PDBSymbol>
- findSymbolByAddress(uint64_t Address, PDB_SymType Type) const override;
+ std::unique_ptr<PDBSymbol> findSymbolByAddress(uint64_t Address,
+ PDB_SymType Type) override;
std::unique_ptr<PDBSymbol> findSymbolByRVA(uint32_t RVA,
- PDB_SymType Type) const override;
- std::unique_ptr<PDBSymbol>
- findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
- PDB_SymType Type) const override;
+ PDB_SymType Type) override;
+ std::unique_ptr<PDBSymbol> findSymbolBySectOffset(uint32_t Sect,
+ uint32_t Offset,
+ PDB_SymType Type) override;
std::unique_ptr<IPDBEnumLineNumbers>
findLineNumbers(const PDBSymbolCompiland &Compiland,
@@ -100,6 +108,8 @@ public:
NativeExeSymbol &getNativeGlobalScope() const;
SymbolCache &getSymbolCache() { return Cache; }
const SymbolCache &getSymbolCache() const { return Cache; }
+ uint32_t getRVAFromSectOffset(uint32_t Section, uint32_t Offset) const;
+ uint64_t getVAFromSectOffset(uint32_t Section, uint32_t Offset) const;
private:
void initializeExeSymbol();
@@ -109,6 +119,7 @@ private:
SymbolCache Cache;
SymIndexId ExeSymbol = 0;
+ uint64_t LoadAddress = 0;
};
} // namespace pdb
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
new file mode 100644
index 000000000000..eb6336f268e8
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeSourceFile.h
@@ -0,0 +1,40 @@
+//===- NativeSourceFile.h - Native source file implementation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVESOURCEFILE_H
+#define LLVM_DEBUGINFO_PDB_NATIVE_NATIVESOURCEFILE_H
+
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+
+namespace llvm {
+namespace pdb {
+class NativeSession;
+
+class NativeSourceFile : public IPDBSourceFile {
+public:
+ explicit NativeSourceFile(NativeSession &Session, uint32_t FileId,
+ const codeview::FileChecksumEntry &Checksum);
+
+ std::string getFileName() const override;
+ uint32_t getUniqueId() const override;
+ std::string getChecksum() const override;
+ PDB_Checksum getChecksumType() const override;
+ std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+ getCompilands() const override;
+
+private:
+ NativeSession &Session;
+ uint32_t FileId;
+ const codeview::FileChecksumEntry Checksum;
+};
+} // namespace pdb
+} // namespace llvm
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h
index a7ea287dffc8..358ddf5e2081 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h
@@ -70,4 +70,4 @@ private:
} // namespace pdb
} // namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H \ No newline at end of file
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
index 446f77db0f6c..7a3dfaecefeb 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypePointer.h
@@ -57,4 +57,4 @@ protected:
} // namespace pdb
} // namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H \ No newline at end of file
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h
index fe8a6f7f2bda..e7fb41bf61fc 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h
@@ -38,4 +38,4 @@ protected:
} // namespace pdb
} // namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H \ No newline at end of file
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEPOINTER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h
index 8f4dee3e658c..e1b31a256c12 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeUDT.h
@@ -70,4 +70,4 @@ protected:
} // namespace pdb
} // namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H \ No newline at end of file
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEUDT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h
index 4ec0f9bf6b3d..4ae8f1471781 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h
@@ -42,4 +42,4 @@ protected:
} // namespace pdb
} // namespace llvm
-#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H \ No newline at end of file
+#endif // LLVM_DEBUGINFO_PDB_NATIVE_NATIVETYPEVTSHAPE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
index 2abaa5f4cdc4..87ba049dd4f6 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
@@ -80,7 +80,6 @@ private:
Error finalizeMsfLayout();
Expected<uint32_t> allocateNamedStream(StringRef Name, uint32_t Size);
- void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout);
void commitInjectedSources(WritableBinaryStream &MsfBuffer,
const msf::MSFLayout &Layout);
void commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
index 4adf3b394c2e..90fd19a7a2fb 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
@@ -10,11 +10,15 @@
#define LLVM_DEBUGINFO_PDB_NATIVE_SYMBOLCACHE_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IntervalMap.h"
+#include "llvm/DebugInfo/CodeView/Line.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
#include <memory>
#include <vector>
@@ -49,9 +53,36 @@ class SymbolCache {
/// appear in the PDB file.
std::vector<SymIndexId> Compilands;
+ /// List of source files, indexed by unique source file index.
+ mutable std::vector<std::unique_ptr<NativeSourceFile>> SourceFiles;
+ mutable DenseMap<uint32_t, SymIndexId> FileNameOffsetToId;
+
/// Map from global symbol offset to SymIndexId.
DenseMap<uint32_t, SymIndexId> GlobalOffsetToSymbolId;
+ /// Map from segment and code offset to SymIndexId.
+ DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToFunctionSymId;
+ DenseMap<std::pair<uint32_t, uint32_t>, SymIndexId> AddressToPublicSymId;
+
+ /// Map from virtual address to module index.
+ using IMap =
+ IntervalMap<uint64_t, uint16_t, 8, IntervalMapHalfOpenInfo<uint64_t>>;
+ IMap::Allocator IMapAllocator;
+ IMap AddrToModuleIndex;
+
+ Expected<ModuleDebugStreamRef> getModuleDebugStream(uint32_t Index) const;
+
+ struct LineTableEntry {
+ uint64_t Addr;
+ codeview::LineInfo Line;
+ uint32_t ColumnNumber;
+ uint32_t FileNameIndex;
+ bool IsTerminalEntry;
+ };
+
+ std::vector<LineTableEntry> findLineTable(uint16_t Modi) const;
+ mutable DenseMap<uint16_t, std::vector<LineTableEntry>> LineTable;
+
SymIndexId createSymbolPlaceholder() {
SymIndexId Id = Cache.size();
Cache.push_back(nullptr);
@@ -78,6 +109,11 @@ class SymbolCache {
SymIndexId createSimpleType(codeview::TypeIndex TI,
codeview::ModifierOptions Mods);
+ std::unique_ptr<PDBSymbol> findFunctionSymbolBySectOffset(uint32_t Sect,
+ uint32_t Offset);
+ std::unique_ptr<PDBSymbol> findPublicSymbolBySectOffset(uint32_t Sect,
+ uint32_t Offset);
+
public:
SymbolCache(NativeSession &Session, DbiStream *Dbi);
@@ -128,6 +164,12 @@ public:
SymIndexId getOrCreateGlobalSymbolByOffset(uint32_t Offset);
+ std::unique_ptr<PDBSymbol>
+ findSymbolBySectOffset(uint32_t Sect, uint32_t Offset, PDB_SymType Type);
+
+ std::unique_ptr<IPDBEnumLineNumbers>
+ findLineNumbersByVA(uint64_t VA, uint32_t Length) const;
+
std::unique_ptr<PDBSymbolCompiland> getOrCreateCompiland(uint32_t Index);
uint32_t getNumCompilands() const;
@@ -139,6 +181,13 @@ public:
ConcreteT &getNativeSymbolById(SymIndexId SymbolId) const {
return static_cast<ConcreteT &>(getNativeSymbolById(SymbolId));
}
+
+ std::unique_ptr<IPDBSourceFile> getSourceFileById(SymIndexId FileId) const;
+ SymIndexId
+ getOrCreateSourceFile(const codeview::FileChecksumEntry &Checksum) const;
+
+ void parseSectionContribs();
+ Optional<uint16_t> getModuleIndexForAddr(uint64_t Addr) const;
};
} // namespace pdb
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
index 0d95a2467556..2982146f960c 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -17,13 +17,11 @@
#include "llvm/Support/Casting.h"
#define FORWARD_SYMBOL_METHOD(MethodName) \
- auto MethodName() const->decltype(RawSymbol->MethodName()) { \
- return RawSymbol->MethodName(); \
- }
+ decltype(auto) MethodName() const { return RawSymbol->MethodName(); }
#define FORWARD_CONCRETE_SYMBOL_ID_METHOD_WITH_NAME(ConcreteType, PrivateName, \
PublicName) \
- auto PublicName##Id() const->decltype(RawSymbol->PrivateName##Id()) { \
+ decltype(auto) PublicName##Id() const { \
return RawSymbol->PrivateName##Id(); \
} \
std::unique_ptr<ConcreteType> PublicName() const { \
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
index c26d8d1ed10c..e7c2ded1bee1 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -9,6 +9,7 @@
#ifndef LLVM_DEBUGINFO_PDB_PDBTYPES_H
#define LLVM_DEBUGINFO_PDB_PDBTYPES_H
+#include "llvm/ADT/APFloat.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
#include "llvm/DebugInfo/PDB/IPDBFrameData.h"
@@ -28,6 +29,7 @@ class IPDBDataStream;
class IPDBInjectedSource;
class IPDBLineNumber;
class IPDBSectionContrib;
+class IPDBSession;
class IPDBSourceFile;
class IPDBTable;
class PDBSymDumper;
@@ -463,6 +465,88 @@ struct Variant {
char *String;
} Value;
+ bool isIntegralType() const {
+ switch (Type) {
+ case Bool:
+ case Int8:
+ case Int16:
+ case Int32:
+ case Int64:
+ case UInt8:
+ case UInt16:
+ case UInt32:
+ case UInt64:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+#define VARIANT_WIDTH(Enum, NumBits) \
+ case PDB_VariantType::Enum: \
+ return NumBits;
+
+ unsigned getBitWidth() const {
+ switch (Type) {
+ VARIANT_WIDTH(Bool, 1u)
+ VARIANT_WIDTH(Int8, 8u)
+ VARIANT_WIDTH(Int16, 16u)
+ VARIANT_WIDTH(Int32, 32u)
+ VARIANT_WIDTH(Int64, 64u)
+ VARIANT_WIDTH(Single, 32u)
+ VARIANT_WIDTH(Double, 64u)
+ VARIANT_WIDTH(UInt8, 8u)
+ VARIANT_WIDTH(UInt16, 16u)
+ VARIANT_WIDTH(UInt32, 32u)
+ VARIANT_WIDTH(UInt64, 64u)
+ default:
+ assert(false && "Variant::toAPSInt called on non-numeric type");
+ return 0u;
+ }
+ }
+
+#undef VARIANT_WIDTH
+
+#define VARIANT_APSINT(Enum, NumBits, IsUnsigned) \
+ case PDB_VariantType::Enum: \
+ return APSInt(APInt(NumBits, Value.Enum), IsUnsigned);
+
+ APSInt toAPSInt() const {
+ switch (Type) {
+ VARIANT_APSINT(Bool, 1u, true)
+ VARIANT_APSINT(Int8, 8u, false)
+ VARIANT_APSINT(Int16, 16u, false)
+ VARIANT_APSINT(Int32, 32u, false)
+ VARIANT_APSINT(Int64, 64u, false)
+ VARIANT_APSINT(UInt8, 8u, true)
+ VARIANT_APSINT(UInt16, 16u, true)
+ VARIANT_APSINT(UInt32, 32u, true)
+ VARIANT_APSINT(UInt64, 64u, true)
+ default:
+ assert(false && "Variant::toAPSInt called on non-integral type");
+ return APSInt();
+ }
+ }
+
+#undef VARIANT_APSINT
+
+ APFloat toAPFloat() const {
+ // Float constants may be tagged as integers.
+ switch (Type) {
+ case PDB_VariantType::Single:
+ case PDB_VariantType::UInt32:
+ case PDB_VariantType::Int32:
+ return APFloat(Value.Single);
+ case PDB_VariantType::Double:
+ case PDB_VariantType::UInt64:
+ case PDB_VariantType::Int64:
+ return APFloat(Value.Double);
+ default:
+ assert(false && "Variant::toAPFloat called on non-floating-point type");
+ return APFloat::getZero(APFloat::IEEEsingle());
+ }
+ }
+
#define VARIANT_EQUAL_CASE(Enum) \
case PDB_VariantType::Enum: \
return Value.Enum == Other.Value.Enum;
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index db7a61a8f160..3d7e06992182 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -14,13 +14,14 @@
#ifndef LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
#define LLVM_DEBUGINFO_SYMBOLIZE_DIPRINTER_H
-#include "llvm/Support/raw_ostream.h"
+#include <string>
namespace llvm {
struct DILineInfo;
class DIInliningInfo;
struct DIGlobal;
struct DILocal;
+class raw_ostream;
namespace symbolize {
@@ -34,7 +35,6 @@ private:
bool PrintPretty;
int PrintSourceContext;
bool Verbose;
- bool Basenames;
OutputStyle Style;
void print(const DILineInfo &Info, bool Inlined);
@@ -43,11 +43,10 @@ private:
public:
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
bool PrintPretty = false, int PrintSourceContext = 0,
- bool Verbose = false, bool Basenames = false,
- OutputStyle Style = OutputStyle::LLVM)
+ bool Verbose = false, OutputStyle Style = OutputStyle::LLVM)
: OS(OS), PrintFunctionNames(PrintFunctionNames),
PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext),
- Verbose(Verbose), Basenames(Basenames), Style(Style) {}
+ Verbose(Verbose), Style(Style) {}
DIPrinter &operator<<(const DILineInfo &Info);
DIPrinter &operator<<(const DIInliningInfo &Info);
@@ -58,4 +57,3 @@ public:
}
#endif
-
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
index 506ecc424b4c..51e92b83eadb 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
@@ -25,11 +25,12 @@ public:
virtual ~SymbolizableModule() = default;
virtual DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
- FunctionNameKind FNKind,
+ DILineInfoSpecifier LineInfoSpecifier,
bool UseSymbolTable) const = 0;
virtual DIInliningInfo
symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
- FunctionNameKind FNKind, bool UseSymbolTable) const = 0;
+ DILineInfoSpecifier LineInfoSpecifier,
+ bool UseSymbolTable) const = 0;
virtual DIGlobal
symbolizeData(object::SectionedAddress ModuleOffset) const = 0;
virtual std::vector<DILocal>
diff --git a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 8bfa5432b811..085e4bb4ccb8 100644
--- a/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/contrib/llvm-project/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -32,15 +32,18 @@ namespace symbolize {
using namespace object;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
+using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
class LLVMSymbolizer {
public:
struct Options {
FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName;
+ FileLineInfoKind PathStyle = FileLineInfoKind::AbsoluteFilePath;
bool UseSymbolTable = true;
bool Demangle = true;
bool RelativeAddresses = false;
bool UntagAddresses = false;
+ bool UseNativePDBReader = false;
std::string DefaultArch;
std::vector<std::string> DsymHints;
std::string FallbackDebugPath;
@@ -114,7 +117,8 @@ private:
Expected<ObjectFile *> getOrCreateObject(const std::string &Path,
const std::string &ArchName);
- std::map<std::string, std::unique_ptr<SymbolizableModule>> Modules;
+ std::map<std::string, std::unique_ptr<SymbolizableModule>, std::less<>>
+ Modules;
/// Contains cached results of getOrCreateObjectPair().
std::map<std::pair<std::string, std::string>, ObjectPair>
diff --git a/contrib/llvm-project/llvm/include/llvm/Demangle/Demangle.h b/contrib/llvm-project/llvm/include/llvm/Demangle/Demangle.h
index 7b85b9a9ccf7..b4006a067d10 100644
--- a/contrib/llvm-project/llvm/include/llvm/Demangle/Demangle.h
+++ b/contrib/llvm-project/llvm/include/llvm/Demangle/Demangle.h
@@ -40,7 +40,21 @@ enum MSDemangleFlags {
MSDF_NoReturnType = 1 << 3,
MSDF_NoMemberType = 1 << 4,
};
-char *microsoftDemangle(const char *mangled_name, char *buf, size_t *n,
+
+/// Demangles the Microsoft symbol pointed at by mangled_name and returns it.
+/// Returns a pointer to the start of a null-terminated demangled string on
+/// success, or nullptr on error.
+/// If n_read is non-null and demangling was successful, it receives how many
+/// bytes of the input string were consumed.
+/// buf can point to a *n_buf bytes large buffer where the demangled name is
+/// stored. If the buffer is too small, it is grown with realloc(). If buf is
+/// nullptr, then this malloc()s memory for the result.
+/// *n_buf stores the size of buf on input if buf is non-nullptr, and it
+/// receives the size of the demangled string on output if n_buf is not nullptr.
+/// status receives one of the demangle_ enum entries above if it's not nullptr.
+/// Flags controls various details of the demangled representation.
+char *microsoftDemangle(const char *mangled_name, size_t *n_read,
+ char *buf, size_t *n_buf,
int *status, MSDemangleFlags Flags = MSDF_None);
/// Attempt to demangle a string using different demangling schemes.
diff --git a/contrib/llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h b/contrib/llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h
index 376e0efea423..6ab873218386 100644
--- a/contrib/llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/contrib/llvm-project/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -98,7 +98,7 @@
X(BoolExpr) \
X(StringLiteral) \
X(LambdaExpr) \
- X(IntegerCastExpr) \
+ X(EnumLiteral) \
X(IntegerLiteral) \
X(FloatLiteral) \
X(DoubleLiteral) \
@@ -2036,22 +2036,26 @@ public:
}
};
-class IntegerCastExpr : public Node {
+class EnumLiteral : public Node {
// ty(integer)
const Node *Ty;
StringView Integer;
public:
- IntegerCastExpr(const Node *Ty_, StringView Integer_)
- : Node(KIntegerCastExpr), Ty(Ty_), Integer(Integer_) {}
+ EnumLiteral(const Node *Ty_, StringView Integer_)
+ : Node(KEnumLiteral), Ty(Ty_), Integer(Integer_) {}
template<typename Fn> void match(Fn F) const { F(Ty, Integer); }
void printLeft(OutputStream &S) const override {
- S += "(";
+ S << "(";
Ty->print(S);
- S += ")";
- S += Integer;
+ S << ")";
+
+ if (Integer[0] == 'n')
+ S << "-" << Integer.dropFront(1);
+ else
+ S << Integer;
}
};
@@ -4064,8 +4068,11 @@ Qualifiers AbstractManglingParser<Alloc, Derived>::parseCVQualifiers() {
// ::= fp <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> _ # L > 0, first parameter
// ::= fL <L-1 non-negative number> p <top-level CV-Qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
+// ::= fpT # 'this' expression (not part of standard?)
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseFunctionParam() {
+ if (consumeIf("fpT"))
+ return make<NameType>("this");
if (consumeIf("fp")) {
parseCVQualifiers();
StringView Num = parseNumber();
@@ -4225,7 +4232,13 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
return getDerived().template parseFloatingLiteral<double>();
case 'e':
++First;
+#if defined(__powerpc__) || defined(__s390__)
+ // Handle cases where long doubles encoded with e have the same size
+ // and representation as doubles.
+ return getDerived().template parseFloatingLiteral<double>();
+#else
return getDerived().template parseFloatingLiteral<long double>();
+#endif
case '_':
if (consumeIf("_Z")) {
Node *R = getDerived().parseEncoding();
@@ -4264,12 +4277,12 @@ Node *AbstractManglingParser<Derived, Alloc>::parseExprPrimary() {
Node *T = getDerived().parseType();
if (T == nullptr)
return nullptr;
- StringView N = parseNumber();
+ StringView N = parseNumber(/*AllowNegative=*/true);
if (N.empty())
return nullptr;
if (!consumeIf('E'))
return nullptr;
- return make<IntegerCastExpr>(T, N);
+ return make<EnumLiteral>(T, N);
}
}
}
@@ -5083,6 +5096,22 @@ Node *AbstractManglingParser<Derived, Alloc>::parseSpecialName() {
// ::= <special-name>
template <typename Derived, typename Alloc>
Node *AbstractManglingParser<Derived, Alloc>::parseEncoding() {
+ // The template parameters of an encoding are unrelated to those of the
+ // enclosing context.
+ class SaveTemplateParams {
+ AbstractManglingParser *Parser;
+ decltype(TemplateParams) OldParams;
+
+ public:
+ SaveTemplateParams(AbstractManglingParser *Parser) : Parser(Parser) {
+ OldParams = std::move(Parser->TemplateParams);
+ Parser->TemplateParams.clear();
+ }
+ ~SaveTemplateParams() {
+ Parser->TemplateParams = std::move(OldParams);
+ }
+ } SaveTemplateParams(this);
+
if (look() == 'G' || look() == 'T')
return getDerived().parseSpecialName();
diff --git a/contrib/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h b/contrib/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
index ec40eec5a05e..62e0f4765a69 100644
--- a/contrib/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Demangle/MicrosoftDemangleNodes.h
@@ -313,8 +313,8 @@ struct PrimitiveTypeNode : public TypeNode {
explicit PrimitiveTypeNode(PrimitiveKind K)
: TypeNode(NodeKind::PrimitiveType), PrimKind(K) {}
- void outputPre(OutputStream &OS, OutputFlags Flags) const;
- void outputPost(OutputStream &OS, OutputFlags Flags) const {}
+ void outputPre(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPost(OutputStream &OS, OutputFlags Flags) const override {}
PrimitiveKind PrimKind;
};
@@ -474,8 +474,8 @@ struct PointerTypeNode : public TypeNode {
struct TagTypeNode : public TypeNode {
explicit TagTypeNode(TagKind Tag) : TypeNode(NodeKind::TagType), Tag(Tag) {}
- void outputPre(OutputStream &OS, OutputFlags Flags) const;
- void outputPost(OutputStream &OS, OutputFlags Flags) const;
+ void outputPre(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPost(OutputStream &OS, OutputFlags Flags) const override;
QualifiedNameNode *QualifiedName = nullptr;
TagKind Tag;
@@ -484,8 +484,8 @@ struct TagTypeNode : public TypeNode {
struct ArrayTypeNode : public TypeNode {
ArrayTypeNode() : TypeNode(NodeKind::ArrayType) {}
- void outputPre(OutputStream &OS, OutputFlags Flags) const;
- void outputPost(OutputStream &OS, OutputFlags Flags) const;
+ void outputPre(OutputStream &OS, OutputFlags Flags) const override;
+ void outputPost(OutputStream &OS, OutputFlags Flags) const override;
void outputDimensionsImpl(OutputStream &OS, OutputFlags Flags) const;
void outputOneDimension(OutputStream &OS, OutputFlags Flags, Node *N) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
index 4fb6dad96387..2562da7cf60b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -158,6 +158,8 @@ protected:
/// getMangledName - Get mangled name.
std::string getMangledName(const GlobalValue *GV);
+ std::string ErrMsg;
+
public:
/// lock - This lock protects the ExecutionEngine and MCJIT classes. It must
/// be held while changing the internal state of any of those classes.
@@ -275,8 +277,20 @@ public:
/// object have been relocated using mapSectionAddress. When this method is
/// called the MCJIT execution engine will reapply relocations for a loaded
/// object. This method has no effect for the interpeter.
+ ///
+ /// Returns true on success, false on failure. Error messages can be retrieved
+ /// by calling getError();
virtual void finalizeObject() {}
+ /// Returns true if an error has been recorded.
+ bool hasError() const { return !ErrMsg.empty(); }
+
+ /// Clear the error message.
+ void clearErrorMessage() { ErrMsg.clear(); }
+
+ /// Returns the most recent error message.
+ const std::string &getErrorMessage() const { return ErrMsg; }
+
/// runStaticConstructorsDestructors - This method is used to execute all of
/// the static constructors or destructors for a program.
///
@@ -499,7 +513,7 @@ protected:
void emitGlobals();
- void EmitGlobalVariable(const GlobalVariable *GV);
+ void emitGlobalVariable(const GlobalVariable *GV);
GenericValue getConstantValue(const Constant *C);
void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
new file mode 100644
index 000000000000..9f6ea5271f4b
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF.h
@@ -0,0 +1,31 @@
+//===------- ELF.h - Generic JIT link function for ELF ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic jit-link functions for ELF.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_ELF_H
+#define LLVM_EXECUTIONENGINE_JITLINK_ELF_H
+
+#include "llvm/ExecutionEngine/JITLink/ELF.h"
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+
+namespace llvm {
+namespace jitlink {
+
+/// jit-link the given ObjBuffer, which must be a ELF object file.
+///
+/// Uses conservative defaults for GOT and stub handling based on the target
+/// platform.
+void jitLink_ELF(std::unique_ptr<JITLinkContext> Ctx);
+
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_ELF_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
new file mode 100644
index 000000000000..7860088f3569
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/ELF_x86_64.h
@@ -0,0 +1,52 @@
+//===--- ELF_x86_64.h - JIT link functions for ELF/x86-64 ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// jit-link functions for ELF/x86-64.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITLINK_ELF_X86_64_H
+#define LLVM_EXECUTIONENGINE_JITLINK_ELF_X86_64_H
+
+#include "llvm/ExecutionEngine/JITLink/JITLink.h"
+
+namespace llvm {
+namespace jitlink {
+
+namespace ELF_x86_64_Edges {
+enum ELFX86RelocationKind : Edge::Kind {
+ Branch32 = Edge::FirstRelocation,
+ Branch32ToStub,
+ Pointer32,
+ Pointer64,
+ Pointer64Anon,
+ PCRel32,
+ PCRel32Minus1,
+ PCRel32Minus2,
+ PCRel32Minus4,
+ PCRel32Anon,
+ PCRel32Minus1Anon,
+ PCRel32Minus2Anon,
+ PCRel32Minus4Anon,
+ PCRel32GOTLoad,
+ PCRel32GOT,
+ PCRel32TLV,
+ Delta32,
+ Delta64,
+ NegDelta32,
+ NegDelta64,
+};
+
+} // end namespace ELF_x86_64_Edges
+
+/// jit-link the given object buffer, which must be a ELF x86-64 object file.
+void jitLink_ELF_x86_64(std::unique_ptr<JITLinkContext> Ctx);
+} // end namespace jitlink
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_JITLINK_ELF_X86_64_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
index fa04653fa7bd..76f9dea4160f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Allocator.h"
@@ -247,8 +248,8 @@ public:
bool edges_empty() const { return Edges.empty(); }
/// Remove the edge pointed to by the given iterator.
- /// Invalidates all iterators that point to or past the given one.
- void removeEdge(const_edge_iterator I) { Edges.erase(I); }
+ /// Returns an iterator to the new next element.
+ edge_iterator removeEdge(edge_iterator I) { return Edges.erase(I); }
private:
static constexpr uint64_t MaxAlignmentOffset = (1ULL << 57) - 1;
@@ -351,7 +352,8 @@ private:
JITTargetAddress Size, bool IsCallable,
bool IsLive) {
assert(SymStorage && "Storage cannot be null");
- assert(Offset < Base.getSize() && "Symbol offset is outside block");
+ assert((Offset + Size) <= Base.getSize() &&
+ "Symbol extends past end of block");
auto *Sym = reinterpret_cast<Symbol *>(SymStorage);
new (Sym) Symbol(Base, Offset, StringRef(), Size, Linkage::Strong,
Scope::Local, IsLive, IsCallable);
@@ -363,7 +365,8 @@ private:
JITTargetAddress Size, Linkage L, Scope S,
bool IsLive, bool IsCallable) {
assert(SymStorage && "Storage cannot be null");
- assert(Offset < Base.getSize() && "Symbol offset is outside block");
+ assert((Offset + Size) <= Base.getSize() &&
+ "Symbol extends past end of block");
assert(!Name.empty() && "Name cannot be empty");
auto *Sym = reinterpret_cast<Symbol *>(SymStorage);
new (Sym) Symbol(Base, Offset, Name, Size, L, S, IsLive, IsCallable);
@@ -487,6 +490,8 @@ public:
/// Set the visibility for this Symbol.
void setScope(Scope S) {
+ assert((!Name.empty() || S == Scope::Local) &&
+ "Can not set anonymous symbol to non-local scope");
assert((S == Scope::Default || Base->isDefined() || Base->isAbsolute()) &&
"Invalid visibility for symbol type");
this->S = static_cast<uint8_t>(S);
@@ -990,6 +995,11 @@ public:
/// Remove a block.
void removeBlock(Block &B) {
+ assert(llvm::none_of(B.getSection().symbols(),
+ [&](const Symbol *Sym) {
+ return &Sym->getBlock() == &B;
+ }) &&
+ "Block still has symbols attached");
B.getSection().removeBlock(B);
destroyBlock(B);
}
@@ -1168,7 +1178,7 @@ struct PassConfiguration {
/// Pre-prune passes.
///
/// These passes are called on the graph after it is built, and before any
- /// symbols have been pruned.
+ /// symbols have been pruned. Graph nodes still have their original vmaddrs.
///
/// Notable use cases: Marking symbols live or should-discard.
LinkGraphPassList PrePrunePasses;
@@ -1176,15 +1186,26 @@ struct PassConfiguration {
/// Post-prune passes.
///
/// These passes are called on the graph after dead stripping, but before
- /// fixups are applied.
+ /// memory is allocated or nodes assigned their final addresses.
///
/// Notable use cases: Building GOT, stub, and TLV symbols.
LinkGraphPassList PostPrunePasses;
+ /// Pre-fixup passes.
+ ///
+ /// These passes are called on the graph after memory has been allocated,
+ /// content copied into working memory, and nodes have been assigned their
+ /// final addresses.
+ ///
+ /// Notable use cases: Late link-time optimizations like GOT and stub
+ /// elimination.
+ LinkGraphPassList PostAllocationPasses;
+
/// Post-fixup passes.
///
/// These passes are called on the graph after block contents has been copied
- /// to working memory, and fixups applied.
+ /// to working memory, and fixups applied. Graph nodes have been updated to
+ /// their final target vmaddrs.
///
/// Notable use cases: Testing and validation.
LinkGraphPassList PostFixupPasses;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
index ac5a593bb77b..0c8514a60a50 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h
@@ -17,7 +17,10 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Memory.h"
+#include "llvm/Support/MSVCErrorWorkarounds.h"
+
#include <cstdint>
+#include <future>
namespace llvm {
namespace jitlink {
@@ -74,6 +77,15 @@ public:
/// working memory.
virtual void finalizeAsync(FinalizeContinuation OnFinalize) = 0;
+ /// Calls finalizeAsync and waits for completion.
+ Error finalize() {
+ std::promise<MSVCPError> FinalizeResultP;
+ auto FinalizeResultF = FinalizeResultP.get_future();
+ finalizeAsync(
+ [&](Error Err) { FinalizeResultP.set_value(std::move(Err)); });
+ return FinalizeResultF.get();
+ }
+
/// Should deallocate target memory.
virtual Error deallocate() = 0;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
index 00a7feb86e83..27fcdf4fa990 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITLink/MachO_x86_64.h
@@ -22,6 +22,7 @@ namespace MachO_x86_64_Edges {
enum MachOX86RelocationKind : Edge::Kind {
Branch32 = Edge::FirstRelocation,
+ Branch32ToStub,
Pointer32,
Pointer64,
Pointer64Anon,
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
index 7a2a6cfa5203..6f0030a18f47 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/JITSymbol.h
@@ -30,6 +30,7 @@
namespace llvm {
class GlobalValue;
+class GlobalValueSummary;
namespace object {
@@ -58,10 +59,9 @@ template <typename T> T jitTargetAddressToPointer(JITTargetAddress Addr) {
/// Casts the given address to a callable function pointer. This operation
/// will perform pointer signing for platforms that require it (e.g. arm64e).
template <typename T> T jitTargetAddressToFunction(JITTargetAddress Addr) {
- static_assert(
- std::is_pointer<T>::value &&
- std::is_function<typename std::remove_pointer<T>::type>::value,
- "T must be a function pointer type");
+ static_assert(std::is_pointer<T>::value &&
+ std::is_function<std::remove_pointer_t<T>>::value,
+ "T must be a function pointer type");
return jitTargetAddressToPointer<T>(Addr);
}
@@ -84,7 +84,9 @@ public:
Absolute = 1U << 3,
Exported = 1U << 4,
Callable = 1U << 5,
- LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Callable)
+ MaterializationSideEffectsOnly = 1U << 6,
+ LLVM_MARK_AS_BITMASK_ENUM( // LargestValue =
+ MaterializationSideEffectsOnly)
};
/// Default-construct a JITSymbolFlags instance.
@@ -146,6 +148,21 @@ public:
/// Returns true if the given symbol is known to be callable.
bool isCallable() const { return (Flags & Callable) == Callable; }
+ /// Returns true if this symbol is a materialization-side-effects-only
+ /// symbol. Such symbols do not have a real address. They exist to trigger
+ /// and support synchronization of materialization side effects, e.g. for
+ /// collecting initialization information. These symbols will vanish from
+ /// the symbol table immediately upon reaching the ready state, and will
+ /// appear to queries as if they were never defined (except that query
+ /// callback execution will be delayed until they reach the ready state).
+ /// MaterializationSideEffectOnly symbols should only be queried using the
+ /// SymbolLookupFlags::WeaklyReferencedSymbol flag (see
+ /// llvm/include/llvm/ExecutionEngine/Orc/Core.h).
+ bool hasMaterializationSideEffectsOnly() const {
+ return (Flags & MaterializationSideEffectsOnly) ==
+ MaterializationSideEffectsOnly;
+ }
+
/// Get the underlying flags value as an integer.
UnderlyingType getRawFlagsValue() const {
return static_cast<UnderlyingType>(Flags);
@@ -161,6 +178,10 @@ public:
/// value.
static JITSymbolFlags fromGlobalValue(const GlobalValue &GV);
+ /// Construct a JITSymbolFlags value based on the flags of the given global
+ /// value summary.
+ static JITSymbolFlags fromSummary(GlobalValueSummary *S);
+
/// Construct a JITSymbolFlags value based on the flags of the given libobject
/// symbol.
static Expected<JITSymbolFlags>
@@ -216,6 +237,13 @@ public:
JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
: Address(Address), Flags(Flags) {}
+ /// Create a symbol from the given pointer with the given flags.
+ template <typename T>
+ static JITEvaluatedSymbol
+ fromPointer(T *P, JITSymbolFlags Flags = JITSymbolFlags::Exported) {
+ return JITEvaluatedSymbol(pointerToJITTargetAddress(P), Flags);
+ }
+
/// An evaluated symbol converts to 'true' if its address is non-zero.
explicit operator bool() const { return Address != 0; }
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ObjectCache.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ObjectCache.h
index 47e94f18a1c7..1c72ca39f7c1 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ObjectCache.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/ObjectCache.h
@@ -9,11 +9,12 @@
#ifndef LLVM_EXECUTIONENGINE_OBJECTCACHE_H
#define LLVM_EXECUTIONENGINE_OBJECTCACHE_H
-#include "llvm/Support/MemoryBuffer.h"
#include <memory>
namespace llvm {
+class MemoryBuffer;
+class MemoryBufferRef;
class Module;
/// This is the base ObjectCache type which can be provided to an
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 7946b5b7b209..9ecc0464dec1 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -18,7 +18,6 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
@@ -94,6 +93,7 @@ public:
/// Sets the ImplSymbolMap
void setImplMap(ImplSymbolMap *Imp);
+
/// Emits the given module. This should not be called by clients: it will be
/// called by the JIT when a definition added via the add method is requested.
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
@@ -338,12 +338,13 @@ public:
for (auto &KV : LogicalDylibs) {
if (auto Sym = KV.second.StubsMgr->findStub(Name, ExportedSymbolsOnly))
return Sym;
- if (auto Sym = findSymbolIn(KV.first, Name, ExportedSymbolsOnly))
+ if (auto Sym =
+ findSymbolIn(KV.first, std::string(Name), ExportedSymbolsOnly))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
}
- return BaseLayer.findSymbol(Name, ExportedSymbolsOnly);
+ return BaseLayer.findSymbol(std::string(Name), ExportedSymbolsOnly);
}
/// Get the address of a symbol provided by this layer, or some layer
@@ -392,50 +393,49 @@ private:
// Create stub functions.
const DataLayout &DL = SrcM.getDataLayout();
- {
- typename IndirectStubsMgrT::StubInitsMap StubInits;
- for (auto &F : SrcM) {
- // Skip declarations.
- if (F.isDeclaration())
- continue;
- // Skip weak functions for which we already have definitions.
- auto MangledName = mangle(F.getName(), DL);
- if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
- if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
- continue;
- else if (auto Err = Sym.takeError())
- return std::move(Err);
- }
+ typename IndirectStubsMgrT::StubInitsMap StubInits;
+ for (auto &F : SrcM) {
+ // Skip declarations.
+ if (F.isDeclaration())
+ continue;
- // Record all functions defined by this module.
- if (CloneStubsIntoPartitions)
- LD.getStubsToClone(LMId).insert(&F);
-
- // Create a callback, associate it with the stub for the function,
- // and set the compile action to compile the partition containing the
- // function.
- auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
- if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
- return *FnImplAddrOrErr;
- else {
- // FIXME: Report error, return to 'abort' or something similar.
- consumeError(FnImplAddrOrErr.takeError());
- return 0;
- }
- };
- if (auto CCAddr =
- CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
- StubInits[MangledName] =
- std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
- else
- return CCAddr.takeError();
+ // Skip weak functions for which we already have definitions.
+ auto MangledName = mangle(F.getName(), DL);
+ if (F.hasWeakLinkage() || F.hasLinkOnceLinkage()) {
+ if (auto Sym = LD.findSymbol(BaseLayer, MangledName, false))
+ continue;
+ else if (auto Err = Sym.takeError())
+ return Err;
}
- if (auto Err = LD.StubsMgr->createStubs(StubInits))
- return Err;
+ // Record all functions defined by this module.
+ if (CloneStubsIntoPartitions)
+ LD.getStubsToClone(LMId).insert(&F);
+
+ // Create a callback, associate it with the stub for the function,
+ // and set the compile action to compile the partition containing the
+ // function.
+ auto CompileAction = [this, &LD, LMId, &F]() -> JITTargetAddress {
+ if (auto FnImplAddrOrErr = this->extractAndCompile(LD, LMId, F))
+ return *FnImplAddrOrErr;
+ else {
+ // FIXME: Report error, return to 'abort' or something similar.
+ consumeError(FnImplAddrOrErr.takeError());
+ return 0;
+ }
+ };
+ if (auto CCAddr =
+ CompileCallbackMgr.getCompileCallback(std::move(CompileAction)))
+ StubInits[MangledName] =
+ std::make_pair(*CCAddr, JITSymbolFlags::fromGlobalValue(F));
+ else
+ return CCAddr.takeError();
}
+ if (auto Err = LD.StubsMgr->createStubs(StubInits))
+ return Err;
+
// If this module doesn't contain any globals, aliases, or module flags then
// we can bail out early and avoid the overhead of creating and managing an
// empty globals module.
@@ -511,11 +511,11 @@ private:
}
// Build a resolver for the globals module and add it to the base layer.
- auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
+ auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol {
if (auto Sym = LD.StubsMgr->findStub(Name, false))
return Sym;
- if (auto Sym = LD.findSymbol(BaseLayer, Name, false))
+ if (auto Sym = LD.findSymbol(BaseLayer, std::string(Name), false))
return Sym;
else if (auto Err = Sym.takeError())
return std::move(Err);
@@ -631,7 +631,7 @@ private:
Module &SrcM = LD.getSourceModule(LMId);
// Create the module.
- std::string NewName = SrcM.getName();
+ std::string NewName(SrcM.getName());
for (auto *F : Part) {
NewName += ".";
NewName += F->getName();
@@ -688,8 +688,8 @@ private:
auto K = ES.allocateVModule();
- auto LegacyLookup = [this, &LD](const std::string &Name) -> JITSymbol {
- return LD.findSymbol(BaseLayer, Name, false);
+ auto LegacyLookup = [this, &LD](StringRef Name) -> JITSymbol {
+ return LD.findSymbol(BaseLayer, std::string(Name), false);
};
// Create memory manager and symbol resolver.
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
index 218afda1b546..8376d163d57a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/CompileUtils.h
@@ -30,7 +30,7 @@ namespace orc {
class JITTargetMachineBuilder;
-IRMaterializationUnit::ManglingOptions
+IRSymbolMapper::ManglingOptions
irManglingOptionsFromTargetOptions(const TargetOptions &Opts);
/// Simple compile functor: Takes a single IR module and returns an ObjectFile.
@@ -52,7 +52,7 @@ public:
Expected<CompileResult> operator()(Module &M) override;
private:
- IRMaterializationUnit::ManglingOptions
+ IRSymbolMapper::ManglingOptions
manglingOptionsForTargetMachine(const TargetMachine &TM);
CompileResult tryToLoadFromObjectCache(const Module &M);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
index ecba454887b3..a117acefd2d3 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Core.h
@@ -14,18 +14,16 @@
#define LLVM_EXECUTIONENGINE_ORC_CORE_H
#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/OrcV1Deprecation.h"
-#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include <memory>
#include <vector>
-#define DEBUG_TYPE "orc"
-
namespace llvm {
namespace orc {
@@ -202,10 +200,10 @@ public:
/// If Body returns true then the element just passed in is removed from the
/// set. If Body returns false then the element is retained.
template <typename BodyFn>
- auto forEachWithRemoval(BodyFn &&Body) -> typename std::enable_if<
+ auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
- bool>::value>::type {
+ bool>::value> {
UnderlyingVector::size_type I = 0;
while (I != Symbols.size()) {
const auto &Name = Symbols[I].first;
@@ -224,11 +222,11 @@ public:
/// returns true then the element just passed in is removed from the set. If
/// Body returns false then the element is retained.
template <typename BodyFn>
- auto forEachWithRemoval(BodyFn &&Body) -> typename std::enable_if<
+ auto forEachWithRemoval(BodyFn &&Body) -> std::enable_if_t<
std::is_same<decltype(Body(std::declval<const SymbolStringPtr &>(),
std::declval<SymbolLookupFlags>())),
Expected<bool>>::value,
- Error>::type {
+ Error> {
UnderlyingVector::size_type I = 0;
while (I != Symbols.size()) {
const auto &Name = Symbols[I].first;
@@ -309,66 +307,6 @@ struct SymbolAliasMapEntry {
/// A map of Symbols to (Symbol, Flags) pairs.
using SymbolAliasMap = DenseMap<SymbolStringPtr, SymbolAliasMapEntry>;
-/// Render a SymbolStringPtr.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
-
-/// Render a SymbolNameSet.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
-
-/// Render a SymbolNameVector.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols);
-
-/// Render a SymbolFlagsMap entry.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV);
-
-/// Render a SymbolMap entry.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV);
-
-/// Render a SymbolFlagsMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags);
-
-/// Render a SymbolMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols);
-
-/// Render a SymbolDependenceMap entry.
-raw_ostream &operator<<(raw_ostream &OS,
- const SymbolDependenceMap::value_type &KV);
-
-/// Render a SymbolDependendeMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
-
-/// Render a MaterializationUnit.
-raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
-
-//// Render a JITDylibLookupFlags instance.
-raw_ostream &operator<<(raw_ostream &OS,
- const JITDylibLookupFlags &JDLookupFlags);
-
-/// Rendar a SymbolLookupFlags instance.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags);
-
-/// Render a JITDylibLookupFlags instance.
-raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
-
-/// Render a SymbolLookupSet entry.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet::value_type &KV);
-
-/// Render a SymbolLookupSet.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet);
-
-/// Render a JITDylibSearchOrder.
-raw_ostream &operator<<(raw_ostream &OS,
- const JITDylibSearchOrder &SearchOrder);
-
-/// Render a SymbolAliasMap.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
-
-/// Render a SymbolState.
-raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
-
-/// Render a LookupKind.
-raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
-
/// Callback to notify client that symbols have been resolved.
using SymbolsResolvedCallback = unique_function<void(Expected<SymbolMap>)>;
@@ -424,6 +362,44 @@ private:
SymbolNameSet Symbols;
};
+/// Errors of this type should be returned if a module fails to include
+/// definitions that are claimed by the module's associated
+/// MaterializationResponsibility. If this error is returned it is indicative of
+/// a broken transformation / compiler / object cache.
+class MissingSymbolDefinitions : public ErrorInfo<MissingSymbolDefinitions> {
+public:
+ static char ID;
+
+ MissingSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols)
+ : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {}
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getModuleName() const { return ModuleName; }
+ const SymbolNameVector &getSymbols() const { return Symbols; }
+private:
+ std::string ModuleName;
+ SymbolNameVector Symbols;
+};
+
+/// Errors of this type should be returned if a module contains definitions for
+/// symbols that are not claimed by the module's associated
+/// MaterializationResponsibility. If this error is returned it is indicative of
+/// a broken transformation / compiler / object cache.
+class UnexpectedSymbolDefinitions : public ErrorInfo<UnexpectedSymbolDefinitions> {
+public:
+ static char ID;
+
+ UnexpectedSymbolDefinitions(std::string ModuleName, SymbolNameVector Symbols)
+ : ModuleName(std::move(ModuleName)), Symbols(std::move(Symbols)) {}
+ std::error_code convertToErrorCode() const override;
+ void log(raw_ostream &OS) const override;
+ const std::string &getModuleName() const { return ModuleName; }
+ const SymbolNameVector &getSymbols() const { return Symbols; }
+private:
+ std::string ModuleName;
+ SymbolNameVector Symbols;
+};
+
/// Tracks responsibility for materialization, and mediates interactions between
/// MaterializationUnits and JDs.
///
@@ -445,7 +421,7 @@ public:
/// Returns the target JITDylib that these symbols are being materialized
/// into.
- JITDylib &getTargetJITDylib() const { return JD; }
+ JITDylib &getTargetJITDylib() const { return *JD; }
/// Returns the VModuleKey for this instance.
VModuleKey getVModuleKey() const { return K; }
@@ -456,6 +432,11 @@ public:
/// before using.
const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
+ /// Returns the initialization pseudo-symbol, if any. This symbol will also
+ /// be present in the SymbolFlagsMap for this MaterializationResponsibility
+ /// object.
+ const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
+
/// Returns the names of any symbols covered by this
/// MaterializationResponsibility object that have queries pending. This
/// information can be used to return responsibility for unrequested symbols
@@ -502,6 +483,20 @@ public:
/// callbacks, metadata).
Error defineMaterializing(SymbolFlagsMap SymbolFlags);
+ /// Define the given symbols as non-existent, removing it from the symbol
+ /// table and notifying any pending queries. Queries that lookup up the
+ /// symbol using the SymbolLookupFlags::WeaklyReferencedSymbol flag will
+ /// behave as if the symbol had not been matched in the first place. Queries
+ /// that required this symbol will fail with a missing symbol definition
+ /// error.
+ ///
+ /// This method is intended to support cleanup of special symbols like
+ /// initializer symbols: Queries using
+ /// SymbolLookupFlags::WeaklyReferencedSymbol can be used to trigger their
+ /// emission, and this method can be used to remove them from the JITDylib
+ /// once materialization is complete.
+ void defineNonExistent(ArrayRef<SymbolStringPtr> Symbols);
+
/// Notify all not-yet-emitted covered by this MaterializationResponsibility
/// instance that an error has occurred.
/// This will remove all symbols covered by this MaterializationResponsibilty
@@ -531,11 +526,18 @@ public:
private:
/// Create a MaterializationResponsibility for the given JITDylib and
/// initial symbols.
- MaterializationResponsibility(JITDylib &JD, SymbolFlagsMap SymbolFlags,
- VModuleKey K);
+ MaterializationResponsibility(std::shared_ptr<JITDylib> JD,
+ SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol, VModuleKey K)
+ : JD(std::move(JD)), SymbolFlags(std::move(SymbolFlags)),
+ InitSymbol(std::move(InitSymbol)), K(std::move(K)) {
+ assert(this->JD && "Cannot initialize with null JD");
+ assert(!this->SymbolFlags.empty() && "Materializing nothing?");
+ }
- JITDylib &JD;
+ std::shared_ptr<JITDylib> JD;
SymbolFlagsMap SymbolFlags;
+ SymbolStringPtr InitSymbol;
VModuleKey K;
};
@@ -548,9 +550,17 @@ private:
/// is requested via the lookup method. The JITDylib will call discard if a
/// stronger definition is added or already present.
class MaterializationUnit {
+ friend class ExecutionSession;
+ friend class JITDylib;
+
public:
- MaterializationUnit(SymbolFlagsMap InitalSymbolFlags, VModuleKey K)
- : SymbolFlags(std::move(InitalSymbolFlags)), K(std::move(K)) {}
+ MaterializationUnit(SymbolFlagsMap InitalSymbolFlags,
+ SymbolStringPtr InitSymbol, VModuleKey K)
+ : SymbolFlags(std::move(InitalSymbolFlags)),
+ InitSymbol(std::move(InitSymbol)), K(std::move(K)) {
+ assert((!this->InitSymbol || this->SymbolFlags.count(this->InitSymbol)) &&
+ "If set, InitSymbol should appear in InitialSymbolFlags map");
+ }
virtual ~MaterializationUnit() {}
@@ -561,13 +571,13 @@ public:
/// Return the set of symbols that this source provides.
const SymbolFlagsMap &getSymbols() const { return SymbolFlags; }
- /// Called by materialization dispatchers (see
- /// ExecutionSession::DispatchMaterializationFunction) to trigger
- /// materialization of this MaterializationUnit.
- void doMaterialize(JITDylib &JD) {
- materialize(MaterializationResponsibility(JD, std::move(SymbolFlags),
- std::move(K)));
- }
+ /// Returns the initialization symbol for this MaterializationUnit (if any).
+ const SymbolStringPtr &getInitializerSymbol() const { return InitSymbol; }
+
+ /// Implementations of this method should materialize all symbols
+ /// in the materialzation unit, except for those that have been
+ /// previously discarded.
+ virtual void materialize(MaterializationResponsibility R) = 0;
/// Called by JITDylibs to notify MaterializationUnits that the given symbol
/// has been overridden.
@@ -578,15 +588,17 @@ public:
protected:
SymbolFlagsMap SymbolFlags;
+ SymbolStringPtr InitSymbol;
VModuleKey K;
private:
virtual void anchor();
- /// Implementations of this method should materialize all symbols
- /// in the materialzation unit, except for those that have been
- /// previously discarded.
- virtual void materialize(MaterializationResponsibility R) = 0;
+ MaterializationResponsibility
+ createMaterializationResponsibility(std::shared_ptr<JITDylib> JD) {
+ return MaterializationResponsibility(std::move(JD), std::move(SymbolFlags),
+ std::move(InitSymbol), K);
+ }
/// Implementations of this method should discard the given symbol
/// from the source (e.g. if the source is an LLVM IR Module and the
@@ -726,15 +738,6 @@ public:
void notifySymbolMetRequiredState(const SymbolStringPtr &Name,
JITEvaluatedSymbol Sym);
- /// Remove a symbol from the query. This is used to drop weakly referenced
- /// symbols that are not found.
- void dropSymbol(const SymbolStringPtr &Name) {
- assert(ResolvedSymbols.count(Name) &&
- "Redundant removal of weakly-referenced symbol");
- ResolvedSymbols.erase(Name);
- --OutstandingSymbolsCount;
- }
-
/// Returns true if all symbols covered by this query have been
/// resolved.
bool isComplete() const { return OutstandingSymbolsCount == 0; }
@@ -752,6 +755,8 @@ private:
void removeQueryDependence(JITDylib &JD, const SymbolStringPtr &Name);
+ void dropSymbol(const SymbolStringPtr &Name);
+
bool canStillFail();
void handleFailed(Error Err);
@@ -771,9 +776,10 @@ private:
/// their addresses may be used as keys for resource management.
/// JITDylib state changes must be made via an ExecutionSession to guarantee
/// that they are synchronized with respect to other JITDylib operations.
-class JITDylib {
+class JITDylib : public std::enable_shared_from_this<JITDylib> {
friend class AsynchronousSymbolQuery;
friend class ExecutionSession;
+ friend class Platform;
friend class MaterializationResponsibility;
public:
/// Definition generators can be attached to JITDylibs to generate new
@@ -822,47 +828,46 @@ public:
/// have been added and not yet removed).
void removeGenerator(DefinitionGenerator &G);
- /// Set the search order to be used when fixing up definitions in JITDylib.
- /// This will replace the previous search order, and apply to any symbol
+ /// Set the link order to be used when fixing up definitions in JITDylib.
+ /// This will replace the previous link order, and apply to any symbol
/// resolutions made for definitions in this JITDylib after the call to
- /// setSearchOrder (even if the definition itself was added before the
+ /// setLinkOrder (even if the definition itself was added before the
/// call).
///
- /// If SearchThisJITDylibFirst is set, which by default it is, then this
- /// JITDylib will add itself to the beginning of the SearchOrder (Clients
- /// should *not* put this JITDylib in the list in this case, to avoid
- /// redundant lookups).
+ /// If LinkAgainstThisJITDylibFirst is true (the default) then this JITDylib
+ /// will add itself to the beginning of the LinkOrder (Clients should not
+ /// put this JITDylib in the list in this case, to avoid redundant lookups).
///
- /// If SearchThisJITDylibFirst is false then the search order will be used as
- /// given. The main motivation for this feature is to support deliberate
+ /// If LinkAgainstThisJITDylibFirst is false then the link order will be used
+ /// as-is. The primary motivation for this feature is to support deliberate
/// shadowing of symbols in this JITDylib by a facade JITDylib. For example,
/// the facade may resolve function names to stubs, and the stubs may compile
/// lazily by looking up symbols in this dylib. Adding the facade dylib
- /// as the first in the search order (instead of this dylib) ensures that
+ /// as the first in the link order (instead of this dylib) ensures that
/// definitions within this dylib resolve to the lazy-compiling stubs,
/// rather than immediately materializing the definitions in this dylib.
- void setSearchOrder(JITDylibSearchOrder NewSearchOrder,
- bool SearchThisJITDylibFirst = true);
+ void setLinkOrder(JITDylibSearchOrder NewSearchOrder,
+ bool LinkAgainstThisJITDylibFirst = true);
- /// Add the given JITDylib to the search order for definitions in this
+ /// Add the given JITDylib to the link order for definitions in this
/// JITDylib.
- void addToSearchOrder(JITDylib &JD,
- JITDylibLookupFlags JDLookupFlags =
- JITDylibLookupFlags::MatchExportedSymbolsOnly);
+ void addToLinkOrder(JITDylib &JD,
+ JITDylibLookupFlags JDLookupFlags =
+ JITDylibLookupFlags::MatchExportedSymbolsOnly);
- /// Replace OldJD with NewJD in the search order if OldJD is present.
+ /// Replace OldJD with NewJD in the link order if OldJD is present.
/// Otherwise this operation is a no-op.
- void replaceInSearchOrder(JITDylib &OldJD, JITDylib &NewJD,
- JITDylibLookupFlags JDLookupFlags =
- JITDylibLookupFlags::MatchExportedSymbolsOnly);
+ void replaceInLinkOrder(JITDylib &OldJD, JITDylib &NewJD,
+ JITDylibLookupFlags JDLookupFlags =
+ JITDylibLookupFlags::MatchExportedSymbolsOnly);
- /// Remove the given JITDylib from the search order for this JITDylib if it is
+ /// Remove the given JITDylib from the link order for this JITDylib if it is
/// present. Otherwise this operation is a no-op.
- void removeFromSearchOrder(JITDylib &JD);
+ void removeFromLinkOrder(JITDylib &JD);
- /// Do something with the search order (run under the session lock).
+ /// Do something with the link order (run under the session lock).
template <typename Func>
- auto withSearchOrderDo(Func &&F)
+ auto withLinkOrderDo(Func &&F)
-> decltype(F(std::declval<const JITDylibSearchOrder &>()));
/// Define all symbols provided by the materialization unit to be part of this
@@ -961,11 +966,6 @@ private:
JITSymbolFlags getFlags() const { return Flags; }
SymbolState getState() const { return static_cast<SymbolState>(State); }
- bool isInMaterializationPhase() const {
- return getState() == SymbolState::Materializing ||
- getState() == SymbolState::Resolved;
- }
-
bool hasMaterializerAttached() const { return MaterializerAttached; }
bool isPendingRemoval() const { return PendingRemoval; }
@@ -1047,11 +1047,41 @@ private:
ExecutionSession &ES;
std::string JITDylibName;
+ bool Open = true;
SymbolTable Symbols;
UnmaterializedInfosMap UnmaterializedInfos;
MaterializingInfosMap MaterializingInfos;
std::vector<std::unique_ptr<DefinitionGenerator>> DefGenerators;
- JITDylibSearchOrder SearchOrder;
+ JITDylibSearchOrder LinkOrder;
+};
+
+/// Platforms set up standard symbols and mediate interactions between dynamic
+/// initializers (e.g. C++ static constructors) and ExecutionSession state.
+/// Note that Platforms do not automatically run initializers: clients are still
+/// responsible for doing this.
+class Platform {
+public:
+ virtual ~Platform();
+
+ /// This method will be called outside the session lock each time a JITDylib
+ /// is created (unless it is created with EmptyJITDylib set) to allow the
+ /// Platform to install any JITDylib specific standard symbols (e.g
+ /// __dso_handle).
+ virtual Error setupJITDylib(JITDylib &JD) = 0;
+
+ /// This method will be called under the ExecutionSession lock each time a
+ /// MaterializationUnit is added to a JITDylib.
+ virtual Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) = 0;
+
+ /// This method will be called under the ExecutionSession lock when a
+ /// VModuleKey is removed.
+ virtual Error notifyRemoving(JITDylib &JD, VModuleKey K) = 0;
+
+ /// A utility function for looking up initializer symbols. Performs a blocking
+ /// lookup for the given symbols in each of the given JITDylibs.
+ static Expected<DenseMap<JITDylib *, SymbolMap>>
+ lookupInitSymbols(ExecutionSession &ES,
+ const DenseMap<JITDylib *, SymbolLookupSet> &InitSyms);
};
/// An ExecutionSession represents a running JIT program.
@@ -1064,8 +1094,9 @@ public:
using ErrorReporter = std::function<void(Error)>;
/// For dispatching MaterializationUnit::materialize calls.
- using DispatchMaterializationFunction = std::function<void(
- JITDylib &JD, std::unique_ptr<MaterializationUnit> MU)>;
+ using DispatchMaterializationFunction =
+ std::function<void(std::unique_ptr<MaterializationUnit> MU,
+ MaterializationResponsibility MR)>;
/// Construct an ExecutionSession.
///
@@ -1078,8 +1109,15 @@ public:
/// Returns a shared_ptr to the SymbolStringPool for this ExecutionSession.
std::shared_ptr<SymbolStringPool> getSymbolStringPool() const { return SSP; }
+ /// Set the Platform for this ExecutionSession.
+ void setPlatform(std::unique_ptr<Platform> P) { this->P = std::move(P); }
+
+ /// Get the Platform for this session.
+ /// Will return null if no Platform has been set for this ExecutionSession.
+ Platform *getPlatform() { return P.get(); }
+
/// Run the given lambda with the session mutex locked.
- template <typename Func> auto runSessionLocked(Func &&F) -> decltype(F()) {
+ template <typename Func> decltype(auto) runSessionLocked(Func &&F) {
std::lock_guard<std::recursive_mutex> Lock(SessionMutex);
return F();
}
@@ -1088,12 +1126,26 @@ public:
/// Ownership of JITDylib remains within Execution Session
JITDylib *getJITDylibByName(StringRef Name);
+ /// Add a new bare JITDylib to this ExecutionSession.
+ ///
+ /// The JITDylib Name is required to be unique. Clients should verify that
+ /// names are not being re-used (E.g. by calling getJITDylibByName) if names
+ /// are based on user input.
+ ///
+ /// This call does not install any library code or symbols into the newly
+ /// created JITDylib. The client is responsible for all configuration.
+ JITDylib &createBareJITDylib(std::string Name);
+
/// Add a new JITDylib to this ExecutionSession.
///
/// The JITDylib Name is required to be unique. Clients should verify that
/// names are not being re-used (e.g. by calling getJITDylibByName) if names
/// are based on user input.
- JITDylib &createJITDylib(std::string Name);
+ ///
+ /// If a Platform is attached then Platform::setupJITDylib will be called to
+ /// install standard platform symbols (e.g. standard library interposes).
+ /// If no Platform is attached this call is equivalent to createBareJITDylib.
+ Expected<JITDylib &> createJITDylib(std::string Name);
/// Allocate a module key for a new module to add to the JIT.
VModuleKey allocateVModule() {
@@ -1177,30 +1229,30 @@ public:
/// Convenience version of blocking lookup.
/// Searches each of the JITDylibs in the search order in turn for the given
/// symbol.
- Expected<JITEvaluatedSymbol> lookup(const JITDylibSearchOrder &SearchOrder,
- SymbolStringPtr Symbol);
+ Expected<JITEvaluatedSymbol>
+ lookup(const JITDylibSearchOrder &SearchOrder, SymbolStringPtr Symbol,
+ SymbolState RequiredState = SymbolState::Ready);
/// Convenience version of blocking lookup.
/// Searches each of the JITDylibs in the search order in turn for the given
/// symbol. The search will not find non-exported symbols.
- Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
- SymbolStringPtr Symbol);
+ Expected<JITEvaluatedSymbol>
+ lookup(ArrayRef<JITDylib *> SearchOrder, SymbolStringPtr Symbol,
+ SymbolState RequiredState = SymbolState::Ready);
/// Convenience version of blocking lookup.
/// Searches each of the JITDylibs in the search order in turn for the given
/// symbol. The search will not find non-exported symbols.
- Expected<JITEvaluatedSymbol> lookup(ArrayRef<JITDylib *> SearchOrder,
- StringRef Symbol);
+ Expected<JITEvaluatedSymbol>
+ lookup(ArrayRef<JITDylib *> SearchOrder, StringRef Symbol,
+ SymbolState RequiredState = SymbolState::Ready);
/// Materialize the given unit.
- void dispatchMaterialization(JITDylib &JD,
- std::unique_ptr<MaterializationUnit> MU) {
- LLVM_DEBUG({
- runSessionLocked([&]() {
- dbgs() << "Dispatching " << *MU << " for " << JD.getName() << "\n";
- });
- });
- DispatchMaterialization(JD, std::move(MU));
+ void dispatchMaterialization(std::unique_ptr<MaterializationUnit> MU,
+ MaterializationResponsibility MR) {
+ assert(MU && "MU must be non-null");
+ DEBUG_WITH_TYPE("orc", dumpDispatchInfo(MR.getTargetJITDylib(), *MU));
+ DispatchMaterialization(std::move(MU), std::move(MR));
}
/// Dump the state of all the JITDylibs in this session.
@@ -1212,26 +1264,32 @@ private:
}
static void
- materializeOnCurrentThread(JITDylib &JD,
- std::unique_ptr<MaterializationUnit> MU) {
- MU->doMaterialize(JD);
+ materializeOnCurrentThread(std::unique_ptr<MaterializationUnit> MU,
+ MaterializationResponsibility MR) {
+ MU->materialize(std::move(MR));
}
void runOutstandingMUs();
+#ifndef NDEBUG
+ void dumpDispatchInfo(JITDylib &JD, MaterializationUnit &MU);
+#endif // NDEBUG
+
mutable std::recursive_mutex SessionMutex;
std::shared_ptr<SymbolStringPool> SSP;
+ std::unique_ptr<Platform> P;
VModuleKey LastKey = 0;
ErrorReporter ReportError = logErrorsToStdErr;
DispatchMaterializationFunction DispatchMaterialization =
materializeOnCurrentThread;
- std::vector<std::unique_ptr<JITDylib>> JDs;
+ std::vector<std::shared_ptr<JITDylib>> JDs;
// FIXME: Remove this (and runOutstandingMUs) once the linking layer works
// with callbacks from asynchronous queries.
mutable std::recursive_mutex OutstandingMUsMutex;
- std::vector<std::pair<JITDylib *, std::unique_ptr<MaterializationUnit>>>
+ std::vector<std::pair<std::unique_ptr<MaterializationUnit>,
+ MaterializationResponsibility>>
OutstandingMUs;
};
@@ -1244,18 +1302,36 @@ GeneratorT &JITDylib::addGenerator(std::unique_ptr<GeneratorT> DefGenerator) {
}
template <typename Func>
-auto JITDylib::withSearchOrderDo(Func &&F)
+auto JITDylib::withLinkOrderDo(Func &&F)
-> decltype(F(std::declval<const JITDylibSearchOrder &>())) {
- return ES.runSessionLocked([&]() { return F(SearchOrder); });
+ return ES.runSessionLocked([&]() { return F(LinkOrder); });
}
template <typename MaterializationUnitType>
Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &&MU) {
assert(MU && "Can not define with a null MU");
+
+ if (MU->getSymbols().empty()) {
+ // Empty MUs are allowable but pathological, so issue a warning.
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Warning: Discarding empty MU " << MU->getName() << " for "
+ << getName() << "\n";
+ });
+ return Error::success();
+ } else
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName() << "\n";
+ });
+
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
+ if (auto *P = ES.getPlatform()) {
+ if (auto Err = P->notifyAdding(*this, *MU))
+ return Err;
+ }
+
/// defineImpl succeeded.
auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
for (auto &KV : UMI->MU->getSymbols())
@@ -1269,10 +1345,27 @@ template <typename MaterializationUnitType>
Error JITDylib::define(std::unique_ptr<MaterializationUnitType> &MU) {
assert(MU && "Can not define with a null MU");
+ if (MU->getSymbols().empty()) {
+ // Empty MUs are allowable but pathological, so issue a warning.
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Warning: Discarding empty MU " << MU->getName() << getName()
+ << "\n";
+ });
+ return Error::success();
+ } else
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "Defining MU " << MU->getName() << " for " << getName() << "\n";
+ });
+
return ES.runSessionLocked([&, this]() -> Error {
if (auto Err = defineImpl(*MU))
return Err;
+ if (auto *P = ES.getPlatform()) {
+ if (auto Err = P->notifyAdding(*this, *MU))
+ return Err;
+ }
+
/// defineImpl succeeded.
auto UMI = std::make_shared<UnmaterializedInfo>(std::move(MU));
for (auto &KV : UMI->MU->getSymbols())
@@ -1305,21 +1398,7 @@ private:
SymbolPredicate Allow;
};
-/// Mangles symbol names then uniques them in the context of an
-/// ExecutionSession.
-class MangleAndInterner {
-public:
- MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);
- SymbolStringPtr operator()(StringRef Name);
-
-private:
- ExecutionSession &ES;
- const DataLayout &DL;
-};
-
} // End namespace orc
} // End namespace llvm
-#undef DEBUG_TYPE // "orc"
-
#endif // LLVM_EXECUTIONENGINE_ORC_CORE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h
index b2ef29d65ffe..4b4472e0ac4d 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/DebugUtils.h
@@ -13,7 +13,11 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_DEBUGUTILS_H
#define LLVM_EXECUTIONENGINE_ORC_DEBUGUTILS_H
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/Support/Error.h"
+#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <string>
@@ -23,6 +27,74 @@ class MemoryBuffer;
namespace orc {
+// --raw_ostream operators for ORC types--
+
+/// Render a SymbolStringPtr.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolStringPtr &Sym);
+
+/// Render a SymbolNameSet.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameSet &Symbols);
+
+/// Render a SymbolNameVector.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolNameVector &Symbols);
+
+/// Render an array of SymbolStringPtrs.
+raw_ostream &operator<<(raw_ostream &OS, ArrayRef<SymbolStringPtr> Symbols);
+
+/// Render JITSymbolFlags.
+raw_ostream &operator<<(raw_ostream &OS, const JITSymbolFlags &Flags);
+
+/// Render a SymbolFlagsMap entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap::value_type &KV);
+
+/// Render a SymbolMap entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolMap::value_type &KV);
+
+/// Render a SymbolFlagsMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolFlagsMap &SymbolFlags);
+
+/// Render a SymbolMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolMap &Symbols);
+
+/// Render a SymbolDependenceMap entry.
+raw_ostream &operator<<(raw_ostream &OS,
+ const SymbolDependenceMap::value_type &KV);
+
+/// Render a SymbolDependendeMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolDependenceMap &Deps);
+
+/// Render a MaterializationUnit.
+raw_ostream &operator<<(raw_ostream &OS, const MaterializationUnit &MU);
+
+//// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibLookupFlags &JDLookupFlags);
+
+/// Rendar a SymbolLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupFlags &LookupFlags);
+
+/// Render a JITDylibLookupFlags instance.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
+/// Render a SymbolLookupSet entry.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet::value_type &KV);
+
+/// Render a SymbolLookupSet.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolLookupSet &LookupSet);
+
+/// Render a JITDylibSearchOrder.
+raw_ostream &operator<<(raw_ostream &OS,
+ const JITDylibSearchOrder &SearchOrder);
+
+/// Render a SymbolAliasMap.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolAliasMap &Aliases);
+
+/// Render a SymbolState.
+raw_ostream &operator<<(raw_ostream &OS, const SymbolState &S);
+
+/// Render a LookupKind.
+raw_ostream &operator<<(raw_ostream &OS, const LookupKind &K);
+
/// A function object that can be used as an ObjectTransformLayer transform
/// to dump object files to disk at a specified path.
class DumpObjects {
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
index f7255c5af845..3b824b83b052 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Mangling.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/Archive.h"
@@ -104,6 +105,53 @@ iterator_range<CtorDtorIterator> getConstructors(const Module &M);
/// array.
iterator_range<CtorDtorIterator> getDestructors(const Module &M);
+/// This iterator provides a convenient way to iterate over GlobalValues that
+/// have initialization effects.
+class StaticInitGVIterator {
+public:
+ StaticInitGVIterator() = default;
+
+ StaticInitGVIterator(Module &M)
+ : I(M.global_values().begin()), E(M.global_values().end()),
+ ObjFmt(Triple(M.getTargetTriple()).getObjectFormat()) {
+ if (I != E) {
+ if (!isStaticInitGlobal(*I))
+ moveToNextStaticInitGlobal();
+ } else
+ I = E = Module::global_value_iterator();
+ }
+
+ bool operator==(const StaticInitGVIterator &O) const { return I == O.I; }
+ bool operator!=(const StaticInitGVIterator &O) const { return I != O.I; }
+
+ StaticInitGVIterator &operator++() {
+ assert(I != E && "Increment past end of range");
+ moveToNextStaticInitGlobal();
+ return *this;
+ }
+
+ GlobalValue &operator*() { return *I; }
+
+private:
+ bool isStaticInitGlobal(GlobalValue &GV);
+ void moveToNextStaticInitGlobal() {
+ ++I;
+ while (I != E && !isStaticInitGlobal(*I))
+ ++I;
+ if (I == E)
+ I = E = Module::global_value_iterator();
+ }
+
+ Module::global_value_iterator I, E;
+ Triple::ObjectFormatType ObjFmt;
+};
+
+/// Create an iterator range over the GlobalValues that contribute to static
+/// initialization.
+inline iterator_range<StaticInitGVIterator> getStaticInitGVs(Module &M) {
+ return make_range(StaticInitGVIterator(M), StaticInitGVIterator());
+}
+
/// Convenience class for recording constructor/destructor names for
/// later execution.
template <typename JITLayerT>
@@ -246,6 +294,22 @@ public:
Error enable(JITDylib &JD, MangleAndInterner &Mangler);
};
+/// An interface for Itanium __cxa_atexit interposer implementations.
+class ItaniumCXAAtExitSupport {
+public:
+ struct AtExitRecord {
+ void (*F)(void *);
+ void *Ctx;
+ };
+
+ void registerAtExit(void (*F)(void *), void *Ctx, void *DSOHandle);
+ void runAtExits(void *DSOHandle);
+
+private:
+ std::mutex AtExitsMutex;
+ DenseMap<void *, std::vector<AtExitRecord>> AtExitRecords;
+};
+
/// A utility class to expose symbols found via dlsym to the JIT.
///
/// If an instance of this class is attached to a JITDylib as a fallback
@@ -303,6 +367,14 @@ public:
static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
Load(ObjectLayer &L, const char *FileName);
+ /// Try to create a StaticLibraryDefinitionGenerator from the given path.
+ ///
+ /// This call will succeed if the file at the given path is a static library
+ /// or a MachO universal binary containing a static library that is compatible
+ /// with the given triple. Otherwise it will return an error.
+ static Expected<std::unique_ptr<StaticLibraryDefinitionGenerator>>
+ Load(ObjectLayer &L, const char *FileName, const Triple &TT);
+
/// Try to create a StaticLibrarySearchGenerator from the given memory buffer.
/// This call will succeed if the buffer contains a valid archive, otherwise
/// it will return an error.
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
index bb8270fe80a3..eb74d283f043 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRCompileLayer.h
@@ -31,18 +31,18 @@ class IRCompileLayer : public IRLayer {
public:
class IRCompiler {
public:
- IRCompiler(IRMaterializationUnit::ManglingOptions MO) : MO(std::move(MO)) {}
+ IRCompiler(IRSymbolMapper::ManglingOptions MO) : MO(std::move(MO)) {}
virtual ~IRCompiler();
- const IRMaterializationUnit::ManglingOptions &getManglingOptions() const {
+ const IRSymbolMapper::ManglingOptions &getManglingOptions() const {
return MO;
}
virtual Expected<std::unique_ptr<MemoryBuffer>> operator()(Module &M) = 0;
protected:
- IRMaterializationUnit::ManglingOptions &manglingOptions() { return MO; }
+ IRSymbolMapper::ManglingOptions &manglingOptions() { return MO; }
private:
- IRMaterializationUnit::ManglingOptions MO;
+ IRSymbolMapper::ManglingOptions MO;
};
using NotifyCompiledFunction =
@@ -61,7 +61,7 @@ private:
mutable std::mutex IRLayerMutex;
ObjectLayer &BaseLayer;
std::unique_ptr<IRCompiler> Compile;
- const IRMaterializationUnit::ManglingOptions *ManglingOpts;
+ const IRSymbolMapper::ManglingOptions *ManglingOpts;
NotifyCompiledFunction NotifyCompiled = NotifyCompiledFunction();
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
index b71e5b339711..296d74ae6b86 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IRTransformLayer.h
@@ -28,7 +28,7 @@ namespace orc {
class IRTransformLayer : public IRLayer {
public:
using TransformFunction = std::function<Expected<ThreadSafeModule>(
- ThreadSafeModule, const MaterializationResponsibility &R)>;
+ ThreadSafeModule, MaterializationResponsibility &R)>;
IRTransformLayer(ExecutionSession &ES, IRLayer &BaseLayer,
TransformFunction Transform = identityTransform);
@@ -39,9 +39,8 @@ public:
void emit(MaterializationResponsibility R, ThreadSafeModule TSM) override;
- static ThreadSafeModule
- identityTransform(ThreadSafeModule TSM,
- const MaterializationResponsibility &R) {
+ static ThreadSafeModule identityTransform(ThreadSafeModule TSM,
+ MaterializationResponsibility &R) {
return TSM;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index a9ab3a630a64..e0cfd8bf2409 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -15,9 +15,9 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/Process.h"
@@ -26,6 +26,7 @@
#include <cassert>
#include <cstdint>
#include <functional>
+#include <future>
#include <map>
#include <memory>
#include <system_error>
@@ -42,6 +43,7 @@ class GlobalVariable;
class Module;
class PointerType;
class Triple;
+class Twine;
class Value;
namespace orc {
@@ -53,6 +55,13 @@ namespace orc {
/// are used by various ORC APIs to support lazy compilation
class TrampolinePool {
public:
+ using NotifyLandingResolvedFunction =
+ unique_function<void(JITTargetAddress) const>;
+
+ using ResolveLandingFunction = unique_function<void(
+ JITTargetAddress TrampolineAddr,
+ NotifyLandingResolvedFunction OnLandingResolved) const>;
+
virtual ~TrampolinePool() {}
/// Get an available trampoline address.
@@ -66,18 +75,15 @@ private:
/// A trampoline pool for trampolines within the current process.
template <typename ORCABI> class LocalTrampolinePool : public TrampolinePool {
public:
- using GetTrampolineLandingFunction =
- std::function<JITTargetAddress(JITTargetAddress TrampolineAddr)>;
-
/// Creates a LocalTrampolinePool with the given RunCallback function.
/// Returns an error if this function is unable to correctly allocate, write
/// and protect the resolver code block.
static Expected<std::unique_ptr<LocalTrampolinePool>>
- Create(GetTrampolineLandingFunction GetTrampolineLanding) {
+ Create(ResolveLandingFunction ResolveLanding) {
Error Err = Error::success();
auto LTP = std::unique_ptr<LocalTrampolinePool>(
- new LocalTrampolinePool(std::move(GetTrampolineLanding), Err));
+ new LocalTrampolinePool(std::move(ResolveLanding), Err));
if (Err)
return std::move(Err);
@@ -108,13 +114,19 @@ private:
static JITTargetAddress reenter(void *TrampolinePoolPtr, void *TrampolineId) {
LocalTrampolinePool<ORCABI> *TrampolinePool =
static_cast<LocalTrampolinePool *>(TrampolinePoolPtr);
- return TrampolinePool->GetTrampolineLanding(static_cast<JITTargetAddress>(
- reinterpret_cast<uintptr_t>(TrampolineId)));
+
+ std::promise<JITTargetAddress> LandingAddressP;
+ auto LandingAddressF = LandingAddressP.get_future();
+
+ TrampolinePool->ResolveLanding(pointerToJITTargetAddress(TrampolineId),
+ [&](JITTargetAddress LandingAddress) {
+ LandingAddressP.set_value(LandingAddress);
+ });
+ return LandingAddressF.get();
}
- LocalTrampolinePool(GetTrampolineLandingFunction GetTrampolineLanding,
- Error &Err)
- : GetTrampolineLanding(std::move(GetTrampolineLanding)) {
+ LocalTrampolinePool(ResolveLandingFunction ResolveLanding, Error &Err)
+ : ResolveLanding(std::move(ResolveLanding)) {
ErrorAsOutParameter _(&Err);
@@ -128,8 +140,10 @@ private:
return;
}
- ORCABI::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
- &reenter, this);
+ ORCABI::writeResolverCode(static_cast<char *>(ResolverBlock.base()),
+ pointerToJITTargetAddress(ResolverBlock.base()),
+ pointerToJITTargetAddress(&reenter),
+ pointerToJITTargetAddress(this));
EC = sys::Memory::protectMappedMemory(ResolverBlock.getMemoryBlock(),
sys::Memory::MF_READ |
@@ -155,14 +169,14 @@ private:
(sys::Process::getPageSizeEstimate() - ORCABI::PointerSize) /
ORCABI::TrampolineSize;
- uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
- ORCABI::writeTrampolines(TrampolineMem, ResolverBlock.base(),
- NumTrampolines);
+ char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());
+ ORCABI::writeTrampolines(
+ TrampolineMem, pointerToJITTargetAddress(TrampolineMem),
+ pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
for (unsigned I = 0; I < NumTrampolines; ++I)
- this->AvailableTrampolines.push_back(
- static_cast<JITTargetAddress>(reinterpret_cast<uintptr_t>(
- TrampolineMem + (I * ORCABI::TrampolineSize))));
+ this->AvailableTrampolines.push_back(pointerToJITTargetAddress(
+ TrampolineMem + (I * ORCABI::TrampolineSize)));
if (auto EC = sys::Memory::protectMappedMemory(
TrampolineBlock.getMemoryBlock(),
@@ -173,7 +187,7 @@ private:
return Error::success();
}
- GetTrampolineLandingFunction GetTrampolineLanding;
+ ResolveLandingFunction ResolveLanding;
std::mutex LTPMutex;
sys::OwningMemoryBlock ResolverBlock;
@@ -201,7 +215,7 @@ protected:
ExecutionSession &ES,
JITTargetAddress ErrorHandlerAddress)
: TP(std::move(TP)), ES(ES),
- CallbacksJD(ES.createJITDylib("<Callbacks>")),
+ CallbacksJD(ES.createBareJITDylib("<Callbacks>")),
ErrorHandlerAddress(ErrorHandlerAddress) {}
void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
@@ -241,10 +255,14 @@ private:
JITTargetAddress ErrorHandlerAddress,
Error &Err)
: JITCompileCallbackManager(nullptr, ES, ErrorHandlerAddress) {
+ using NotifyLandingResolvedFunction =
+ TrampolinePool::NotifyLandingResolvedFunction;
+
ErrorAsOutParameter _(&Err);
auto TP = LocalTrampolinePool<ORCABI>::Create(
- [this](JITTargetAddress TrampolineAddr) {
- return executeCompileCallback(TrampolineAddr);
+ [this](JITTargetAddress TrampolineAddr,
+ NotifyLandingResolvedFunction NotifyLandingResolved) {
+ NotifyLandingResolved(executeCompileCallback(TrampolineAddr));
});
if (!TP) {
@@ -287,6 +305,61 @@ private:
virtual void anchor();
};
+template <typename ORCABI> class LocalIndirectStubsInfo {
+public:
+ LocalIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
+ : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
+
+ static Expected<LocalIndirectStubsInfo> create(unsigned MinStubs,
+ unsigned PageSize) {
+ auto ISAS = getIndirectStubsBlockSizes<ORCABI>(MinStubs, PageSize);
+
+ assert((ISAS.StubBytes % PageSize == 0) &&
+ "StubBytes is not a page size multiple");
+ uint64_t PointerAlloc = alignTo(ISAS.PointerBytes, PageSize);
+
+ // Allocate memory for stubs and pointers in one call.
+ std::error_code EC;
+ auto StubsAndPtrsMem =
+ sys::OwningMemoryBlock(sys::Memory::allocateMappedMemory(
+ ISAS.StubBytes + PointerAlloc, nullptr,
+ sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC));
+ if (EC)
+ return errorCodeToError(EC);
+
+ sys::MemoryBlock StubsBlock(StubsAndPtrsMem.base(), ISAS.StubBytes);
+ auto StubsBlockMem = static_cast<char *>(StubsAndPtrsMem.base());
+ auto PtrBlockAddress =
+ pointerToJITTargetAddress(StubsBlockMem) + ISAS.StubBytes;
+
+ ORCABI::writeIndirectStubsBlock(StubsBlockMem,
+ pointerToJITTargetAddress(StubsBlockMem),
+ PtrBlockAddress, ISAS.NumStubs);
+
+ if (auto EC = sys::Memory::protectMappedMemory(
+ StubsBlock, sys::Memory::MF_READ | sys::Memory::MF_EXEC))
+ return errorCodeToError(EC);
+
+ return LocalIndirectStubsInfo(ISAS.NumStubs, std::move(StubsAndPtrsMem));
+ }
+
+ unsigned getNumStubs() const { return NumStubs; }
+
+ void *getStub(unsigned Idx) const {
+ return static_cast<char *>(StubsMem.base()) + Idx * ORCABI::StubSize;
+ }
+
+ void **getPtr(unsigned Idx) const {
+ char *PtrsBase =
+ static_cast<char *>(StubsMem.base()) + NumStubs * ORCABI::StubSize;
+ return reinterpret_cast<void **>(PtrsBase) + Idx;
+ }
+
+private:
+ unsigned NumStubs = 0;
+ sys::OwningMemoryBlock StubsMem;
+};
+
/// IndirectStubsManager implementation for the host architecture, e.g.
/// OrcX86_64. (See OrcArchitectureSupport.h).
template <typename TargetT>
@@ -364,13 +437,13 @@ private:
unsigned NewStubsRequired = NumStubs - FreeStubs.size();
unsigned NewBlockId = IndirectStubsInfos.size();
- typename TargetT::IndirectStubsInfo ISI;
- if (auto Err =
- TargetT::emitIndirectStubsBlock(ISI, NewStubsRequired, nullptr))
- return Err;
- for (unsigned I = 0; I < ISI.getNumStubs(); ++I)
+ auto ISI =
+ LocalIndirectStubsInfo<TargetT>::create(NewStubsRequired, PageSize);
+ if (!ISI)
+ return ISI.takeError();
+ for (unsigned I = 0; I < ISI->getNumStubs(); ++I)
FreeStubs.push_back(std::make_pair(NewBlockId, I));
- IndirectStubsInfos.push_back(std::move(ISI));
+ IndirectStubsInfos.push_back(std::move(*ISI));
return Error::success();
}
@@ -379,12 +452,13 @@ private:
auto Key = FreeStubs.back();
FreeStubs.pop_back();
*IndirectStubsInfos[Key.first].getPtr(Key.second) =
- reinterpret_cast<void *>(static_cast<uintptr_t>(InitAddr));
+ jitTargetAddressToPointer<void *>(InitAddr);
StubIndexes[StubName] = std::make_pair(Key, StubFlags);
}
+ unsigned PageSize = sys::Process::getPageSizeEstimate();
std::mutex StubsMutex;
- std::vector<typename TargetT::IndirectStubsInfo> IndirectStubsInfos;
+ std::vector<LocalIndirectStubsInfo<TargetT>> IndirectStubsInfos;
using StubKey = std::pair<uint16_t, uint16_t>;
std::vector<StubKey> FreeStubs;
StringMap<std::pair<StubKey, JITSymbolFlags>> StubIndexes;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
index 4f2f55770996..c4109a8de82e 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h
@@ -25,6 +25,9 @@
#include <vector>
namespace llvm {
+
+class raw_ostream;
+
namespace orc {
/// A utility class for building TargetMachines for JITs.
@@ -136,6 +139,12 @@ public:
/// Access Triple.
const Triple &getTargetTriple() const { return TT; }
+#ifndef NDEBUG
+ /// Debug-dump a JITTargetMachineBuilder.
+ friend raw_ostream &operator<<(raw_ostream &OS,
+ const JITTargetMachineBuilder &JTMB);
+#endif
+
private:
Triple TT;
std::string CPU;
@@ -143,7 +152,7 @@ private:
TargetOptions Options;
Optional<Reloc::Model> RM;
Optional<CodeModel::Model> CM;
- CodeGenOpt::Level OptLevel = CodeGenOpt::None;
+ CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
};
} // end namespace orc
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index 8e4760024aa8..96f8e169e7dc 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -21,6 +21,7 @@
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ThreadPool.h"
namespace llvm {
@@ -35,8 +36,22 @@ class LLLazyJITBuilderState;
class LLJIT {
template <typename, typename, typename> friend class LLJITBuilderSetters;
+ friend void setUpGenericLLVMIRPlatform(LLJIT &J);
+
public:
- static Expected<std::unique_ptr<LLJIT>> Create(LLJITBuilderState &S);
+ /// Initializer support for LLJIT.
+ class PlatformSupport {
+ public:
+ virtual ~PlatformSupport();
+
+ virtual Error initialize(JITDylib &JD) = 0;
+
+ virtual Error deinitialize(JITDylib &JD) = 0;
+
+ protected:
+ static void setInitTransform(LLJIT &J,
+ IRTransformLayer::TransformFunction T);
+ };
/// Destruct this instance. If a multi-threaded instance, waits for all
/// compile threads to complete.
@@ -45,11 +60,14 @@ public:
/// Returns the ExecutionSession for this instance.
ExecutionSession &getExecutionSession() { return *ES; }
+ /// Returns a reference to the triple for this instance.
+ const Triple &getTargetTriple() const { return TT; }
+
/// Returns a reference to the DataLayout for this instance.
const DataLayout &getDataLayout() const { return DL; }
/// Returns a reference to the JITDylib representing the JIT'd main program.
- JITDylib &getMainJITDylib() { return Main; }
+ JITDylib &getMainJITDylib() { return *Main; }
/// Returns the JITDylib with the given name, or nullptr if no JITDylib with
/// that name exists.
@@ -63,19 +81,32 @@ public:
/// input or elsewhere in the environment then the client should check
/// (e.g. by calling getJITDylibByName) that the given name is not already in
/// use.
- JITDylib &createJITDylib(std::string Name) {
+ Expected<JITDylib &> createJITDylib(std::string Name) {
return ES->createJITDylib(std::move(Name));
}
- /// Convenience method for defining an absolute symbol.
- Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
+ /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can
+ /// be useful for succinctly defining absolute symbols, aliases and
+ /// re-exports.
+ template <typename MUType>
+ Error define(std::unique_ptr<MUType> &&MU) {
+ return Main->define(std::move(MU));
+ }
+
+ /// A convenience method for defining MUs in LLJIT's Main JITDylib. This can
+ /// be usedful for succinctly defining absolute symbols, aliases and
+ /// re-exports.
+ template <typename MUType>
+ Error define(std::unique_ptr<MUType> &MU) {
+ return Main->define(MU);
+ }
/// Adds an IR module to the given JITDylib.
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
/// Adds an IR module to the Main JITDylib.
Error addIRModule(ThreadSafeModule TSM) {
- return addIRModule(Main, std::move(TSM));
+ return addIRModule(*Main, std::move(TSM));
}
/// Adds an object file to the given JITDylib.
@@ -83,19 +114,26 @@ public:
/// Adds an object file to the given JITDylib.
Error addObjectFile(std::unique_ptr<MemoryBuffer> Obj) {
- return addObjectFile(Main, std::move(Obj));
+ return addObjectFile(*Main, std::move(Obj));
}
/// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
/// look up symbols based on their IR name use the lookup function instead).
Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
- StringRef Name);
+ SymbolStringPtr Name);
+
+ /// Look up a symbol in JITDylib JD by the symbol's linker-mangled name (to
+ /// look up symbols based on their IR name use the lookup function instead).
+ Expected<JITEvaluatedSymbol> lookupLinkerMangled(JITDylib &JD,
+ StringRef Name) {
+ return lookupLinkerMangled(JD, ES->intern(Name));
+ }
/// Look up a symbol in the main JITDylib by the symbol's linker-mangled name
/// (to look up symbols based on their IR name use the lookup function
/// instead).
Expected<JITEvaluatedSymbol> lookupLinkerMangled(StringRef Name) {
- return lookupLinkerMangled(Main, Name);
+ return lookupLinkerMangled(*Main, Name);
}
/// Look up a symbol in JITDylib JD based on its IR symbol name.
@@ -105,14 +143,36 @@ public:
/// Look up a symbol in the main JITDylib based on its IR symbol name.
Expected<JITEvaluatedSymbol> lookup(StringRef UnmangledName) {
- return lookup(Main, UnmangledName);
+ return lookup(*Main, UnmangledName);
+ }
+
+ /// Set the PlatformSupport instance.
+ void setPlatformSupport(std::unique_ptr<PlatformSupport> PS) {
+ this->PS = std::move(PS);
}
- /// Runs all not-yet-run static constructors.
- Error runConstructors() { return CtorRunner.run(); }
+ /// Get the PlatformSupport instance.
+ PlatformSupport *getPlatformSupport() { return PS.get(); }
+
+ /// Run the initializers for the given JITDylib.
+ Error initialize(JITDylib &JD) {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "LLJIT running initializers for JITDylib \"" << JD.getName()
+ << "\"\n";
+ });
+ assert(PS && "PlatformSupport must be set to run initializers.");
+ return PS->initialize(JD);
+ }
- /// Runs all not-yet-run static destructors.
- Error runDestructors() { return DtorRunner.run(); }
+ /// Run the deinitializers for the given JITDylib.
+ Error deinitialize(JITDylib &JD) {
+ DEBUG_WITH_TYPE("orc", {
+ dbgs() << "LLJIT running deinitializers for JITDylib \"" << JD.getName()
+ << "\"\n";
+ });
+ assert(PS && "PlatformSupport must be set to run initializers.");
+ return PS->deinitialize(JD);
+ }
/// Returns a reference to the ObjLinkingLayer
ObjectLayer &getObjLinkingLayer() { return *ObjLinkingLayer; }
@@ -120,6 +180,20 @@ public:
/// Returns a reference to the object transform layer.
ObjectTransformLayer &getObjTransformLayer() { return ObjTransformLayer; }
+ /// Returns a reference to the IR transform layer.
+ IRTransformLayer &getIRTransformLayer() { return *TransformLayer; }
+
+ /// Returns a reference to the IR compile layer.
+ IRCompileLayer &getIRCompileLayer() { return *CompileLayer; }
+
+ /// Returns a linker-mangled version of UnmangledName.
+ std::string mangle(StringRef UnmangledName) const;
+
+ /// Returns an interned, linker-mangled version of UnmangledName.
+ SymbolStringPtr mangleAndIntern(StringRef UnmangledName) const {
+ return ES->intern(mangle(UnmangledName));
+ }
+
protected:
static std::unique_ptr<ObjectLayer>
createObjectLinkingLayer(LLJITBuilderState &S, ExecutionSession &ES);
@@ -130,23 +204,24 @@ protected:
/// Create an LLJIT instance with a single compile thread.
LLJIT(LLJITBuilderState &S, Error &Err);
- std::string mangle(StringRef UnmangledName);
-
Error applyDataLayout(Module &M);
void recordCtorDtors(Module &M);
std::unique_ptr<ExecutionSession> ES;
- JITDylib &Main;
+ std::unique_ptr<PlatformSupport> PS;
+
+ JITDylib *Main = nullptr;
DataLayout DL;
+ Triple TT;
std::unique_ptr<ThreadPool> CompileThreads;
std::unique_ptr<ObjectLayer> ObjLinkingLayer;
ObjectTransformLayer ObjTransformLayer;
std::unique_ptr<IRCompileLayer> CompileLayer;
-
- CtorDtorRunner CtorRunner, DtorRunner;
+ std::unique_ptr<IRTransformLayer> TransformLayer;
+ std::unique_ptr<IRTransformLayer> InitHelperTransformLayer;
};
/// An extended version of LLJIT that supports lazy function-at-a-time
@@ -156,12 +231,6 @@ class LLLazyJIT : public LLJIT {
public:
- /// Set an IR transform (e.g. pass manager pipeline) to run on each function
- /// when it is compiled.
- void setLazyCompileTransform(IRTransformLayer::TransformFunction Transform) {
- TransformLayer->setTransform(std::move(Transform));
- }
-
/// Sets the partition function.
void
setPartitionFunction(CompileOnDemandLayer::PartitionFunction Partition) {
@@ -173,7 +242,7 @@ public:
/// Add a module to be lazily compiled to the main JITDylib.
Error addLazyIRModule(ThreadSafeModule M) {
- return addLazyIRModule(Main, std::move(M));
+ return addLazyIRModule(*Main, std::move(M));
}
private:
@@ -182,7 +251,6 @@ private:
LLLazyJIT(LLLazyJITBuilderState &S, Error &Err);
std::unique_ptr<LazyCallThroughManager> LCTMgr;
- std::unique_ptr<IRTransformLayer> TransformLayer;
std::unique_ptr<CompileOnDemandLayer> CODLayer;
};
@@ -195,10 +263,14 @@ public:
std::function<Expected<std::unique_ptr<IRCompileLayer::IRCompiler>>(
JITTargetMachineBuilder JTMB)>;
+ using PlatformSetupFunction = std::function<Error(LLJIT &J)>;
+
std::unique_ptr<ExecutionSession> ES;
Optional<JITTargetMachineBuilder> JTMB;
+ Optional<DataLayout> DL;
ObjectLinkingLayerCreator CreateObjectLinkingLayer;
CompileFunctionCreator CreateCompileFunction;
+ PlatformSetupFunction SetUpPlatform;
unsigned NumCompileThreads = 0;
/// Called prior to JIT class construcion to fix up defaults.
@@ -208,6 +280,13 @@ public:
template <typename JITType, typename SetterImpl, typename State>
class LLJITBuilderSetters {
public:
+
+ /// Set an ExecutionSession for this instance.
+ SetterImpl &setExecutionSession(std::unique_ptr<ExecutionSession> ES) {
+ impl().ES = std::move(ES);
+ return impl();
+ }
+
/// Set the JITTargetMachineBuilder for this instance.
///
/// If this method is not called, JITTargetMachineBuilder::detectHost will be
@@ -223,6 +302,13 @@ public:
return impl().JTMB;
}
+ /// Set a DataLayout for this instance. If no data layout is specified then
+ /// the target's default data layout will be used.
+ SetterImpl &setDataLayout(Optional<DataLayout> DL) {
+ impl().DL = std::move(DL);
+ return impl();
+ }
+
/// Set an ObjectLinkingLayer creation function.
///
/// If this method is not called, a default creation function will be used
@@ -245,6 +331,16 @@ public:
return impl();
}
+ /// Set up an PlatformSetupFunction.
+ ///
+ /// If this method is not called then setUpGenericLLVMIRPlatform
+ /// will be used to configure the JIT's platform support.
+ SetterImpl &
+ setPlatformSetUp(LLJITBuilderState::PlatformSetupFunction SetUpPlatform) {
+ impl().SetUpPlatform = std::move(SetUpPlatform);
+ return impl();
+ }
+
/// Set the number of compile threads to use.
///
/// If set to zero, compilation will be performed on the execution thread when
@@ -333,6 +429,26 @@ class LLLazyJITBuilder
public LLLazyJITBuilderSetters<LLLazyJIT, LLLazyJITBuilder,
LLLazyJITBuilderState> {};
+/// Configure the LLJIT instance to scrape modules for llvm.global_ctors and
+/// llvm.global_dtors variables and (if present) build initialization and
+/// deinitialization functions. Platform specific initialization configurations
+/// should be preferred where available.
+void setUpGenericLLVMIRPlatform(LLJIT &J);
+
+/// Configure the LLJIT instance to use MachOPlatform support.
+///
+/// Warning: MachOPlatform *requires* that LLJIT be configured to use
+/// ObjectLinkingLayer (default on platforms supported by JITLink). If
+/// MachOPlatform is used with RTDyldObjectLinkingLayer it will result in
+/// undefined behavior).
+///
+/// MachOPlatform installs an ObjectLinkingLayer plugin to scrape initializers
+/// from the __mod_inits section. It also provides interposes for the dlfcn
+/// functions (dlopen, dlclose, dlsym, dlerror) that work for JITDylibs as
+/// well as regular libraries (JITDylibs will be preferenced, so make sure
+/// your JITDylib names do not shadow any real library paths).
+Error setUpMachOPlatform(LLJIT &J);
+
} // End namespace orc
} // End namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
index 95e32b2431a0..e843d0f56245 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Layer.h
@@ -14,6 +14,7 @@
#define LLVM_EXECUTIONENGINE_ORC_LAYER_H
#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/Mangling.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -27,15 +28,12 @@ namespace orc {
/// their linkage is changed to available-externally.
class IRMaterializationUnit : public MaterializationUnit {
public:
- struct ManglingOptions {
- bool EmulatedTLS = false;
- };
-
using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
/// Create an IRMaterializationLayer. Scans the module to build the
/// SymbolFlags and SymbolToDefinition maps.
- IRMaterializationUnit(ExecutionSession &ES, const ManglingOptions &MO,
+ IRMaterializationUnit(ExecutionSession &ES,
+ const IRSymbolMapper::ManglingOptions &MO,
ThreadSafeModule TSM, VModuleKey K);
/// Create an IRMaterializationLayer from a module, and pre-existing
@@ -44,12 +42,13 @@ public:
/// This constructor is useful for delegating work from one
/// IRMaterializationUnit to another.
IRMaterializationUnit(ThreadSafeModule TSM, VModuleKey K,
- SymbolFlagsMap SymbolFlags,
+ SymbolFlagsMap SymbolFlags, SymbolStringPtr InitSymbol,
SymbolNameToDefinitionMap SymbolToDefinition);
/// Return the ModuleIdentifier as the name for this MaterializationUnit.
StringRef getName() const override;
+ /// Return a reference to the contained ThreadSafeModule.
const ThreadSafeModule &getModule() const { return TSM; }
protected:
@@ -57,14 +56,16 @@ protected:
SymbolNameToDefinitionMap SymbolToDefinition;
private:
+ static SymbolStringPtr getInitSymbol(ExecutionSession &ES,
+ const ThreadSafeModule &TSM);
+
void discard(const JITDylib &JD, const SymbolStringPtr &Name) override;
};
/// Interface for layers that accept LLVM IR.
class IRLayer {
public:
- IRLayer(ExecutionSession &ES,
- const IRMaterializationUnit::ManglingOptions *&MO)
+ IRLayer(ExecutionSession &ES, const IRSymbolMapper::ManglingOptions *&MO)
: ES(ES), MO(MO) {}
virtual ~IRLayer();
@@ -73,7 +74,7 @@ public:
ExecutionSession &getExecutionSession() { return ES; }
/// Get the mangling options for this layer.
- const IRMaterializationUnit::ManglingOptions *&getManglingOptions() const {
+ const IRSymbolMapper::ManglingOptions *&getManglingOptions() const {
return MO;
}
@@ -104,14 +105,15 @@ public:
private:
bool CloneToNewContextOnEmit = false;
ExecutionSession &ES;
- const IRMaterializationUnit::ManglingOptions *&MO;
+ const IRSymbolMapper::ManglingOptions *&MO;
};
/// MaterializationUnit that materializes modules by calling the 'emit' method
/// on the given IRLayer.
class BasicIRLayerMaterializationUnit : public IRMaterializationUnit {
public:
- BasicIRLayerMaterializationUnit(IRLayer &L, const ManglingOptions &MO,
+ BasicIRLayerMaterializationUnit(IRLayer &L,
+ const IRSymbolMapper::ManglingOptions &MO,
ThreadSafeModule TSM, VModuleKey K);
private:
@@ -153,7 +155,8 @@ public:
BasicObjectLayerMaterializationUnit(ObjectLayer &L, VModuleKey K,
std::unique_ptr<MemoryBuffer> O,
- SymbolFlagsMap SymbolFlags);
+ SymbolFlagsMap SymbolFlags,
+ SymbolStringPtr InitSymbol);
/// Return the buffer's identifier as the name for this MaterializationUnit.
StringRef getName() const override;
@@ -167,12 +170,6 @@ private:
std::unique_ptr<MemoryBuffer> O;
};
-/// Returns a SymbolFlagsMap for the object file represented by the given
-/// buffer, or an error if the buffer does not contain a valid object file.
-// FIXME: Maybe move to Core.h?
-Expected<SymbolFlagsMap> getObjectSymbolFlags(ExecutionSession &ES,
- MemoryBufferRef ObjBuffer);
-
} // End namespace orc
} // End namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index b67a9feed523..84f5e0350c2e 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -78,7 +78,7 @@ private:
// RuntimeDyld that did the lookup), so just return a nullptr here.
return nullptr;
case Emitted:
- return B.findSymbolIn(K, Name, ExportedSymbolsOnly);
+ return B.findSymbolIn(K, std::string(Name), ExportedSymbolsOnly);
}
llvm_unreachable("Invalid emit-state.");
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
index 311ed59b1549..0d3ccecdf121 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/LazyReexports.h
@@ -16,6 +16,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
#define LLVM_EXECUTIONENGINE_ORC_LAZYREEXPORTS_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/Speculation.h"
@@ -36,73 +37,48 @@ namespace orc {
/// function.
class LazyCallThroughManager {
public:
- /// Clients will want to take some action on first resolution, e.g. updating
- /// a stub pointer. Instances of this class can be used to implement this.
- class NotifyResolvedFunction {
- public:
- virtual ~NotifyResolvedFunction() {}
-
- /// Called the first time a lazy call through is executed and the target
- /// symbol resolved.
- virtual Error operator()(JITDylib &SourceJD,
- const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) = 0;
-
- private:
- virtual void anchor();
- };
-
- template <typename NotifyResolvedImpl>
- class NotifyResolvedFunctionImpl : public NotifyResolvedFunction {
- public:
- NotifyResolvedFunctionImpl(NotifyResolvedImpl NotifyResolved)
- : NotifyResolved(std::move(NotifyResolved)) {}
- Error operator()(JITDylib &SourceJD, const SymbolStringPtr &SymbolName,
- JITTargetAddress ResolvedAddr) {
- return NotifyResolved(SourceJD, SymbolName, ResolvedAddr);
- }
-
- private:
- NotifyResolvedImpl NotifyResolved;
- };
-
- /// Create a shared NotifyResolvedFunction from a given type that is
- /// callable with the correct signature.
- template <typename NotifyResolvedImpl>
- static std::unique_ptr<NotifyResolvedFunction>
- createNotifyResolvedFunction(NotifyResolvedImpl NotifyResolved) {
- return std::make_unique<NotifyResolvedFunctionImpl<NotifyResolvedImpl>>(
- std::move(NotifyResolved));
- }
+ using NotifyResolvedFunction =
+ unique_function<Error(JITTargetAddress ResolvedAddr)>;
// Return a free call-through trampoline and bind it to look up and call
// through to the given symbol.
- Expected<JITTargetAddress> getCallThroughTrampoline(
- JITDylib &SourceJD, SymbolStringPtr SymbolName,
- std::shared_ptr<NotifyResolvedFunction> NotifyResolved);
+ Expected<JITTargetAddress>
+ getCallThroughTrampoline(JITDylib &SourceJD, SymbolStringPtr SymbolName,
+ NotifyResolvedFunction NotifyResolved);
+
+ void resolveTrampolineLandingAddress(
+ JITTargetAddress TrampolineAddr,
+ TrampolinePool::NotifyLandingResolvedFunction NotifyLandingResolved);
+
+ virtual ~LazyCallThroughManager() = default;
protected:
+ using NotifyLandingResolvedFunction =
+ TrampolinePool::NotifyLandingResolvedFunction;
+
LazyCallThroughManager(ExecutionSession &ES,
- JITTargetAddress ErrorHandlerAddr,
- std::unique_ptr<TrampolinePool> TP);
+ JITTargetAddress ErrorHandlerAddr, TrampolinePool *TP);
- JITTargetAddress callThroughToSymbol(JITTargetAddress TrampolineAddr);
+ struct ReexportsEntry {
+ JITDylib *SourceJD;
+ SymbolStringPtr SymbolName;
+ };
- void setTrampolinePool(std::unique_ptr<TrampolinePool> TP) {
- this->TP = std::move(TP);
- }
+ JITTargetAddress reportCallThroughError(Error Err);
+ Expected<ReexportsEntry> findReexport(JITTargetAddress TrampolineAddr);
+ Error notifyResolved(JITTargetAddress TrampolineAddr,
+ JITTargetAddress ResolvedAddr);
+ void setTrampolinePool(TrampolinePool &TP) { this->TP = &TP; }
private:
- using ReexportsMap =
- std::map<JITTargetAddress, std::pair<JITDylib *, SymbolStringPtr>>;
+ using ReexportsMap = std::map<JITTargetAddress, ReexportsEntry>;
- using NotifiersMap =
- std::map<JITTargetAddress, std::shared_ptr<NotifyResolvedFunction>>;
+ using NotifiersMap = std::map<JITTargetAddress, NotifyResolvedFunction>;
std::mutex LCTMMutex;
ExecutionSession &ES;
JITTargetAddress ErrorHandlerAddr;
- std::unique_ptr<TrampolinePool> TP;
+ TrampolinePool *TP = nullptr;
ReexportsMap Reexports;
NotifiersMap Notifiers;
};
@@ -110,23 +86,31 @@ private:
/// A lazy call-through manager that builds trampolines in the current process.
class LocalLazyCallThroughManager : public LazyCallThroughManager {
private:
+ using NotifyTargetResolved = unique_function<void(JITTargetAddress)>;
+
LocalLazyCallThroughManager(ExecutionSession &ES,
JITTargetAddress ErrorHandlerAddr)
: LazyCallThroughManager(ES, ErrorHandlerAddr, nullptr) {}
template <typename ORCABI> Error init() {
auto TP = LocalTrampolinePool<ORCABI>::Create(
- [this](JITTargetAddress TrampolineAddr) {
- return callThroughToSymbol(TrampolineAddr);
+ [this](JITTargetAddress TrampolineAddr,
+ TrampolinePool::NotifyLandingResolvedFunction
+ NotifyLandingResolved) {
+ resolveTrampolineLandingAddress(TrampolineAddr,
+ std::move(NotifyLandingResolved));
});
if (!TP)
return TP.takeError();
- setTrampolinePool(std::move(*TP));
+ this->TP = std::move(*TP);
+ setTrampolinePool(*this->TP);
return Error::success();
}
+ std::unique_ptr<TrampolinePool> TP;
+
public:
/// Create a LocalLazyCallThroughManager using the given ABI. See
/// createLocalLazyCallThroughManager.
@@ -173,8 +157,6 @@ private:
IndirectStubsManager &ISManager;
JITDylib &SourceJD;
SymbolAliasMap CallableAliases;
- std::shared_ptr<LazyCallThroughManager::NotifyResolvedFunction>
- NotifyResolved;
ImplSymbolMap *AliaseeTable;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
index 148e260c9569..b20202a49ef6 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Legacy.h
@@ -73,17 +73,13 @@ private:
/// function objects.
template <typename GetResponsibilitySetFn, typename LookupFn>
std::unique_ptr<LambdaSymbolResolver<
- typename std::remove_cv<
- typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
- typename std::remove_cv<
- typename std::remove_reference<LookupFn>::type>::type>>
+ std::remove_cv_t<std::remove_reference_t<GetResponsibilitySetFn>>,
+ std::remove_cv_t<std::remove_reference_t<LookupFn>>>>
createSymbolResolver(GetResponsibilitySetFn &&GetResponsibilitySet,
LookupFn &&Lookup) {
using LambdaSymbolResolverImpl = LambdaSymbolResolver<
- typename std::remove_cv<
- typename std::remove_reference<GetResponsibilitySetFn>::type>::type,
- typename std::remove_cv<
- typename std::remove_reference<LookupFn>::type>::type>;
+ std::remove_cv_t<std::remove_reference_t<GetResponsibilitySetFn>>,
+ std::remove_cv_t<std::remove_reference_t<LookupFn>>>;
return std::make_unique<LambdaSymbolResolverImpl>(
std::forward<GetResponsibilitySetFn>(GetResponsibilitySet),
std::forward<LookupFn>(Lookup));
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
new file mode 100644
index 000000000000..15fe079eccaf
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
@@ -0,0 +1,161 @@
+//===-- MachOPlatform.h - Utilities for executing MachO in Orc --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for executing JIT'd MachO in Orc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
+#define LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+
+#include <future>
+#include <thread>
+#include <vector>
+
+namespace llvm {
+namespace orc {
+
+/// Enable registration of JIT'd ObjC classes and selectors.
+Error enableObjCRegistration(const char *PathToLibObjC);
+bool objCRegistrationEnabled();
+
+class MachOJITDylibInitializers {
+public:
+ struct SectionExtent {
+ SectionExtent() = default;
+ SectionExtent(JITTargetAddress Address, uint64_t NumPtrs)
+ : Address(Address), NumPtrs(NumPtrs) {}
+ JITTargetAddress Address = 0;
+ uint64_t NumPtrs = 0;
+ };
+
+ using RawPointerSectionList = std::vector<SectionExtent>;
+
+ void setObjCImageInfoAddr(JITTargetAddress ObjCImageInfoAddr) {
+ this->ObjCImageInfoAddr = ObjCImageInfoAddr;
+ }
+
+ void addModInitsSection(SectionExtent ModInit) {
+ ModInitSections.push_back(std::move(ModInit));
+ }
+
+ const RawPointerSectionList &getModInitsSections() const {
+ return ModInitSections;
+ }
+
+ void addObjCSelRefsSection(SectionExtent ObjCSelRefs) {
+ ObjCSelRefsSections.push_back(std::move(ObjCSelRefs));
+ }
+
+ const RawPointerSectionList &getObjCSelRefsSections() const {
+ return ObjCSelRefsSections;
+ }
+
+ void addObjCClassListSection(SectionExtent ObjCClassList) {
+ ObjCClassListSections.push_back(std::move(ObjCClassList));
+ }
+
+ const RawPointerSectionList &getObjCClassListSections() const {
+ return ObjCClassListSections;
+ }
+
+ void runModInits() const;
+ void registerObjCSelectors() const;
+ Error registerObjCClasses() const;
+
+private:
+
+ JITTargetAddress ObjCImageInfoAddr;
+ RawPointerSectionList ModInitSections;
+ RawPointerSectionList ObjCSelRefsSections;
+ RawPointerSectionList ObjCClassListSections;
+};
+
+class MachOJITDylibDeinitializers {};
+
+/// Mediates between MachO initialization and ExecutionSession state.
+class MachOPlatform : public Platform {
+public:
+ using InitializerSequence =
+ std::vector<std::pair<JITDylib *, MachOJITDylibInitializers>>;
+
+ using DeinitializerSequence =
+ std::vector<std::pair<JITDylib *, MachOJITDylibDeinitializers>>;
+
+ MachOPlatform(ExecutionSession &ES, ObjectLinkingLayer &ObjLinkingLayer,
+ std::unique_ptr<MemoryBuffer> StandardSymbolsObject);
+
+ ExecutionSession &getExecutionSession() const { return ES; }
+
+ Error setupJITDylib(JITDylib &JD) override;
+ Error notifyAdding(JITDylib &JD, const MaterializationUnit &MU) override;
+ Error notifyRemoving(JITDylib &JD, VModuleKey K) override;
+
+ Expected<InitializerSequence> getInitializerSequence(JITDylib &JD);
+
+ Expected<DeinitializerSequence> getDeinitializerSequence(JITDylib &JD);
+
+private:
+ // This ObjectLinkingLayer plugin scans JITLink graphs for __mod_init_func,
+ // __objc_classlist and __sel_ref sections and records their extents so that
+ // they can be run in the target process.
+ class InitScraperPlugin : public ObjectLinkingLayer::Plugin {
+ public:
+ InitScraperPlugin(MachOPlatform &MP) : MP(MP) {}
+
+ void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
+ jitlink::PassConfiguration &Config) override;
+
+ LocalDependenciesMap getSyntheticSymbolLocalDependencies(
+ MaterializationResponsibility &MR) override;
+
+ private:
+ using InitSymbolDepMap =
+ DenseMap<MaterializationResponsibility *, JITLinkSymbolVector>;
+
+ void preserveInitSectionIfPresent(JITLinkSymbolVector &Syms,
+ jitlink::LinkGraph &G,
+ StringRef SectionName);
+
+ Error processObjCImageInfo(jitlink::LinkGraph &G,
+ MaterializationResponsibility &MR);
+
+ std::mutex InitScraperMutex;
+ MachOPlatform &MP;
+ DenseMap<JITDylib *, std::pair<uint32_t, uint32_t>> ObjCImageInfos;
+ InitSymbolDepMap InitSymbolDeps;
+ };
+
+ static std::vector<JITDylib *> getDFSLinkOrder(JITDylib &JD);
+
+ void registerInitInfo(JITDylib &JD, JITTargetAddress ObjCImageInfoAddr,
+ MachOJITDylibInitializers::SectionExtent ModInits,
+ MachOJITDylibInitializers::SectionExtent ObjCSelRefs,
+ MachOJITDylibInitializers::SectionExtent ObjCClassList);
+
+ ExecutionSession &ES;
+ ObjectLinkingLayer &ObjLinkingLayer;
+ std::unique_ptr<MemoryBuffer> StandardSymbolsObject;
+
+ DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;
+
+ // InitSeqs gets its own mutex to avoid locking the whole session when
+ // aggregating data from the jitlink.
+ std::mutex InitSeqsMutex;
+ DenseMap<JITDylib *, MachOJITDylibInitializers> InitSeqs;
+};
+
+} // end namespace orc
+} // end namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_MACHOPLATFORM_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h
new file mode 100644
index 000000000000..e0f770a601fb
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Mangling.h
@@ -0,0 +1,66 @@
+//===------ Mangling.h -- Name Mangling Utilities for ORC -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Name mangling utilities for ORC.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_ORC_MANGLING_H
+#define LLVM_EXECUTIONENGINE_ORC_MANGLING_H
+
+#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+namespace llvm {
+namespace orc {
+
+/// Mangles symbol names then uniques them in the context of an
+/// ExecutionSession.
+class MangleAndInterner {
+public:
+ MangleAndInterner(ExecutionSession &ES, const DataLayout &DL);
+ SymbolStringPtr operator()(StringRef Name);
+
+private:
+ ExecutionSession &ES;
+ const DataLayout &DL;
+};
+
+/// Maps IR global values to their linker symbol names / flags.
+///
+/// This utility can be used when adding new IR globals in the JIT.
+class IRSymbolMapper {
+public:
+ struct ManglingOptions {
+ bool EmulatedTLS = false;
+ };
+
+ using SymbolNameToDefinitionMap = std::map<SymbolStringPtr, GlobalValue *>;
+
+ /// Add mangled symbols for the given GlobalValues to SymbolFlags.
+ /// If a SymbolToDefinitionMap pointer is supplied then it will be populated
+ /// with Name-to-GlobalValue* mappings. Note that this mapping is not
+ /// necessarily one-to-one: thread-local GlobalValues, for example, may
+ /// produce more than one symbol, in which case the map will contain duplicate
+ /// values.
+ static void add(ExecutionSession &ES, const ManglingOptions &MO,
+ ArrayRef<GlobalValue *> GVs, SymbolFlagsMap &SymbolFlags,
+ SymbolNameToDefinitionMap *SymbolToDefinition = nullptr);
+};
+
+/// Returns a SymbolFlagsMap for the object file represented by the given
+/// buffer, or an error if the buffer does not contain a valid object file.
+Expected<std::pair<SymbolFlagsMap, SymbolStringPtr>>
+getObjectSymbolInfo(ExecutionSession &ES, MemoryBufferRef ObjBuffer);
+
+} // End namespace orc
+} // End namespace llvm
+
+#endif // LLVM_EXECUTIONENGINE_ORC_MANGLING_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 50d25f18891e..2bfe3b001709 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -35,6 +35,7 @@ namespace llvm {
namespace jitlink {
class EHFrameRegistrar;
+class Symbol;
} // namespace jitlink
namespace object {
@@ -59,10 +60,14 @@ public:
/// configured.
class Plugin {
public:
+ using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;
+ using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;
+
virtual ~Plugin();
virtual void modifyPassConfig(MaterializationResponsibility &MR,
const Triple &TT,
jitlink::PassConfiguration &Config) {}
+
virtual void notifyLoaded(MaterializationResponsibility &MR) {}
virtual Error notifyEmitted(MaterializationResponsibility &MR) {
return Error::success();
@@ -71,6 +76,15 @@ public:
return Error::success();
}
virtual Error notifyRemovingAllModules() { return Error::success(); }
+
+ /// Return any dependencies that synthetic symbols (e.g. init symbols)
+ /// have on locally scoped jitlink::Symbols. This is used by the
+ /// ObjectLinkingLayer to update the dependencies for the synthetic
+ /// symbols.
+ virtual LocalDependenciesMap
+ getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {
+ return LocalDependenciesMap();
+ }
};
using ReturnObjectBufferFunction =
@@ -170,6 +184,7 @@ private:
size_t Size;
};
+ std::mutex EHFramePluginMutex;
jitlink::EHFrameRegistrar &Registrar;
DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
DenseMap<VModuleKey, EHFrameRange> TrackedEHFrameRanges;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
index 2e58ddd75d31..5061c15cf4c9 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcABISupport.h
@@ -20,13 +20,33 @@
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Memory.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
#include <cstdint>
namespace llvm {
namespace orc {
+struct IndirectStubsAllocationSizes {
+ uint64_t StubBytes = 0;
+ uint64_t PointerBytes = 0;
+ unsigned NumStubs = 0;
+};
+
+template <typename ORCABI>
+IndirectStubsAllocationSizes
+getIndirectStubsBlockSizes(unsigned MinStubs, unsigned RoundToMultipleOf = 0) {
+ assert(
+ (RoundToMultipleOf == 0 || (RoundToMultipleOf % ORCABI::StubSize == 0)) &&
+ "RoundToMultipleOf is not a multiple of stub size");
+ uint64_t StubBytes = MinStubs * ORCABI::StubSize;
+ if (RoundToMultipleOf)
+ StubBytes = alignTo(StubBytes, RoundToMultipleOf);
+ unsigned NumStubs = StubBytes / ORCABI::StubSize;
+ uint64_t PointerBytes = NumStubs * ORCABI::PointerSize;
+ return {StubBytes, PointerBytes, NumStubs};
+}
+
/// Generic ORC ABI support.
///
/// This class can be substituted as the target architecture support class for
@@ -35,113 +55,72 @@ namespace orc {
/// will result in execution of an llvm_unreachable.
class OrcGenericABI {
public:
- static const unsigned PointerSize = sizeof(uintptr_t);
- static const unsigned TrampolineSize = 1;
- static const unsigned ResolverCodeSize = 1;
-
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
-
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
- void *CallbackMgr) {
+ static constexpr unsigned PointerSize = sizeof(uintptr_t);
+ static constexpr unsigned TrampolineSize = 1;
+ static constexpr unsigned StubSize = 1;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1;
+ static constexpr unsigned ResolverCodeSize = 1;
+
+ static void writeResolverCode(char *ResolveWorkingMem,
+ JITTargetAddress ResolverTargetAddr,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) {
llvm_unreachable("writeResolverCode is not supported by the generic host "
"support class");
}
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddr,
+ JITTargetAddress ResolverAddr,
unsigned NumTrampolines) {
llvm_unreachable("writeTrampolines is not supported by the generic host "
"support class");
}
- class IndirectStubsInfo {
- public:
- const static unsigned StubSize = 1;
-
- unsigned getNumStubs() const { llvm_unreachable("Not supported"); }
- void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }
- void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }
- };
-
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
- unsigned MinStubs, void *InitialPtrVal) {
- llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "
- "host support class");
- }
-};
-
-/// Provide information about stub blocks generated by the
-/// makeIndirectStubsBlock function.
-template <unsigned StubSizeVal> class GenericIndirectStubsInfo {
-public:
- const static unsigned StubSize = StubSizeVal;
-
- GenericIndirectStubsInfo() = default;
- GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
- : NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
- GenericIndirectStubsInfo(GenericIndirectStubsInfo &&Other)
- : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
- Other.NumStubs = 0;
- }
-
- GenericIndirectStubsInfo &operator=(GenericIndirectStubsInfo &&Other) {
- NumStubs = Other.NumStubs;
- Other.NumStubs = 0;
- StubsMem = std::move(Other.StubsMem);
- return *this;
- }
-
- /// Number of stubs in this block.
- unsigned getNumStubs() const { return NumStubs; }
-
- /// Get a pointer to the stub at the given index, which must be in
- /// the range 0 .. getNumStubs() - 1.
- void *getStub(unsigned Idx) const {
- return static_cast<char *>(StubsMem.base()) + Idx * StubSize;
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs) {
+ llvm_unreachable(
+ "writeIndirectStubsBlock is not supported by the generic host "
+ "support class");
}
-
- /// Get a pointer to the implementation-pointer at the given index,
- /// which must be in the range 0 .. getNumStubs() - 1.
- void **getPtr(unsigned Idx) const {
- char *PtrsBase = static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;
- return reinterpret_cast<void **>(PtrsBase) + Idx;
- }
-
-private:
- unsigned NumStubs = 0;
- sys::OwningMemoryBlock StubsMem;
};
class OrcAArch64 {
public:
- static const unsigned PointerSize = 8;
- static const unsigned TrampolineSize = 12;
- static const unsigned ResolverCodeSize = 0x120;
-
- using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
-
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
+ static constexpr unsigned PointerSize = 8;
+ static constexpr unsigned TrampolineSize = 12;
+ static constexpr unsigned StubSize = 8;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1U << 27;
+ static constexpr unsigned ResolverCodeSize = 0x120;
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
- void *CallbackMgr);
+ ///
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress RentryCtxAddr);
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
/// trampolines.
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverAddr,
unsigned NumTrampolines);
- /// Emit at least MinStubs worth of indirect call stubs, rounded out to
- /// the nearest page size.
- ///
- /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
- /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
- /// will return a block of 1024 (2-pages worth).
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
- unsigned MinStubs, void *InitialPtrVal);
+ /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+ /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+ /// Nth stub using the Nth pointer in memory starting at
+ /// PointersBlockTargetAddress.
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned MinStubs);
};
/// X86_64 code that's common to all ABIs.
@@ -149,25 +128,26 @@ public:
/// X86_64 supports lazy JITing.
class OrcX86_64_Base {
public:
- static const unsigned PointerSize = 8;
- static const unsigned TrampolineSize = 8;
-
- using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
+ static constexpr unsigned PointerSize = 8;
+ static constexpr unsigned TrampolineSize = 8;
+ static constexpr unsigned StubSize = 8;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
/// trampolines.
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverAddr,
unsigned NumTrampolines);
- /// Emit at least MinStubs worth of indirect call stubs, rounded out to
- /// the nearest page size.
- ///
- /// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
- /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
- /// will return a block of 1024 (2-pages worth).
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
- unsigned MinStubs, void *InitialPtrVal);
+ /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+ /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+ /// Nth stub using the Nth pointer in memory starting at
+ /// PointersBlockTargetAddress.
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
};
/// X86_64 support for SysV ABI (Linux, MacOSX).
@@ -175,15 +155,19 @@ public:
/// X86_64_SysV supports lazy JITing.
class OrcX86_64_SysV : public OrcX86_64_Base {
public:
- static const unsigned ResolverCodeSize = 0x6C;
-
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
+ static constexpr unsigned ResolverCodeSize = 0x6C;
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
- void *CallbackMgr);
+ ///
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
};
/// X86_64 support for Win32.
@@ -191,15 +175,19 @@ public:
/// X86_64_Win32 supports lazy JITing.
class OrcX86_64_Win32 : public OrcX86_64_Base {
public:
- static const unsigned ResolverCodeSize = 0x74;
-
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
+ static constexpr unsigned ResolverCodeSize = 0x74;
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
- void *CallbackMgr);
+ ///
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
};
/// I386 support.
@@ -207,34 +195,39 @@ public:
/// I386 supports lazy JITing.
class OrcI386 {
public:
- static const unsigned PointerSize = 4;
- static const unsigned TrampolineSize = 8;
- static const unsigned ResolverCodeSize = 0x4a;
-
- using IndirectStubsInfo = GenericIndirectStubsInfo<8>;
-
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
+ static constexpr unsigned PointerSize = 4;
+ static constexpr unsigned TrampolineSize = 8;
+ static constexpr unsigned StubSize = 8;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+ static constexpr unsigned ResolverCodeSize = 0x4a;
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
- void *CallbackMgr);
+ ///
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
/// trampolines.
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverAddr,
unsigned NumTrampolines);
- /// Emit at least MinStubs worth of indirect call stubs, rounded out to
- /// the nearest page size.
- ///
- /// E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k
- /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
- /// will return a block of 1024 (2-pages worth).
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
- unsigned MinStubs, void *InitialPtrVal);
+ /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+ /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+ /// Nth stub using the Nth pointer in memory starting at
+ /// PointersBlockTargetAddress.
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
};
// @brief Mips32 support.
@@ -242,41 +235,61 @@ public:
// Mips32 supports lazy JITing.
class OrcMips32_Base {
public:
- static const unsigned PointerSize = 4;
- static const unsigned TrampolineSize = 20;
- static const unsigned ResolverCodeSize = 0xfc;
- using IndirectStubsInfo = GenericIndirectStubsInfo<16>;
+ static constexpr unsigned PointerSize = 4;
+ static constexpr unsigned TrampolineSize = 20;
+ static constexpr unsigned StubSize = 8;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+ static constexpr unsigned ResolverCodeSize = 0xfc;
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
/// trampolines.
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverAddr,
+ unsigned NumTrampolines);
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr, bool isBigEndian);
- /// Emit at least MinStubs worth of indirect call stubs, rounded out to
- /// the nearest page size.
///
- /// E.g. Asking for 4 stubs on Mips32, where stubs are 8-bytes, with 4k
- /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
- /// will return a block of 1024 (2-pages worth).
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverBlockWorkingMem,
+ JITTargetAddress ResolverBlockTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr,
+ bool isBigEndian);
+ /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+ /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+ /// Nth stub using the Nth pointer in memory starting at
+ /// PointersBlockTargetAddress.
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
};
-
class OrcMips32Le : public OrcMips32_Base {
public:
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
- { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, false); }
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) {
+ OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
+ ReentryFnAddr, ReentryCtxAddr, false);
+ }
};
class OrcMips32Be : public OrcMips32_Base {
public:
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr)
- { OrcMips32_Base::writeResolverCode(ResolveMem, Reentry, CallbackMgr, true); }
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr) {
+ OrcMips32_Base::writeResolverCode(ResolverWorkingMem, ResolverTargetAddress,
+ ReentryFnAddr, ReentryCtxAddr, true);
+ }
};
// @brief Mips64 support.
@@ -284,31 +297,41 @@ public:
// Mips64 supports lazy JITing.
class OrcMips64 {
public:
- static const unsigned PointerSize = 8;
- static const unsigned TrampolineSize = 40;
- static const unsigned ResolverCodeSize = 0x120;
+ static constexpr unsigned PointerSize = 8;
+ static constexpr unsigned TrampolineSize = 40;
+ static constexpr unsigned StubSize = 32;
+ static constexpr unsigned StubToPointerMaxDisplacement = 1 << 31;
+ static constexpr unsigned ResolverCodeSize = 0x120;
- using IndirectStubsInfo = GenericIndirectStubsInfo<32>;
- using JITReentryFn = JITTargetAddress (*)(void *CallbackMgr,
- void *TrampolineId);
/// Write the resolver code into the given memory. The user is
/// responsible for allocating the memory and setting permissions.
- static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,void *CallbackMgr);
+ ///
+ /// ReentryFnAddr should be the address of a function whose signature matches
+ /// void* (*)(void *TrampolineAddr, void *ReentryCtxAddr). The ReentryCtxAddr
+ /// argument of writeResolverCode will be passed as the second argument to
+ /// the function at ReentryFnAddr.
+ static void writeResolverCode(char *ResolverWorkingMem,
+ JITTargetAddress ResolverTargetAddress,
+ JITTargetAddress ReentryFnAddr,
+ JITTargetAddress ReentryCtxAddr);
/// Write the requested number of trampolines into the given memory,
/// which must be big enough to hold 1 pointer, plus NumTrampolines
/// trampolines.
- static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,unsigned NumTrampolines);
-
- /// Emit at least MinStubs worth of indirect call stubs, rounded out to
- /// the nearest page size.
- ///
- /// E.g. Asking for 4 stubs on Mips64, where stubs are 8-bytes, with 4k
- /// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
- /// will return a block of 1024 (2-pages worth).
- static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,unsigned MinStubs, void *InitialPtrVal);
+ static void writeTrampolines(char *TrampolineBlockWorkingMem,
+ JITTargetAddress TrampolineBlockTargetAddress,
+ JITTargetAddress ResolverFnAddr,
+ unsigned NumTrampolines);
+ /// Write NumStubs indirect stubs to working memory at StubsBlockWorkingMem.
+ /// Stubs will be written as if linked at StubsBlockTargetAddress, with the
+ /// Nth stub using the Nth pointer in memory starting at
+ /// PointersBlockTargetAddress.
+ static void writeIndirectStubsBlock(
+ char *StubsBlockWorkingMem, JITTargetAddress StubsBlockTargetAddress,
+ JITTargetAddress PointersBlockTargetAddress, unsigned NumStubs);
};
- } // end namespace orc
- } // end namespace llvm
+} // end namespace orc
+} // end namespace llvm
+
#endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
index 61e2e49a872a..9b0d941f5459 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcError.h
@@ -37,7 +37,9 @@ enum class OrcErrorCode : int {
UnexpectedRPCCall,
UnexpectedRPCResponse,
UnknownErrorCodeFromRemote,
- UnknownResourceHandle
+ UnknownResourceHandle,
+ MissingSymbolDefinitions,
+ UnexpectedSymbolDefinitions,
};
std::error_code orcError(OrcErrorCode ErrCode);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
index 3ff5a5f6e90e..52a328165240 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h
@@ -108,8 +108,7 @@ public:
template <typename ChannelT>
class SerializationTraits<
ChannelT, remote::DirectBufferWriter, remote::DirectBufferWriter,
- typename std::enable_if<
- std::is_base_of<RawByteChannel, ChannelT>::value>::type> {
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
static Error serialize(ChannelT &C, const remote::DirectBufferWriter &DBW) {
if (auto EC = serializeSeq(C, DBW.getDst()))
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
index 4c8e2ea1a7be..50c155d77db1 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h
@@ -15,6 +15,7 @@
#define LLVM_EXECUTIONENGINE_ORC_ORCREMOTETARGETSERVER_H
#include "llvm/ExecutionEngine/JITSymbol.h"
+#include "llvm/ExecutionEngine/Orc/IndirectionUtils.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
#include "llvm/Support/Debug.h"
@@ -60,7 +61,7 @@ public:
SymbolLookup(std::move(SymbolLookup)),
EHFramesRegister(std::move(EHFramesRegister)),
EHFramesDeregister(std::move(EHFramesDeregister)) {
- using ThisT = typename std::remove_reference<decltype(*this)>::type;
+ using ThisT = std::remove_reference_t<decltype(*this)>;
addHandler<exec::CallIntVoid>(*this, &ThisT::handleCallIntVoid);
addHandler<exec::CallMain>(*this, &ThisT::handleCallMain);
addHandler<exec::CallVoidVoid>(*this, &ThisT::handleCallVoidVoid);
@@ -262,19 +263,17 @@ private:
return errorCodeToError(
orcError(OrcErrorCode::RemoteIndirectStubsOwnerDoesNotExist));
- typename TargetT::IndirectStubsInfo IS;
- if (auto Err =
- TargetT::emitIndirectStubsBlock(IS, NumStubsRequired, nullptr))
- return std::move(Err);
+ auto IS = LocalIndirectStubsInfo<TargetT>::create(
+ NumStubsRequired, sys::Process::getPageSizeEstimate());
+ if (!IS)
+ return IS.takeError();
- JITTargetAddress StubsBase = static_cast<JITTargetAddress>(
- reinterpret_cast<uintptr_t>(IS.getStub(0)));
- JITTargetAddress PtrsBase = static_cast<JITTargetAddress>(
- reinterpret_cast<uintptr_t>(IS.getPtr(0)));
- uint32_t NumStubsEmitted = IS.getNumStubs();
+ JITTargetAddress StubsBase = pointerToJITTargetAddress(IS->getStub(0));
+ JITTargetAddress PtrsBase = pointerToJITTargetAddress(IS->getPtr(0));
+ uint32_t NumStubsEmitted = IS->getNumStubs();
auto &BlockList = StubOwnerItr->second;
- BlockList.push_back(std::move(IS));
+ BlockList.push_back(std::move(*IS));
return std::make_tuple(StubsBase, PtrsBase, NumStubsEmitted);
}
@@ -287,8 +286,10 @@ private:
if (EC)
return errorCodeToError(EC);
- TargetT::writeResolverCode(static_cast<uint8_t *>(ResolverBlock.base()),
- &reenter, this);
+ TargetT::writeResolverCode(static_cast<char *>(ResolverBlock.base()),
+ pointerToJITTargetAddress(ResolverBlock.base()),
+ pointerToJITTargetAddress(&reenter),
+ pointerToJITTargetAddress(this));
return errorCodeToError(sys::Memory::protectMappedMemory(
ResolverBlock.getMemoryBlock(),
@@ -308,9 +309,10 @@ private:
(sys::Process::getPageSizeEstimate() - TargetT::PointerSize) /
TargetT::TrampolineSize;
- uint8_t *TrampolineMem = static_cast<uint8_t *>(TrampolineBlock.base());
- TargetT::writeTrampolines(TrampolineMem, ResolverBlock.base(),
- NumTrampolines);
+ char *TrampolineMem = static_cast<char *>(TrampolineBlock.base());
+ TargetT::writeTrampolines(
+ TrampolineMem, pointerToJITTargetAddress(TrampolineMem),
+ pointerToJITTargetAddress(ResolverBlock.base()), NumTrampolines);
EC = sys::Memory::protectMappedMemory(TrampolineBlock.getMemoryBlock(),
sys::Memory::MF_READ |
@@ -318,10 +320,8 @@ private:
TrampolineBlocks.push_back(std::move(TrampolineBlock));
- auto TrampolineBaseAddr = static_cast<JITTargetAddress>(
- reinterpret_cast<uintptr_t>(TrampolineMem));
-
- return std::make_tuple(TrampolineBaseAddr, NumTrampolines);
+ return std::make_tuple(pointerToJITTargetAddress(TrampolineMem),
+ NumTrampolines);
}
Expected<JITTargetAddress> handleGetSymbolAddress(const std::string &Name) {
@@ -337,7 +337,7 @@ private:
uint32_t PointerSize = TargetT::PointerSize;
uint32_t PageSize = sys::Process::getPageSizeEstimate();
uint32_t TrampolineSize = TargetT::TrampolineSize;
- uint32_t IndirectStubSize = TargetT::IndirectStubsInfo::StubSize;
+ uint32_t IndirectStubSize = TargetT::StubSize;
LLVM_DEBUG(dbgs() << " Remote info:\n"
<< " triple = '" << ProcessTriple << "'\n"
<< " pointer size = " << PointerSize << "\n"
@@ -433,7 +433,7 @@ private:
SymbolLookupFtor SymbolLookup;
EHFrameRegistrationFtor EHFramesRegister, EHFramesDeregister;
std::map<ResourceIdMgr::ResourceId, Allocator> Allocators;
- using ISBlockOwnerList = std::vector<typename TargetT::IndirectStubsInfo>;
+ using ISBlockOwnerList = std::vector<LocalIndirectStubsInfo<TargetT>>;
std::map<ResourceIdMgr::ResourceId, ISBlockOwnerList> IndirectStubsOwners;
sys::OwningMemoryBlock ResolverBlock;
std::vector<sys::OwningMemoryBlock> TrampolineBlocks;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h
index 9c69a84f4c67..2f37ab40c7f8 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h
@@ -230,9 +230,9 @@ public:
///
/// template <DerivedChannelT>
/// class SerializationTraits<DerivedChannelT, bool,
-/// typename std::enable_if<
+/// std::enable_if_t<
/// std::is_base_of<VirtChannel, DerivedChannel>::value
-/// >::type> {
+/// >> {
/// public:
/// static const char* getName() { ... };
/// }
@@ -274,9 +274,8 @@ public:
template <typename CArgT>
static Error serialize(ChannelT &C, CArgT &&CArg) {
- return SerializationTraits<ChannelT, ArgT,
- typename std::decay<CArgT>::type>::
- serialize(C, std::forward<CArgT>(CArg));
+ return SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+ C, std::forward<CArgT>(CArg));
}
template <typename CArgT>
@@ -293,8 +292,8 @@ public:
static Error serialize(ChannelT &C, CArgT &&CArg,
CArgTs &&... CArgs) {
if (auto Err =
- SerializationTraits<ChannelT, ArgT, typename std::decay<CArgT>::type>::
- serialize(C, std::forward<CArgT>(CArg)))
+ SerializationTraits<ChannelT, ArgT, std::decay_t<CArgT>>::serialize(
+ C, std::forward<CArgT>(CArg)))
return Err;
if (auto Err = SequenceTraits<ChannelT>::emitSeparator(C))
return Err;
@@ -316,8 +315,8 @@ public:
template <typename ChannelT, typename... ArgTs>
Error serializeSeq(ChannelT &C, ArgTs &&... Args) {
- return SequenceSerialization<ChannelT, typename std::decay<ArgTs>::type...>::
- serialize(C, std::forward<ArgTs>(Args)...);
+ return SequenceSerialization<ChannelT, std::decay_t<ArgTs>...>::serialize(
+ C, std::forward<ArgTs>(Args)...);
}
template <typename ChannelT, typename... ArgTs>
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h
index ed09363dcecc..f348844f39ce 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCUtils.h
@@ -184,8 +184,7 @@ template <typename T, typename = void> class RPCFunctionIdAllocator;
/// This specialization of RPCFunctionIdAllocator provides a default
/// implementation for integral types.
template <typename T>
-class RPCFunctionIdAllocator<
- T, typename std::enable_if<std::is_integral<T>::value>::type> {
+class RPCFunctionIdAllocator<T, std::enable_if_t<std::is_integral<T>::value>> {
public:
static T getInvalidId() { return T(0); }
static T getResponseId() { return T(1); }
@@ -205,8 +204,7 @@ template <typename T> class FunctionArgsTuple;
template <typename RetT, typename... ArgTs>
class FunctionArgsTuple<RetT(ArgTs...)> {
public:
- using Type = std::tuple<typename std::decay<
- typename std::remove_reference<ArgTs>::type>::type...>;
+ using Type = std::tuple<std::decay_t<std::remove_reference_t<ArgTs>>...>;
};
// ResultTraits provides typedefs and utilities specific to the return type
@@ -483,9 +481,9 @@ public:
};
template <typename ResponseHandlerT, typename... ArgTs>
-class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)> :
- public AsyncHandlerTraits<Error(typename std::decay<ResponseHandlerT>::type,
- ArgTs...)> {};
+class AsyncHandlerTraits<Error(ResponseHandlerT, ArgTs...)>
+ : public AsyncHandlerTraits<Error(std::decay_t<ResponseHandlerT>,
+ ArgTs...)> {};
// This template class provides utilities related to RPC function handlers.
// The base case applies to non-function types (the template class is
@@ -524,18 +522,17 @@ public:
// Call the given handler with the given arguments.
template <typename HandlerT>
- static typename std::enable_if<
- std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
- Error>::type
+ static std::enable_if_t<
+ std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value, Error>
run(HandlerT &Handler, ArgTs &&... Args) {
Handler(std::move(Args)...);
return Error::success();
}
template <typename HandlerT, typename... TArgTs>
- static typename std::enable_if<
+ static std::enable_if_t<
!std::is_void<typename HandlerTraits<HandlerT>::ReturnType>::value,
- typename HandlerTraits<HandlerT>::ReturnType>::type
+ typename HandlerTraits<HandlerT>::ReturnType>
run(HandlerT &Handler, TArgTs... Args) {
return Handler(std::move(Args)...);
}
@@ -894,12 +891,12 @@ private:
using S = SerializationTraits<ChannelT, WireT, ConcreteT>;
template <typename T>
- static std::true_type
- check(typename std::enable_if<
- std::is_same<decltype(T::serialize(std::declval<ChannelT &>(),
- std::declval<const ConcreteT &>())),
- Error>::value,
- void *>::type);
+ static std::true_type check(
+ std::enable_if_t<std::is_same<decltype(T::serialize(
+ std::declval<ChannelT &>(),
+ std::declval<const ConcreteT &>())),
+ Error>::value,
+ void *>);
template <typename> static std::false_type check(...);
@@ -914,11 +911,11 @@ private:
template <typename T>
static std::true_type
- check(typename std::enable_if<
- std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
- std::declval<ConcreteT &>())),
- Error>::value,
- void *>::type);
+ check(std::enable_if_t<
+ std::is_same<decltype(T::deserialize(std::declval<ChannelT &>(),
+ std::declval<ConcreteT &>())),
+ Error>::value,
+ void *>);
template <typename> static std::false_type check(...);
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h
index 50e26f8449df..35745993248c 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RPC/RawByteChannel.h
@@ -87,13 +87,13 @@ private:
template <typename ChannelT, typename T>
class SerializationTraits<
ChannelT, T, T,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<RawByteChannel, ChannelT>::value &&
(std::is_same<T, uint8_t>::value || std::is_same<T, int8_t>::value ||
std::is_same<T, uint16_t>::value || std::is_same<T, int16_t>::value ||
std::is_same<T, uint32_t>::value || std::is_same<T, int32_t>::value ||
std::is_same<T, uint64_t>::value || std::is_same<T, int64_t>::value ||
- std::is_same<T, char>::value)>::type> {
+ std::is_same<T, char>::value)>> {
public:
static Error serialize(ChannelT &C, T V) {
support::endian::byte_swap<T, support::big>(V);
@@ -109,9 +109,9 @@ public:
};
template <typename ChannelT>
-class SerializationTraits<ChannelT, bool, bool,
- typename std::enable_if<std::is_base_of<
- RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+ ChannelT, bool, bool,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
static Error serialize(ChannelT &C, bool V) {
uint8_t Tmp = V ? 1 : 0;
@@ -131,9 +131,9 @@ public:
};
template <typename ChannelT>
-class SerializationTraits<ChannelT, std::string, StringRef,
- typename std::enable_if<std::is_base_of<
- RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+ ChannelT, std::string, StringRef,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
/// RPC channel serialization for std::strings.
static Error serialize(RawByteChannel &C, StringRef S) {
@@ -144,11 +144,11 @@ public:
};
template <typename ChannelT, typename T>
-class SerializationTraits<ChannelT, std::string, T,
- typename std::enable_if<
- std::is_base_of<RawByteChannel, ChannelT>::value &&
- (std::is_same<T, const char*>::value ||
- std::is_same<T, char*>::value)>::type> {
+class SerializationTraits<
+ ChannelT, std::string, T,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value &&
+ (std::is_same<T, const char *>::value ||
+ std::is_same<T, char *>::value)>> {
public:
static Error serialize(RawByteChannel &C, const char *S) {
return SerializationTraits<ChannelT, std::string, StringRef>::serialize(C,
@@ -157,9 +157,9 @@ public:
};
template <typename ChannelT>
-class SerializationTraits<ChannelT, std::string, std::string,
- typename std::enable_if<std::is_base_of<
- RawByteChannel, ChannelT>::value>::type> {
+class SerializationTraits<
+ ChannelT, std::string, std::string,
+ std::enable_if_t<std::is_base_of<RawByteChannel, ChannelT>::value>> {
public:
/// RPC channel serialization for std::strings.
static Error serialize(RawByteChannel &C, const std::string &S) {
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
index 091394795c0b..9ada0871cf0c 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
@@ -115,15 +116,23 @@ public:
return *this;
}
+ /// Register a JITEventListener.
+ void registerJITEventListener(JITEventListener &L);
+
+ /// Unregister a JITEventListener.
+ void unregisterJITEventListener(JITEventListener &L);
+
private:
Error onObjLoad(VModuleKey K, MaterializationResponsibility &R,
- object::ObjectFile &Obj,
+ const object::ObjectFile &Obj,
+ RuntimeDyld::MemoryManager *MemMgr,
std::unique_ptr<RuntimeDyld::LoadedObjectInfo> LoadedObjInfo,
std::map<StringRef, JITEvaluatedSymbol> Resolved,
std::set<StringRef> &InternalSymbols);
- void onObjEmit(VModuleKey K, std::unique_ptr<MemoryBuffer> ObjBuffer,
- MaterializationResponsibility &R, Error Err);
+ void onObjEmit(VModuleKey K, MaterializationResponsibility &R,
+ object::OwningBinary<object::ObjectFile> O,
+ RuntimeDyld::MemoryManager *MemMgr, Error Err);
mutable std::mutex RTDyldLayerMutex;
GetMemoryManagerFunction GetMemoryManager;
@@ -133,6 +142,10 @@ private:
bool OverrideObjectFlags = false;
bool AutoClaimObjectSymbols = false;
std::vector<std::unique_ptr<RuntimeDyld::MemoryManager>> MemMgrs;
+ std::vector<JITEventListener *> EventListeners;
+ DenseMap<RuntimeDyld::MemoryManager *,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>>
+ LoadedObjInfos;
};
class LegacyRTDyldObjectLinkingLayerBase {
@@ -170,7 +183,7 @@ protected:
if (!SymEntry->second.getFlags().isExported() && ExportedSymbolsOnly)
return nullptr;
if (!Finalized)
- return JITSymbol(getSymbolMaterializer(Name),
+ return JITSymbol(getSymbolMaterializer(std::string(Name)),
SymEntry->second.getFlags());
return JITSymbol(SymEntry->second);
}
@@ -291,8 +304,15 @@ private:
private:
void buildInitialSymbolTable(const OwnedObject &Obj) {
for (auto &Symbol : Obj.getBinary()->symbols()) {
- if (Symbol.getFlags() & object::SymbolRef::SF_Undefined)
+ if (Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags()) {
+ if (*SymbolFlagsOrErr & object::SymbolRef::SF_Undefined)
+ continue;
+ } else {
+ // FIXME: Raise an error for bad symbols.
+ consumeError(SymbolFlagsOrErr.takeError());
continue;
+ }
+
Expected<StringRef> SymbolName = Symbol.getName();
// FIXME: Raise an error for bad symbols.
if (!SymbolName) {
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
index 97a3dc365457..d8213d3b35e8 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/Speculation.h
@@ -13,10 +13,10 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
#define LLVM_EXECUTIONENGINE_ORC_SPECULATION_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
+#include "llvm/ExecutionEngine/Orc/DebugUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Passes/PassBuilder.h"
@@ -192,11 +192,10 @@ private:
internToJITSymbols(DenseMap<StringRef, DenseSet<StringRef>> IRNames) {
assert(!IRNames.empty() && "No IRNames received to Intern?");
TargetAndLikelies InternedNames;
- DenseSet<SymbolStringPtr> TargetJITNames;
for (auto &NamePair : IRNames) {
+ DenseSet<SymbolStringPtr> TargetJITNames;
for (auto &TargetNames : NamePair.second)
TargetJITNames.insert(Mangle(TargetNames));
-
InternedNames[Mangle(NamePair.first)] = std::move(TargetJITNames);
}
return InternedNames;
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
index c354f6c3559c..c9fadd727e88 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -48,11 +48,13 @@ private:
/// Pointer to a pooled string representing a symbol name.
class SymbolStringPtr {
+ friend class OrcV2CAPIHelper;
friend class SymbolStringPool;
friend struct DenseMapInfo<SymbolStringPtr>;
public:
SymbolStringPtr() = default;
+ SymbolStringPtr(std::nullptr_t) {}
SymbolStringPtr(const SymbolStringPtr &Other)
: S(Other.S) {
if (isRealPoolEntry(S))
@@ -85,6 +87,8 @@ public:
--S->getValue();
}
+ explicit operator bool() const { return S; }
+
StringRef operator*() const { return S->first(); }
friend bool operator==(const SymbolStringPtr &LHS,
@@ -103,7 +107,8 @@ public:
}
private:
- using PoolEntryPtr = SymbolStringPool::PoolMapEntry *;
+ using PoolEntry = SymbolStringPool::PoolMapEntry;
+ using PoolEntryPtr = PoolEntry *;
SymbolStringPtr(SymbolStringPool::PoolMapEntry *S)
: S(S) {
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
index 2347faed37a2..58c96737e580 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ThreadSafeModule.h
@@ -130,8 +130,7 @@ public:
/// Locks the associated ThreadSafeContext and calls the given function
/// on the contained Module.
- template <typename Func>
- auto withModuleDo(Func &&F) -> decltype(F(std::declval<Module &>())) {
+ template <typename Func> decltype(auto) withModuleDo(Func &&F) {
assert(M && "Can not call on null module");
auto Lock = TSCtx.getLock();
return F(*M);
@@ -139,9 +138,7 @@ public:
/// Locks the associated ThreadSafeContext and calls the given function
/// on the contained Module.
- template <typename Func>
- auto withModuleDo(Func &&F) const
- -> decltype(F(std::declval<const Module &>())) {
+ template <typename Func> decltype(auto) withModuleDo(Func &&F) const {
auto Lock = TSCtx.getLock();
return F(*M);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
index ce7024a7f19b..1b3ce1127e4a 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -267,15 +267,16 @@ public:
void finalizeWithMemoryManagerLocking();
private:
- friend void
- jitLinkForORC(object::ObjectFile &Obj,
- std::unique_ptr<MemoryBuffer> UnderlyingBuffer,
- RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
- bool ProcessAllSections,
- unique_function<Error(std::unique_ptr<LoadedObjectInfo>,
- std::map<StringRef, JITEvaluatedSymbol>)>
- OnLoaded,
- unique_function<void(Error)> OnEmitted);
+ friend void jitLinkForORC(
+ object::OwningBinary<object::ObjectFile> O,
+ RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
+ bool ProcessAllSections,
+ unique_function<Error(const object::ObjectFile &Obj,
+ std::unique_ptr<LoadedObjectInfo>,
+ std::map<StringRef, JITEvaluatedSymbol>)>
+ OnLoaded,
+ unique_function<void(object::OwningBinary<object::ObjectFile> O, Error)>
+ OnEmitted);
// RuntimeDyldImpl is the actual class. RuntimeDyld is just the public
// interface.
@@ -293,13 +294,15 @@ private:
// instance and uses continuation passing to perform the fix-up and finalize
// steps asynchronously.
void jitLinkForORC(
- object::ObjectFile &Obj, std::unique_ptr<MemoryBuffer> UnderlyingBuffer,
+ object::OwningBinary<object::ObjectFile> O,
RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
bool ProcessAllSections,
- unique_function<Error(std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
+ unique_function<Error(const object::ObjectFile &Obj,
+ std::unique_ptr<RuntimeDyld::LoadedObjectInfo>,
std::map<StringRef, JITEvaluatedSymbol>)>
OnLoaded,
- unique_function<void(Error)> OnEmitted);
+ unique_function<void(object::OwningBinary<object::ObjectFile>, Error)>
+ OnEmitted);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h
index d7316425da2f..49956fab17ce 100644
--- a/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -15,7 +15,6 @@
#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/Memory.h"
#include <cstdint>
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/Directive/DirectiveBase.td b/contrib/llvm-project/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
new file mode 100644
index 000000000000..26049ca60db3
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/Directive/DirectiveBase.td
@@ -0,0 +1,109 @@
+//===-- DirectiveBase.td - Base directive definition file --*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the base definition file directives and clauses.
+//
+//===----------------------------------------------------------------------===//
+
+
+// General information about the directive language.
+class DirectiveLanguage {
+ // Name of the directive language such as omp or acc.
+ string name = ?;
+
+ // The C++ namespace that code of this directive language should be placed
+ // into. This namespace is nested in llvm namespace.
+ //
+ // By default, uses the name of the directive language as the only namespace.
+ // To avoid placing in any namespace, use "". To specify nested namespaces,
+ // use "::" as the delimiter, e.g., given "A::B", ops will be placed in
+ // `namespace A { namespace B { <directives-clauses> } }`.
+ string cppNamespace = name;
+
+ // Optional prefix used for the generation of the enumerator in the Directive
+ // enum.
+ string directivePrefix = "";
+
+ // Optional prefix used for the generation of the enumerator in the Clause
+ // enum.
+ string clausePrefix = "";
+
+ // Make the enum values available in the namespace. This allows us to
+ // write something like Enum_X if we have a `using namespace cppNamespace`.
+ bit makeEnumAvailableInNamespace = 0;
+
+ // Generate include and macro to enable LLVM BitmaskEnum.
+ bit enableBitmaskEnumInNamespace = 0;
+
+ // Header file included in the implementation code generated. Ususally the
+ // output file of the declaration code generation. Can be left blank.
+ string includeHeader = "";
+
+ // EnumSet class name used for clauses to generated the allowed clauses map.
+ string clauseEnumSetClass = "";
+}
+
+// Information about a specific clause.
+class Clause<string c> {
+ // Name of the clause.
+ string name = c;
+
+ // Define an alternative name return in get<LanguageName>ClauseName function.
+ string alternativeName = "";
+
+ // Optional class holding value of the clause in clang AST.
+ string clangClass = ?;
+
+ // Optional class holding value of the clause in flang AST.
+ string flangClass = ?;
+
+ // Is clause implicit? If clause is set as implicit, the default kind will
+ // be return in get<LanguageName>ClauseKind instead of their own kind.
+ bit isImplicit = 0;
+
+ // Set directive used by default when unknown. Function returning the kind
+ // of enumeration will use this clause as the default.
+ bit isDefault = 0;
+}
+
+// Hold information about clause validity by version.
+class VersionedClause<Clause c, int min = 1, int max = 0x7FFFFFFF> {
+ // Actual clause.
+ Clause clause = c;
+
+ // Mininum version number where this clause is valid.
+ int minVersion = min;
+
+ // Maximum version number where this clause is valid.
+ int maxVersion = max;
+}
+
+// Information about a specific directive.
+class Directive<string d> {
+ // Name of the directive. Can be composite directive sepearted by whitespace.
+ string name = d;
+
+ // Define an alternative name return in get<LanguageName>DirectiveName
+ // function.
+ string alternativeName = "";
+
+ // List of allowed clauses for the directive.
+ list<VersionedClause> allowedClauses = [];
+
+ // List of clauses that are allowed to appear only once.
+ list<VersionedClause> allowedOnceClauses = [];
+
+ // List of clauses that are allowed but mutually exclusive.
+ list<VersionedClause> allowedExclusiveClauses = [];
+
+ // List of clauses that are required.
+ list<VersionedClause> requiredClauses = [];
+
+ // Set directive used by default when unknown.
+ bit isDefault = 0;
+}
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenACC/ACC.td b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenACC/ACC.td
new file mode 100644
index 000000000000..e96b7e846662
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenACC/ACC.td
@@ -0,0 +1,604 @@
+//===-- ACC.td - OpenACC directive definition file ---------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the definition file for OpenACC directives and clauses.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Frontend/Directive/DirectiveBase.td"
+
+//===----------------------------------------------------------------------===//
+// Definition of general OpenACC information
+//===----------------------------------------------------------------------===//
+
+def OpenACC : DirectiveLanguage {
+ let name = "OpenACC";
+ let cppNamespace = "acc"; // final namespace will be llvm::acc
+ let directivePrefix = "ACCD_";
+ let clausePrefix = "ACCC_";
+ let makeEnumAvailableInNamespace = 1;
+ let enableBitmaskEnumInNamespace = 1;
+ let includeHeader = "llvm/Frontend/OpenACC/ACC.h.inc";
+ let clauseEnumSetClass = "AccClauseSet";
+}
+
+//===----------------------------------------------------------------------===//
+// Definition of OpenACC clauses
+//===----------------------------------------------------------------------===//
+
+// 2.9.6
+def ACCC_Auto : Clause<"auto"> {}
+
+// 2.16.1
+def ACCC_Async : Clause<"async"> {
+ let flangClass = "std::optional<ScalarIntExpr>";
+}
+
+// 2.7.11
+def ACCC_Attach : Clause<"attach"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.15.1
+def ACCC_Bind : Clause<"bind"> {
+ let flangClass = "Name";
+}
+
+// 2.12
+def ACCC_Capture : Clause<"capture"> {
+}
+
+// 2.9.1
+def ACCC_Collapse : Clause<"collapse"> {
+ let flangClass = "ScalarIntConstantExpr";
+}
+
+// 2.7.5
+def ACCC_Copy : Clause<"copy"> {
+ let flangClass = "AccObjectList";
+}
+// 2.7.6
+def ACCC_Copyin : Clause<"copyin"> {
+ let flangClass = "AccObjectListWithModifier";
+}
+
+// 2.7.7
+def ACCC_Copyout : Clause<"copyout"> {
+ let flangClass = "AccObjectListWithModifier";
+}
+
+// 2.7.8
+def ACCC_Create : Clause<"create"> {
+ let flangClass = "AccObjectListWithModifier";
+}
+
+// 2.5.14
+def ACCC_Default : Clause<"default"> {
+ let flangClass = "AccDefaultClause";
+}
+
+// 2.4.12
+def ACCC_DefaultAsync : Clause<"default_async"> {
+ let flangClass = "ScalarIntExpr";
+}
+
+// 2.7.10
+def ACCC_Delete : Clause<"delete"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.7.12
+def ACCC_Detach : Clause<"detach"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.14.4
+def ACCC_Device : Clause<"device"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.14.1
+def ACCC_DeviceNum : Clause<"device_num"> {
+ let flangClass = "ScalarIntConstantExpr";
+}
+
+// 2.7.3
+def ACCC_DevicePtr : Clause<"deviceptr"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.13
+def ACCC_DeviceResident : Clause<"device_resident"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.4
+def ACCC_DeviceType : Clause<"device_type"> {
+ // (DeviceType, "*"
+ let flangClass = "std::optional<std::list<Name>>";
+}
+
+// 2.6.6
+def ACCC_Finalize : Clause<"finalize"> {}
+
+// 2.5.12
+def ACCC_FirstPrivate : Clause<"firstprivate"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.9.2
+def ACCC_Gang : Clause<"gang"> {
+ let flangClass = "std::optional<AccGangArgument>";
+}
+
+// 2.14.4
+def ACCC_Host : Clause<"host"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.5.4
+def ACCC_If : Clause <"if"> {
+ let flangClass = "ScalarLogicalExpr";
+}
+
+// 2.14.4
+def ACCC_IfPresent : Clause<"if_present"> {}
+
+// 2.9.9
+def ACCC_Independent : Clause<"independent"> {}
+
+// 2.13
+def ACCC_Link : Clause<"link"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.7.9
+def ACCC_NoCreate : Clause<"no_create"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.15.1
+def ACCC_NoHost : Clause<"nohost"> {}
+
+// 2.5.8
+def ACCC_NumGangs : Clause<"num_gangs"> {
+ let flangClass = "ScalarIntExpr";
+}
+
+// 2.5.9
+def ACCC_NumWorkers : Clause<"num_workers"> {
+ let flangClass = "ScalarIntExpr";
+}
+
+// 2.7.4
+def ACCC_Present : Clause<"present"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.5.11
+def ACCC_Private : Clause<"private"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.9.7
+def ACCC_Tile : Clause <"tile"> {
+ let flangClass = "AccSizeExprList";
+}
+
+// 2.8.1
+def ACCC_UseDevice : Clause <"use_device"> {
+ let flangClass = "AccObjectList";
+}
+
+// 2.12
+def ACCC_Read : Clause<"read"> {}
+
+// 2.5.13
+def ACCC_Reduction : Clause<"reduction"> {
+ let flangClass = "AccObjectListWithReduction";
+}
+
+// 2.5.5
+def ACCC_Self : Clause<"self"> {
+ let flangClass = "std::optional<ScalarLogicalExpr>";
+}
+
+// 2.9.5
+def ACCC_Seq : Clause<"seq"> {}
+
+// 2.9.4
+def ACCC_Vector : Clause<"vector"> {
+ let flangClass = "std::optional<ScalarIntExpr>";
+}
+
+// 2.5.10
+def ACCC_VectorLength : Clause<"vector_length"> {
+ let flangClass = "ScalarIntExpr";
+}
+
+// 2.16.2
+def ACCC_Wait : Clause<"wait"> {
+ let flangClass = "std::optional<AccWaitArgument>";
+}
+
+// 2.9.3
+def ACCC_Worker: Clause<"worker"> {
+ let flangClass = "std::optional<ScalarIntExpr>";
+}
+
+// 2.12
+def ACCC_Write : Clause<"write"> {}
+
+def ACCC_Unknown : Clause<"unknown"> {
+ let isDefault = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// Definition of OpenACC directives
+//===----------------------------------------------------------------------===//
+
+// 2.12
+def ACC_Atomic : Directive<"atomic"> {}
+
+// 2.6.5
+def ACC_Data : Directive<"data"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_If>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>
+ ];
+}
+
+// 2.13
+def ACC_Declare : Directive<"declare"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_DeviceResident>,
+ VersionedClause<ACCC_Link>
+ ];
+}
+
+// 2.5.2
+def ACC_Kernels : Directive<"kernels"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_DevicePtr>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_NumGangs>,
+ VersionedClause<ACCC_NumWorkers>,
+ VersionedClause<ACCC_Self>,
+ VersionedClause<ACCC_VectorLength>,
+ VersionedClause<ACCC_Wait>
+ ];
+}
+
+// 2.5.1
+def ACC_Parallel : Directive<"parallel"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_Private>,
+ VersionedClause<ACCC_FirstPrivate>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_NumGangs>,
+ VersionedClause<ACCC_NumWorkers>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Self>,
+ VersionedClause<ACCC_VectorLength>
+ ];
+}
+
+// 2.5.3
+def ACC_Serial : Directive<"serial"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_FirstPrivate>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_Private>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Self>
+ ];
+}
+
+// 2.9
+def ACC_Loop : Directive<"loop"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_Private>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Collapse>,
+ VersionedClause<ACCC_Gang>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Tile>,
+ VersionedClause<ACCC_Vector>,
+ VersionedClause<ACCC_Worker>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<ACCC_Auto>,
+ VersionedClause<ACCC_Independent>,
+ VersionedClause<ACCC_Seq>
+ ];
+}
+
+// 2.10
+def ACC_Cache : Directive<"cache"> {}
+
+// 2.14.1
+def ACC_Init : Directive<"init"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_DeviceNum>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_If>
+ ];
+}
+
+// 2.15.1
+def ACC_Routine : Directive<"routine"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Bind>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_NoHost>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_Gang>,
+ VersionedClause<ACCC_Seq>,
+ VersionedClause<ACCC_Vector>,
+ VersionedClause<ACCC_Worker>
+ ];
+}
+
+// 2.14.3
+def ACC_Set : Directive<"set"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_If>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_DefaultAsync>,
+ VersionedClause<ACCC_DeviceNum>,
+ VersionedClause<ACCC_DeviceType>
+ ];
+}
+
+// 2.14.2
+def ACC_Shutdown : Directive<"shutdown"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_DeviceNum>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_If>
+ ];
+}
+
+// 2.14.4
+def ACC_Update : Directive<"update"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_IfPresent>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_Device>,
+ VersionedClause<ACCC_Host>,
+ VersionedClause<ACCC_Self>
+ ];
+}
+
+// 2.16.3
+def ACC_Wait : Directive<"wait"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_If>
+ ];
+}
+
+// 2.14.6
+def ACC_EnterData : Directive<"enter data"> {
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_Copyin>
+ ];
+}
+
+// 2.14.7
+def ACC_ExitData : Directive<"exit data"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Wait>,
+ VersionedClause<ACCC_Finalize>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Delete>,
+ VersionedClause<ACCC_Detach>
+ ];
+}
+def ACC_HostData : Directive<"host_data"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_IfPresent>
+ ];
+ let requiredClauses = [
+ VersionedClause<ACCC_UseDevice>
+ ];
+}
+
+// 2.11
+def ACC_KernelsLoop : Directive<"kernels loop"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_Private>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_Attach>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Collapse>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_Gang>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Independent>,
+ VersionedClause<ACCC_NumGangs>,
+ VersionedClause<ACCC_NumWorkers>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Self>,
+ VersionedClause<ACCC_Tile>,
+ VersionedClause<ACCC_Vector>,
+ VersionedClause<ACCC_VectorLength>,
+ VersionedClause<ACCC_Wait>,
+ VersionedClause<ACCC_Worker>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<ACCC_Auto>,
+ VersionedClause<ACCC_Independent>,
+ VersionedClause<ACCC_Seq>
+ ];
+}
+
+// 2.11
+def ACC_ParallelLoop : Directive<"parallel loop"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_FirstPrivate>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_Private>,
+ VersionedClause<ACCC_Tile>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Collapse>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_Gang>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_NumGangs>,
+ VersionedClause<ACCC_NumWorkers>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Self>,
+ VersionedClause<ACCC_Vector>,
+ VersionedClause<ACCC_VectorLength>,
+ VersionedClause<ACCC_Worker>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<ACCC_Auto>,
+ VersionedClause<ACCC_Independent>,
+ VersionedClause<ACCC_Seq>
+ ];
+}
+
+// 2.11
+def ACC_SerialLoop : Directive<"serial loop"> {
+ let allowedClauses = [
+ VersionedClause<ACCC_Attach>,
+ VersionedClause<ACCC_Copy>,
+ VersionedClause<ACCC_Copyin>,
+ VersionedClause<ACCC_Copyout>,
+ VersionedClause<ACCC_Create>,
+ VersionedClause<ACCC_DevicePtr>,
+ VersionedClause<ACCC_DeviceType>,
+ VersionedClause<ACCC_FirstPrivate>,
+ VersionedClause<ACCC_NoCreate>,
+ VersionedClause<ACCC_Present>,
+ VersionedClause<ACCC_Private>,
+ VersionedClause<ACCC_Wait>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<ACCC_Async>,
+ VersionedClause<ACCC_Collapse>,
+ VersionedClause<ACCC_Default>,
+ VersionedClause<ACCC_Gang>,
+ VersionedClause<ACCC_If>,
+ VersionedClause<ACCC_Reduction>,
+ VersionedClause<ACCC_Self>,
+ VersionedClause<ACCC_Tile>,
+ VersionedClause<ACCC_Vector>,
+ VersionedClause<ACCC_Worker>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<ACCC_Auto>,
+ VersionedClause<ACCC_Independent>,
+ VersionedClause<ACCC_Seq>
+ ];
+}
+
+def ACC_Unknown : Directive<"unknown"> {
+ let isDefault = 1;
+} \ No newline at end of file
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMP.td b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMP.td
new file mode 100644
index 000000000000..a565bdf90b3f
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -0,0 +1,1489 @@
+//===-- OMP.td - OpenMP directive definition file ----------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the definition file for OpenMP directives and clauses.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Frontend/Directive/DirectiveBase.td"
+
+//===----------------------------------------------------------------------===//
+// Definition of general OpenMP information
+//===----------------------------------------------------------------------===//
+
+def OpenMP : DirectiveLanguage {
+ let name = "OpenMP";
+ let cppNamespace = "omp"; // final namespace will be llvm::omp
+ let directivePrefix = "OMPD_";
+ let clausePrefix = "OMPC_";
+ let makeEnumAvailableInNamespace = 1;
+ let enableBitmaskEnumInNamespace = 1;
+ let includeHeader = "llvm/Frontend/OpenMP/OMP.h.inc";
+ let clauseEnumSetClass = "OmpClauseSet";
+}
+
+//===----------------------------------------------------------------------===//
+// Definition of OpenMP clauses
+//===----------------------------------------------------------------------===//
+
+def OMPC_Allocator : Clause<"allocator"> {
+ let clangClass = "OMPAllocatorClause";
+}
+def OMPC_If : Clause<"if"> { let clangClass = "OMPIfClause"; }
+def OMPC_Final : Clause<"final"> { let clangClass = "OMPFinalClause"; }
+def OMPC_NumThreads : Clause<"num_threads"> {
+ let clangClass = "OMPNumThreadsClause";
+}
+def OMPC_SafeLen : Clause<"safelen"> { let clangClass = "OMPSafelenClause"; }
+def OMPC_SimdLen : Clause<"simdlen"> { let clangClass = "OMPSimdlenClause"; }
+def OMPC_Collapse : Clause<"collapse"> { let clangClass = "OMPCollapseClause"; }
+def OMPC_Default : Clause<"default"> { let clangClass = "OMPDefaultClause"; }
+def OMPC_Private : Clause<"private"> { let clangClass = "OMPPrivateClause"; }
+def OMPC_FirstPrivate : Clause<"firstprivate"> {
+ let clangClass = "OMPFirstprivateClause";
+}
+def OMPC_LastPrivate : Clause<"lastprivate"> {
+ let clangClass = "OMPLastprivateClause";
+}
+def OMPC_Shared : Clause<"shared"> { let clangClass = "OMPSharedClause"; }
+def OMPC_Reduction : Clause<"reduction"> {
+ let clangClass = "OMPReductionClause";
+}
+def OMPC_Linear : Clause<"linear"> { let clangClass = "OMPLinearClause"; }
+def OMPC_Aligned : Clause<"aligned"> { let clangClass = "OMPAlignedClause"; }
+def OMPC_Copyin : Clause<"copyin"> { let clangClass = "OMPCopyinClause"; }
+def OMPC_CopyPrivate : Clause<"copyprivate"> {
+ let clangClass = "OMPCopyprivateClause";
+}
+def OMPC_ProcBind : Clause<"proc_bind"> {
+ let clangClass = "OMPProcBindClause";
+}
+def OMPC_Schedule : Clause<"schedule"> { let clangClass = "OMPScheduleClause"; }
+def OMPC_Ordered : Clause<"ordered"> { let clangClass = "OMPOrderedClause"; }
+def OMPC_NoWait : Clause<"nowait"> { let clangClass = "OMPNowaitClause"; }
+def OMPC_Untied : Clause<"untied"> { let clangClass = "OMPUntiedClause"; }
+def OMPC_Mergeable : Clause<"mergeable"> {
+ let clangClass = "OMPMergeableClause";
+}
+def OMPC_Read : Clause<"read"> { let clangClass = "OMPReadClause"; }
+def OMPC_Write : Clause<"write"> { let clangClass = "OMPWriteClause"; }
+def OMPC_Update : Clause<"update"> { let clangClass = "OMPUpdateClause"; }
+def OMPC_Capture : Clause<"capture"> { let clangClass = "OMPCaptureClause"; }
+def OMPC_SeqCst : Clause<"seq_cst"> { let clangClass = "OMPSeqCstClause"; }
+def OMPC_AcqRel : Clause<"acq_rel"> { let clangClass = "OMPAcqRelClause"; }
+def OMPC_Acquire : Clause<"acquire"> { let clangClass = "OMPAcquireClause"; }
+def OMPC_Release : Clause<"release"> { let clangClass = "OMPReleaseClause"; }
+def OMPC_Relaxed : Clause<"relaxed"> { let clangClass = "OMPRelaxedClause"; }
+def OMPC_Depend : Clause<"depend"> { let clangClass = "OMPDependClause"; }
+def OMPC_Device : Clause<"device"> { let clangClass = "OMPDeviceClause"; }
+def OMPC_Threads : Clause<"threads"> { let clangClass = "OMPThreadsClause"; }
+def OMPC_Simd : Clause<"simd"> { let clangClass = "OMPSIMDClause"; }
+def OMPC_Map : Clause<"map"> { let clangClass = "OMPMapClause"; }
+def OMPC_NumTeams : Clause<"num_teams"> {
+ let clangClass = "OMPNumTeamsClause";
+}
+def OMPC_ThreadLimit : Clause<"thread_limit"> {
+ let clangClass = "OMPThreadLimitClause";
+}
+def OMPC_Priority : Clause<"priority"> {
+ let clangClass = "OMPPriorityClause";
+}
+def OMPC_GrainSize : Clause<"grainsize"> {
+ let clangClass = "OMPGrainsizeClause";
+}
+def OMPC_NoGroup : Clause<"nogroup"> {
+ let clangClass = "OMPNogroupClause";
+}
+def OMPC_NumTasks : Clause<"num_tasks"> {
+ let clangClass = "OMPNumTasksClause";
+}
+def OMPC_Hint : Clause<"hint"> {
+ let clangClass = "OMPHintClause";
+}
+def OMPC_DistSchedule : Clause<"dist_schedule"> {
+ let clangClass = "OMPDistScheduleClause";
+}
+def OMPC_DefaultMap : Clause<"defaultmap"> {
+ let clangClass = "OMPDefaultmapClause";
+}
+def OMPC_To : Clause<"to"> {
+ let clangClass = "OMPToClause";
+}
+def OMPC_From : Clause<"from"> { let clangClass = "OMPFromClause"; }
+def OMPC_UseDevicePtr : Clause<"use_device_ptr"> {
+ let clangClass = "OMPUseDevicePtrClause";
+}
+def OMPC_IsDevicePtr : Clause<"is_device_ptr"> {
+ let clangClass = "OMPIsDevicePtrClause";
+}
+def OMPC_TaskReduction : Clause<"task_reduction"> {
+ let clangClass = "OMPTaskReductionClause";
+}
+def OMPC_InReduction : Clause<"in_reduction"> {
+ let clangClass = "OMPInReductionClause";
+}
+def OMPC_UnifiedAddress : Clause<"unified_address"> {
+ let clangClass = "OMPUnifiedAddressClause";
+}
+def OMPC_UnifiedSharedMemory : Clause<"unified_shared_memory"> {
+ let clangClass = "OMPUnifiedSharedMemoryClause";
+}
+def OMPC_ReverseOffload : Clause<"reverse_offload"> {
+ let clangClass = "OMPReverseOffloadClause";
+}
+def OMPC_DynamicAllocators : Clause<"dynamic_allocators"> {
+ let clangClass = "OMPDynamicAllocatorsClause";
+}
+def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
+ let clangClass = "OMPAtomicDefaultMemOrderClause";
+}
+def OMPC_Allocate : Clause<"allocate"> {
+ let clangClass = "OMPAllocateClause";
+}
+def OMPC_NonTemporal : Clause<"nontemporal"> {
+ let clangClass = "OMPNontemporalClause";
+}
+def OMPC_Order : Clause<"order"> {
+ let clangClass = "OMPOrderClause";
+}
+def OMPC_Destroy : Clause<"destroy"> {
+ let clangClass = "OMPDestroyClause";
+}
+def OMPC_Detach : Clause<"detach"> {
+ let clangClass = "OMPDetachClause";
+}
+def OMPC_Inclusive : Clause<"inclusive"> {
+ let clangClass = "OMPInclusiveClause";
+}
+def OMPC_Exclusive : Clause<"exclusive"> {
+ let clangClass = "OMPExclusiveClause";
+}
+def OMPC_UsesAllocators : Clause<"uses_allocators"> {
+ let clangClass = "OMPUsesAllocatorsClause";
+}
+def OMPC_Affinity : Clause<"affinity"> {
+ let clangClass = "OMPAffinityClause";
+}
+def OMPC_UseDeviceAddr : Clause<"use_device_addr"> {
+ let clangClass = "OMPUseDeviceAddrClause";
+}
+def OMPC_Uniform : Clause<"uniform"> {}
+def OMPC_DeviceType : Clause<"device_type"> {}
+def OMPC_Match : Clause<"match"> {}
+def OMPC_Depobj : Clause<"depobj"> {
+ let clangClass = "OMPDepobjClause";
+ let isImplicit = 1;
+}
+def OMPC_Flush : Clause<"flush"> {
+ let clangClass = "OMPFlushClause";
+ let isImplicit = 1;
+}
+def OMPC_ThreadPrivate : Clause<"threadprivate"> {
+ let alternativeName = "threadprivate or thread local";
+ let isImplicit = 1;
+}
+def OMPC_Unknown : Clause<"unknown"> {
+ let isImplicit = 1;
+ let isDefault = 1;
+}
+def OMPC_Link : Clause<"link"> {}
+def OMPC_Inbranch : Clause<"inbranch"> {}
+def OMPC_Notinbranch : Clause<"notinbranch"> {}
+
+//===----------------------------------------------------------------------===//
+// Definition of OpenMP directives
+//===----------------------------------------------------------------------===//
+
+def OMP_ThreadPrivate : Directive<"threadprivate"> {}
+def OMP_Parallel : Directive<"parallel"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Allocate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ ];
+}
+def OMP_Task : Directive<"task"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Detach, 50>,
+ VersionedClause<OMPC_Affinity, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>
+ ];
+}
+def OMP_Simd : Directive<"simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_If, 50>,
+ ];
+}
+def OMP_For : Directive<"for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_Do : Directive<"do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Reduction>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_Sections : Directive<"sections"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_Section : Directive<"section"> {}
+def OMP_Single : Directive<"single"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_CopyPrivate>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_Master : Directive<"master"> {}
+def OMP_Critical : Directive<"critical"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Hint>
+ ];
+}
+def OMP_TaskYield : Directive<"taskyield"> {}
+def OMP_Barrier : Directive<"barrier"> {}
+def OMP_TaskWait : Directive<"taskwait"> {}
+def OMP_TaskGroup : Directive<"taskgroup"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_TaskReduction>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_Flush : Directive<"flush"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_AcqRel, 50>,
+ VersionedClause<OMPC_Acquire, 50>,
+ VersionedClause<OMPC_Release, 50>,
+ // TODO This should ne `none` instead. Comment carried over from
+ // OMPKinds.def.
+ VersionedClause<OMPC_Flush>
+ ];
+}
+def OMP_Ordered : Directive<"ordered"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Threads>,
+ VersionedClause<OMPC_Simd>,
+ VersionedClause<OMPC_Depend>
+ ];
+}
+def OMP_Atomic : Directive<"atomic"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Read>,
+ VersionedClause<OMPC_Write>,
+ VersionedClause<OMPC_Update>,
+ VersionedClause<OMPC_Capture>,
+ VersionedClause<OMPC_SeqCst>,
+ VersionedClause<OMPC_AcqRel, 50>,
+ VersionedClause<OMPC_Acquire, 50>,
+ VersionedClause<OMPC_Release, 50>,
+ VersionedClause<OMPC_Relaxed, 50>,
+ VersionedClause<OMPC_Hint, 50>
+ ];
+}
+def OMP_Target : Directive<"target"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_Teams : Directive<"teams"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>
+ ];
+}
+def OMP_Cancel : Directive<"cancel"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>
+ ];
+}
+def OMP_Requires : Directive<"requires"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_UnifiedAddress>,
+ VersionedClause<OMPC_UnifiedSharedMemory>,
+ VersionedClause<OMPC_ReverseOffload>,
+ VersionedClause<OMPC_DynamicAllocators>,
+ VersionedClause<OMPC_AtomicDefaultMemOrder>
+ ];
+}
+def OMP_TargetData : Directive<"target data"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_UseDevicePtr>,
+ VersionedClause<OMPC_UseDeviceAddr, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_If>
+ ];
+ let requiredClauses = [
+ VersionedClause<OMPC_Map>
+ ];
+}
+def OMP_TargetEnterData : Directive<"target enter data"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Map>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_TargetExitData : Directive<"target exit data"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Map>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NoWait>
+ ];
+ let requiredClauses = [
+ VersionedClause<OMPC_Map>
+ ];
+}
+def OMP_TargetParallel : Directive<"target parallel"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>
+ ];
+}
+def OMP_TargetParallelFor : Directive<"target parallel for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+}
+def OMP_TargetParallelDo : Directive<"target parallel do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Allocator>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Copyin>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_TargetUpdate : Directive<"target update"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_To>,
+ VersionedClause<OMPC_From>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>
+ ];
+}
+def OMP_ParallelFor : Directive<"parallel for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_ParallelDo : Directive<"parallel do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Collapse>
+ ];
+}
+def OMP_ParallelForSimd : Directive<"parallel for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_ParallelDoSimd : Directive<"parallel do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal>,
+ VersionedClause<OMPC_Order>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>
+ ];
+}
+def OMP_ParallelMaster : Directive<"parallel master"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_ParallelSections : Directive<"parallel sections"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_NumThreads>
+ ];
+}
+def OMP_ForSimd : Directive<"for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_If, 50>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ ];
+}
+def OMP_DoSimd : Directive<"do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Reduction>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_NoWait>
+ ];
+}
+def OMP_CancellationPoint : Directive<"cancellation point"> {}
+def OMP_DeclareReduction : Directive<"declare reduction"> {}
+def OMP_DeclareMapper : Directive<"declare mapper"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Map>
+ ];
+}
+def OMP_DeclareSimd : Directive<"declare simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Uniform>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_SimdLen>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_Inbranch>,
+ VersionedClause<OMPC_Notinbranch>
+ ];
+}
+def OMP_TaskLoop : Directive<"taskloop"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_Allocate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>,
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NumTasks>
+ ];
+}
+def OMP_TaskLoopSimd : Directive<"taskloop simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Untied>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Priority>
+ ];
+ let allowedExclusiveClauses = [
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NumTasks>
+ ];
+}
+def OMP_Distribute : Directive<"distribute"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>
+ ];
+}
+def OMP_DeclareTarget : Directive<"declare target"> {}
+def OMP_EndDeclareTarget : Directive<"end declare target"> {}
+def OMP_DistributeParallelFor : Directive<"distribute parallel for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_DistributeParallelDo : Directive<"distribute parallel do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>
+ ];
+}
+def OMP_DistributeParallelForSimd : Directive<"distribute parallel for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_DistributeParallelDoSimd : Directive<"distribute parallel do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal>,
+ VersionedClause<OMPC_Order>
+ ];
+}
+def OMP_DistributeSimd : Directive<"distribute simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If, 50>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>
+ ];
+}
+
+def OMP_TargetParallelForSimd : Directive<"target parallel for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+}
+def OMP_TargetParallelDoSimd : Directive<"target parallel do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_UsesAllocators>
+ ];
+}
+def OMP_TargetSimd : Directive<"target simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Schedule>
+ ];
+}
+def OMP_TeamsDistribute : Directive<"teams distribute"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_TeamsDistributeSimd : Directive<"teams distribute simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If, 50>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_ThreadLimit>
+ ];
+}
+
+def OMP_TeamsDistributeParallelForSimd :
+ Directive<"teams distribute parallel for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_TeamsDistributeParallelDoSimd :
+ Directive<"teams distribute parallel do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_NonTemporal>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_If>,
+ ];
+}
+def OMP_TeamsDistributeParallelFor :
+ Directive<"teams distribute parallel for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_TeamsDistributeParallelDo :
+ Directive<"teams distribute parallel do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>
+ ];
+let allowedOnceClauses = [
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>
+ ];
+}
+def OMP_TargetTeams : Directive<"target teams"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators, 50>,
+ VersionedClause<OMPC_Shared>
+ ];
+
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>
+ ];
+}
+def OMP_TargetTeamsDistribute : Directive<"target teams distribute"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators, 50>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>
+ ];
+}
+
+def OMP_TargetTeamsDistributeParallelFor :
+ Directive<"target teams distribute parallel for"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+}
+def OMP_TargetTeamsDistributeParallelDo :
+ Directive<"target teams distribute parallel do"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ ];
+}
+def OMP_TargetTeamsDistributeParallelForSimd :
+ Directive<"target teams distribute parallel for simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+}
+def OMP_TargetTeamsDistributeParallelDoSimd :
+ Directive<"target teams distribute parallel do simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_UsesAllocators>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Ordered>,
+ VersionedClause<OMPC_Order>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_NonTemporal>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Schedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>
+ ];
+}
+def OMP_TargetTeamsDistributeSimd :
+ Directive<"target teams distribute simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Depend>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_IsDevicePtr>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Map>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_UsesAllocators, 50>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_Device>,
+ VersionedClause<OMPC_DefaultMap>,
+ VersionedClause<OMPC_NoWait>,
+ VersionedClause<OMPC_NumTeams>,
+ VersionedClause<OMPC_ThreadLimit>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_DistSchedule>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ ];
+}
+def OMP_Allocate : Directive<"allocate"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Allocator>
+ ];
+}
+def OMP_DeclareVariant : Directive<"declare variant"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Match>
+ ];
+}
+def OMP_MasterTaskloop : Directive<"master taskloop"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_NumTasks>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_Allocate>
+ ];
+}
+def OMP_ParallelMasterTaskloop :
+ Directive<"parallel master taskloop"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_NumTasks>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Copyin>
+ ];
+}
+def OMP_MasterTaskloopSimd : Directive<"master taskloop simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_NumTasks>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_InReduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_ParallelMasterTaskloopSimd :
+ Directive<"parallel master taskloop simd"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_Shared>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_LastPrivate>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_Collapse>,
+ VersionedClause<OMPC_Final>,
+ VersionedClause<OMPC_Untied>,
+ VersionedClause<OMPC_Mergeable>,
+ VersionedClause<OMPC_Priority>,
+ VersionedClause<OMPC_GrainSize>,
+ VersionedClause<OMPC_NoGroup>,
+ VersionedClause<OMPC_NumTasks>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Linear>,
+ VersionedClause<OMPC_Aligned>,
+ VersionedClause<OMPC_SafeLen>,
+ VersionedClause<OMPC_SimdLen>,
+ VersionedClause<OMPC_NonTemporal, 50>,
+ VersionedClause<OMPC_Order, 50>
+ ];
+}
+def OMP_Depobj : Directive<"depobj"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Depend, 50>,
+ VersionedClause<OMPC_Destroy, 50>,
+ VersionedClause<OMPC_Update, 50>,
+ // TODO This should ne `none` instead. Comment carried over from
+ // OMPKinds.def.
+ VersionedClause<OMPC_Depobj, 50>
+ ];
+}
+def OMP_Scan : Directive<"scan"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Inclusive, 50>,
+ VersionedClause<OMPC_Exclusive, 50>
+ ];
+}
+def OMP_BeginDeclareVariant : Directive<"begin declare variant"> {}
+def OMP_EndDeclareVariant : Directive<"end declare variant"> {}
+def OMP_ParallelWorkshare : Directive<"parallel workshare"> {
+ let allowedClauses = [
+ VersionedClause<OMPC_Allocate>,
+ VersionedClause<OMPC_Copyin>,
+ VersionedClause<OMPC_Default>,
+ VersionedClause<OMPC_FirstPrivate>,
+ VersionedClause<OMPC_Private>,
+ VersionedClause<OMPC_Reduction>,
+ VersionedClause<OMPC_Shared>
+ ];
+ let allowedOnceClauses = [
+ VersionedClause<OMPC_If>,
+ VersionedClause<OMPC_NumThreads>,
+ VersionedClause<OMPC_ProcBind>
+ ];
+}
+def OMP_Workshare : Directive<"workshare"> {}
+def OMP_EndDo : Directive<"end do"> {}
+def OMP_EndDoSimd : Directive<"end do simd"> {}
+def OMP_EndSections : Directive<"end sections"> {}
+def OMP_EndSingle : Directive<"end single"> {}
+def OMP_EndWorkshare : Directive<"end workshare"> {}
+def OMP_Unknown : Directive<"unknown"> {
+ let isDefault = 1;
+}
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
index 2f9a5ee71e67..d171d0a2b6c4 100644
--- a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPConstants.h
@@ -15,29 +15,38 @@
#define LLVM_OPENMP_CONSTANTS_H
#include "llvm/ADT/BitmaskEnum.h"
-#include "llvm/ADT/StringRef.h"
+
+#include "llvm/Frontend/OpenMP/OMP.h.inc"
namespace llvm {
class Type;
class Module;
+class ArrayType;
class StructType;
class PointerType;
+class StringRef;
class FunctionType;
namespace omp {
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
-/// IDs for all OpenMP directives.
-enum class Directive {
-#define OMP_DIRECTIVE(Enum, ...) Enum,
+/// IDs for all Internal Control Variables (ICVs).
+enum class InternalControlVar {
+#define ICV_DATA_ENV(Enum, ...) Enum,
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+#define ICV_DATA_ENV(Enum, ...) \
+ constexpr auto Enum = omp::InternalControlVar::Enum;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+
+enum class ICVInitValue {
+#define ICV_DATA_ENV(Enum, Name, EnvVar, Init) Init,
#include "llvm/Frontend/OpenMP/OMPKinds.def"
};
-/// Make the enum values available in the llvm::omp namespace. This allows us to
-/// write something like OMPD_parallel if we have a `using namespace omp`. At
-/// the same time we do not loose the strong type guarantees of the enum class,
-/// that is we cannot pass an unsigned as Directive without an explicit cast.
-#define OMP_DIRECTIVE(Enum, ...) constexpr auto Enum = omp::Directive::Enum;
+#define ICV_DATA_ENV(Enum, Name, EnvVar, Init) \
+ constexpr auto Init = omp::ICVInitValue::Init;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
/// IDs for all omp runtime library (RTL) functions.
@@ -49,6 +58,16 @@ enum class RuntimeFunction {
#define OMP_RTL(Enum, ...) constexpr auto Enum = omp::RuntimeFunction::Enum;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
+/// IDs for the different default kinds.
+enum class DefaultKind {
+#define OMP_DEFAULT_KIND(Enum, Str) Enum,
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+#define OMP_DEFAULT_KIND(Enum, ...) \
+ constexpr auto Enum = omp::DefaultKind::Enum;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+
/// IDs for the different proc bind kinds.
enum class ProcBindKind {
#define OMP_PROC_BIND_KIND(Enum, Str, Value) Enum = Value,
@@ -70,38 +89,6 @@ enum class IdentFlag {
#define OMP_IDENT_FLAG(Enum, ...) constexpr auto Enum = omp::IdentFlag::Enum;
#include "llvm/Frontend/OpenMP/OMPKinds.def"
-/// Parse \p Str and return the directive it matches or OMPD_unknown if none.
-Directive getOpenMPDirectiveKind(StringRef Str);
-
-/// Return a textual representation of the directive \p D.
-StringRef getOpenMPDirectiveName(Directive D);
-
-/// Forward declarations for LLVM-IR types (simple, function and structure) are
-/// generated below. Their names are defined and used in OpenMP/OMPKinds.def.
-/// Here we provide the forward declarations, the initializeTypes function will
-/// provide the values.
-///
-///{
-namespace types {
-
-#define OMP_TYPE(VarName, InitValue) extern Type *VarName;
-#define OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, ...) \
- extern FunctionType *VarName; \
- extern PointerType *VarName##Ptr;
-#define OMP_STRUCT_TYPE(VarName, StrName, ...) \
- extern StructType *VarName; \
- extern PointerType *VarName##Ptr;
-#include "llvm/Frontend/OpenMP/OMPKinds.def"
-
-/// Helper to initialize all types defined in OpenMP/OMPKinds.def.
-void initializeTypes(Module &M);
-
-/// Helper to uninitialize all types defined in OpenMP/OMPKinds.def.
-void uninitializeTypes();
-
-} // namespace types
-///}
-
} // end namespace omp
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPContext.h b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPContext.h
new file mode 100644
index 000000000000..1a42d189db44
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPContext.h
@@ -0,0 +1,187 @@
+//===- OpenMP/OMPContext.h ----- OpenMP context helper functions - C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides helper functions and classes to deal with OpenMP
+/// contexts as used by `[begin/end] declare variant` and `metadirective`.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPENMP_CONTEXT_H
+#define LLVM_OPENMP_CONTEXT_H
+
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
+
+namespace llvm {
+namespace omp {
+
+/// OpenMP Context related IDs and helpers
+///
+///{
+
+/// IDs for all OpenMP context selector trait sets (construct/device/...).
+enum class TraitSet {
+#define OMP_TRAIT_SET(Enum, ...) Enum,
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+/// IDs for all OpenMP context selector trait (device={kind/isa...}/...).
+enum class TraitSelector {
+#define OMP_TRAIT_SELECTOR(Enum, ...) Enum,
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+/// IDs for all OpenMP context trait properties (host/gpu/bsc/llvm/...)
+enum class TraitProperty {
+#define OMP_TRAIT_PROPERTY(Enum, ...) Enum,
+#define OMP_LAST_TRAIT_PROPERTY(Enum) Last = Enum
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+};
+
+/// Parse \p Str and return the trait set it matches or TraitSet::invalid.
+TraitSet getOpenMPContextTraitSetKind(StringRef Str);
+
+/// Return the trait set for which \p Selector is a selector.
+TraitSet getOpenMPContextTraitSetForSelector(TraitSelector Selector);
+
+/// Return the trait set for which \p Property is a property.
+TraitSet getOpenMPContextTraitSetForProperty(TraitProperty Property);
+
+/// Return a textual representation of the trait set \p Kind.
+StringRef getOpenMPContextTraitSetName(TraitSet Kind);
+
+/// Parse \p Str and return the trait set it matches or
+/// TraitSelector::invalid.
+TraitSelector getOpenMPContextTraitSelectorKind(StringRef Str);
+
+/// Return the trait selector for which \p Property is a property.
+TraitSelector getOpenMPContextTraitSelectorForProperty(TraitProperty Property);
+
+/// Return a textual representation of the trait selector \p Kind.
+StringRef getOpenMPContextTraitSelectorName(TraitSelector Kind);
+
+/// Parse \p Str and return the trait set it matches or
+/// TraitProperty::invalid.
+TraitProperty getOpenMPContextTraitPropertyKind(TraitSet Set, StringRef Str);
+
+/// Return the trait property for a singleton selector \p Selector.
+TraitProperty getOpenMPContextTraitPropertyForSelector(TraitSelector Selector);
+
+/// Return a textual representation of the trait property \p Kind.
+StringRef getOpenMPContextTraitPropertyName(TraitProperty Kind);
+
+/// Return a textual representation of the trait property \p Kind with selector
+/// and set name included.
+StringRef getOpenMPContextTraitPropertyFullName(TraitProperty Kind);
+
+/// Return a string listing all trait sets.
+std::string listOpenMPContextTraitSets();
+
+/// Return a string listing all trait selectors for \p Set.
+std::string listOpenMPContextTraitSelectors(TraitSet Set);
+
+/// Return a string listing all trait properties for \p Set and \p Selector.
+std::string listOpenMPContextTraitProperties(TraitSet Set,
+ TraitSelector Selector);
+///}
+
+/// Return true if \p Selector can be nested in \p Set. Also sets
+/// \p AllowsTraitScore and \p RequiresProperty to true/false if the user can
+/// specify a score for properties in \p Selector and if the \p Selector
+/// requires at least one property.
+bool isValidTraitSelectorForTraitSet(TraitSelector Selector, TraitSet Set,
+ bool &AllowsTraitScore,
+ bool &RequiresProperty);
+
+/// Return true if \p Property can be nested in \p Selector and \p Set.
+bool isValidTraitPropertyForTraitSetAndSelector(TraitProperty Property,
+ TraitSelector Selector,
+ TraitSet Set);
+
+/// Variant match information describes the required traits and how they are
+/// scored (via the ScoresMap). In addition, the required consturct nesting is
+/// decribed as well.
+struct VariantMatchInfo {
+ /// Add the trait \p Property to the required trait set. If \p Score is not
+ /// null, it recorded as well. If \p Property is in the `construct` set it
+ /// is recorded in-order in the ConstructTraits as well.
+ void addTrait(TraitProperty Property, APInt *Score = nullptr) {
+ addTrait(getOpenMPContextTraitSetForProperty(Property), Property, Score);
+ }
+ /// Add the trait \p Property which is in set \p Set to the required trait
+ /// set. If \p Score is not null, it recorded as well. If \p Set is the
+ /// `construct` set it is recorded in-order in the ConstructTraits as well.
+ void addTrait(TraitSet Set, TraitProperty Property, APInt *Score = nullptr) {
+ if (Score)
+ ScoreMap[Property] = *Score;
+ RequiredTraits.set(unsigned(Property));
+ if (Set == TraitSet::construct)
+ ConstructTraits.push_back(Property);
+ }
+
+ BitVector RequiredTraits = BitVector(unsigned(TraitProperty::Last) + 1);
+ SmallVector<TraitProperty, 8> ConstructTraits;
+ SmallDenseMap<TraitProperty, APInt> ScoreMap;
+};
+
+/// The context for a source location is made up of active property traits,
+/// e.g., device={kind(host)}, and constructs traits which describe the nesting
+/// in OpenMP constructs at the location.
+struct OMPContext {
+ OMPContext(bool IsDeviceCompilation, Triple TargetTriple);
+
+ void addTrait(TraitProperty Property) {
+ addTrait(getOpenMPContextTraitSetForProperty(Property), Property);
+ }
+ void addTrait(TraitSet Set, TraitProperty Property) {
+ ActiveTraits.set(unsigned(Property));
+ if (Set == TraitSet::construct)
+ ConstructTraits.push_back(Property);
+ }
+
+ BitVector ActiveTraits = BitVector(unsigned(TraitProperty::Last) + 1);
+ SmallVector<TraitProperty, 8> ConstructTraits;
+};
+
+/// Return true if \p VMI is applicable in \p Ctx, that is, all traits required
+/// by \p VMI are available in the OpenMP context \p Ctx. If \p DeviceSetOnly is
+/// true, only the device selector set, if present, are checked. Note that we
+/// still honor extension traits provided by the user.
+bool isVariantApplicableInContext(const VariantMatchInfo &VMI,
+ const OMPContext &Ctx,
+ bool DeviceSetOnly = false);
+
+/// Return the index (into \p VMIs) of the variant with the highest score
+/// from the ones applicble in \p Ctx. See llvm::isVariantApplicableInContext.
+int getBestVariantMatchForContext(const SmallVectorImpl<VariantMatchInfo> &VMIs,
+ const OMPContext &Ctx);
+
+} // namespace omp
+
+template <> struct DenseMapInfo<omp::TraitProperty> {
+ static inline omp::TraitProperty getEmptyKey() {
+ return omp::TraitProperty(-1);
+ }
+ static inline omp::TraitProperty getTombstoneKey() {
+ return omp::TraitProperty(-2);
+ }
+ static unsigned getHashValue(omp::TraitProperty val) {
+ return std::hash<unsigned>{}(unsigned(val));
+ }
+ static bool isEqual(omp::TraitProperty LHS, omp::TraitProperty RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // end namespace llvm
+#endif // LLVM_OPENMP_CONTEXT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPGridValues.h b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPGridValues.h
new file mode 100644
index 000000000000..3ae4a2edbf96
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPGridValues.h
@@ -0,0 +1,131 @@
+//====--- OMPGridValues.h - Language-specific address spaces --*- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides definitions for Target specific Grid Values
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OPENMP_GRIDVALUES_H
+#define LLVM_OPENMP_GRIDVALUES_H
+
+namespace llvm {
+
+namespace omp {
+
+/// \brief Defines various target-specific GPU grid values that must be
+/// consistent between host RTL (plugin), device RTL, and clang.
+/// We can change grid values for a "fat" binary so that different
+/// passes get the correct values when generating code for a
+/// multi-target binary. Both amdgcn and nvptx values are stored in
+/// this file. In the future, should there be differences between GPUs
+/// of the same architecture, then simply make a different array and
+/// use the new array name.
+///
+/// Example usage in clang:
+/// const unsigned slot_size = ctx.GetTargetInfo().getGridValue(GV_Warp_Size);
+///
+/// Example usage in libomptarget/deviceRTLs:
+/// #include "OMPGridValues.h"
+/// #ifdef __AMDGPU__
+/// #define GRIDVAL AMDGPUGpuGridValues
+/// #else
+/// #define GRIDVAL NVPTXGpuGridValues
+/// #endif
+/// ... Then use this reference for GV_Warp_Size in the deviceRTL source.
+/// GRIDVAL[GV_Warp_Size]
+///
+/// Example usage in libomptarget hsa plugin:
+/// #include "OMPGridValues.h"
+/// #define GRIDVAL AMDGPUGpuGridValues
+/// ... Then use this reference to access GV_Warp_Size in the hsa plugin.
+/// GRIDVAL[GV_Warp_Size]
+///
+/// Example usage in libomptarget cuda plugin:
+/// #include "OMPGridValues.h"
+/// #define GRIDVAL NVPTXGpuGridValues
+/// ... Then use this reference to access GV_Warp_Size in the cuda plugin.
+/// GRIDVAL[GV_Warp_Size]
+///
+enum GVIDX {
+ /// The maximum number of workers in a kernel.
+ /// (THREAD_ABSOLUTE_LIMIT) - (GV_Warp_Size), might be issue for blockDim.z
+ GV_Threads,
+ /// The size reserved for data in a shared memory slot.
+ GV_Slot_Size,
+ /// The default value of maximum number of threads in a worker warp.
+ GV_Warp_Size,
+ /// Alternate warp size for some AMDGCN architectures. Same as GV_Warp_Size
+ /// for NVPTX.
+ GV_Warp_Size_32,
+ /// The number of bits required to represent the max number of threads in warp
+ GV_Warp_Size_Log2,
+ /// GV_Warp_Size * GV_Slot_Size,
+ GV_Warp_Slot_Size,
+ /// the maximum number of teams.
+ GV_Max_Teams,
+ /// Global Memory Alignment
+ GV_Mem_Align,
+ /// (~0u >> (GV_Warp_Size - GV_Warp_Size_Log2))
+ GV_Warp_Size_Log2_Mask,
+ // An alternative to the heavy data sharing infrastructure that uses global
+ // memory is one that uses device __shared__ memory. The amount of such space
+ // (in bytes) reserved by the OpenMP runtime is noted here.
+ GV_SimpleBufferSize,
+ // The absolute maximum team size for a working group
+ GV_Max_WG_Size,
+ // The default maximum team size for a working group
+ GV_Default_WG_Size,
+ // This is GV_Max_WG_Size / GV_WarpSize. 32 for NVPTX and 16 for AMDGCN.
+ GV_Max_Warp_Number,
+ /// The slot size that should be reserved for a working warp.
+ /// (~0u >> (GV_Warp_Size - GV_Warp_Size_Log2))
+ GV_Warp_Size_Log2_MaskL
+};
+
+/// For AMDGPU GPUs
+static constexpr unsigned AMDGPUGpuGridValues[] = {
+ 448, // GV_Threads
+ 256, // GV_Slot_Size
+ 64, // GV_Warp_Size
+ 32, // GV_Warp_Size_32
+ 6, // GV_Warp_Size_Log2
+ 64 * 256, // GV_Warp_Slot_Size
+ 128, // GV_Max_Teams
+ 256, // GV_Mem_Align
+ 63, // GV_Warp_Size_Log2_Mask
+ 896, // GV_SimpleBufferSize
+ 1024, // GV_Max_WG_Size,
+ 256, // GV_Defaut_WG_Size
+ 1024 / 64, // GV_Max_WG_Size / GV_WarpSize
+ 63 // GV_Warp_Size_Log2_MaskL
+};
+
+/// For Nvidia GPUs
+static constexpr unsigned NVPTXGpuGridValues[] = {
+ 992, // GV_Threads
+ 256, // GV_Slot_Size
+ 32, // GV_Warp_Size
+ 32, // GV_Warp_Size_32
+ 5, // GV_Warp_Size_Log2
+ 32 * 256, // GV_Warp_Slot_Size
+ 1024, // GV_Max_Teams
+ 256, // GV_Mem_Align
+ (~0u >> (32 - 5)), // GV_Warp_Size_Log2_Mask
+ 896, // GV_SimpleBufferSize
+ 1024, // GV_Max_WG_Size
+ 128, // GV_Defaut_WG_Size
+ 1024 / 32, // GV_Max_WG_Size / GV_WarpSize
+ 31 // GV_Warp_Size_Log2_MaskL
+};
+
+} // namespace omp
+} // namespace llvm
+
+#endif // LLVM_OPENMP_GRIDVALUES_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
index e1e1d5a30f3c..95eed59f1b3d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h
@@ -14,9 +14,10 @@
#ifndef LLVM_OPENMP_IR_IRBUILDER_H
#define LLVM_OPENMP_IR_IRBUILDER_H
+#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/IRBuilder.h"
-#include "llvm/Frontend/OpenMP/OMPConstants.h"
+#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -34,6 +35,9 @@ public:
/// before any other method and only once!
void initialize();
+ /// Finalize the underlying module, e.g., by outlining regions.
+ void finalize();
+
/// Add attributes known for \p FnID to \p Fn.
void addAttributes(omp::RuntimeFunction FnID, Function &Fn);
@@ -146,9 +150,8 @@ public:
/// \param CanceledDirective The kind of directive that is cancled.
///
/// \returns The insertion point after the barrier.
- InsertPointTy CreateCancel(const LocationDescription &Loc,
- Value *IfCondition,
- omp::Directive CanceledDirective);
+ InsertPointTy CreateCancel(const LocationDescription &Loc, Value *IfCondition,
+ omp::Directive CanceledDirective);
/// Generator for '#omp parallel'
///
@@ -168,9 +171,26 @@ public:
Value *IfCondition, Value *NumThreads,
omp::ProcBindKind ProcBind, bool IsCancellable);
+ /// Generator for '#omp flush'
+ ///
+ /// \param Loc The location where the flush directive was encountered
+ void CreateFlush(const LocationDescription &Loc);
+
+ /// Generator for '#omp taskwait'
+ ///
+ /// \param Loc The location where the taskwait directive was encountered.
+ void CreateTaskwait(const LocationDescription &Loc);
+
+ /// Generator for '#omp taskyield'
+ ///
+ /// \param Loc The location where the taskyield directive was encountered.
+ void CreateTaskyield(const LocationDescription &Loc);
+
///}
-private:
+ /// Return the insertion point used by the underlying IRBuilder.
+ InsertPointTy getInsertionPoint() { return Builder.saveIP(); }
+
/// Update the internal location to \p Loc.
bool updateToLocation(const LocationDescription &Loc) {
Builder.restoreIP(Loc.IP);
@@ -179,7 +199,10 @@ private:
}
/// Return the function declaration for the runtime function with \p FnID.
- Function *getOrCreateRuntimeFunction(omp::RuntimeFunction FnID);
+ FunctionCallee getOrCreateRuntimeFunction(Module &M,
+ omp::RuntimeFunction FnID);
+
+ Function *getOrCreateRuntimeFunctionPtr(omp::RuntimeFunction FnID);
/// Return the (LLVM-IR) string describing the source location \p LocStr.
Constant *getOrCreateSrcLocStr(StringRef LocStr);
@@ -214,6 +237,11 @@ private:
omp::Directive DK, bool ForceSimpleCall,
bool CheckCancelFlag);
+ /// Generate a flush runtime call.
+ ///
+ /// \param Loc The location at which the request originated and is fulfilled.
+ void emitFlush(const LocationDescription &Loc);
+
/// The finalization stack made up of finalize callbacks currently in-flight,
/// wrapped into FinalizationInfo objects that reference also the finalization
/// target block and the kind of cancellable directive.
@@ -227,6 +255,16 @@ private:
FinalizationStack.back().DK == DK;
}
+ /// Generate a taskwait runtime call.
+ ///
+ /// \param Loc The location at which the request originated and is fulfilled.
+ void emitTaskwaitImpl(const LocationDescription &Loc);
+
+ /// Generate a taskyield runtime call.
+ ///
+ /// \param Loc The location at which the request originated and is fulfilled.
+ void emitTaskyieldImpl(const LocationDescription &Loc);
+
/// Return the current thread ID.
///
/// \param Ident The ident (ident_t*) describing the query origin.
@@ -243,6 +281,214 @@ private:
/// Map to remember existing ident_t*.
DenseMap<std::pair<Constant *, uint64_t>, GlobalVariable *> IdentMap;
+
+ /// Helper that contains information about regions we need to outline
+ /// during finalization.
+ struct OutlineInfo {
+ using PostOutlineCBTy = std::function<void(Function &)>;
+ PostOutlineCBTy PostOutlineCB;
+ BasicBlock *EntryBB, *ExitBB;
+
+ /// Collect all blocks in between EntryBB and ExitBB in both the given
+ /// vector and set.
+ void collectBlocks(SmallPtrSetImpl<BasicBlock *> &BlockSet,
+ SmallVectorImpl<BasicBlock *> &BlockVector);
+ };
+
+ /// Collection of regions that need to be outlined during finalization.
+ SmallVector<OutlineInfo, 16> OutlineInfos;
+
+ /// Add a new region that will be outlined later.
+ void addOutlineInfo(OutlineInfo &&OI) { OutlineInfos.emplace_back(OI); }
+
+ /// An ordered map of auto-generated variables to their unique names.
+ /// It stores variables with the following names: 1) ".gomp_critical_user_" +
+ /// <critical_section_name> + ".var" for "omp critical" directives; 2)
+ /// <mangled_name_for_global_var> + ".cache." for cache for threadprivate
+ /// variables.
+ StringMap<AssertingVH<Constant>, BumpPtrAllocator> InternalVars;
+
+public:
+ /// Generator for '#omp master'
+ ///
+ /// \param Loc The insert and source location description.
+ /// \param BodyGenCB Callback that will generate the region code.
+ /// \param FiniCB Callback to finalize variable copies.
+ ///
+ /// \returns The insertion position *after* the master.
+ InsertPointTy CreateMaster(const LocationDescription &Loc,
+ BodyGenCallbackTy BodyGenCB,
+ FinalizeCallbackTy FiniCB);
+
+ /// Generator for '#omp critical'
+ ///
+ /// \param Loc The insert and source location description.
+ /// \param BodyGenCB Callback that will generate the region body code.
+ /// \param FiniCB Callback to finalize variable copies.
+ /// \param CriticalName name of the lock used by the critical directive
+ /// \param HintInst Hint Instruction for hint clause associated with critical
+ ///
+ /// \returns The insertion position *after* the master.
+ InsertPointTy CreateCritical(const LocationDescription &Loc,
+ BodyGenCallbackTy BodyGenCB,
+ FinalizeCallbackTy FiniCB,
+ StringRef CriticalName, Value *HintInst);
+
+ /// Generate conditional branch and relevant BasicBlocks through which private
+ /// threads copy the 'copyin' variables from Master copy to threadprivate
+ /// copies.
+ ///
+ /// \param IP insertion block for copyin conditional
+ /// \param MasterVarPtr a pointer to the master variable
+ /// \param PrivateVarPtr a pointer to the threadprivate variable
+ /// \param IntPtrTy Pointer size type
+ /// \param BranchtoEnd Create a branch between the copyin.not.master blocks
+ // and copy.in.end block
+ ///
+ /// \returns The insertion point where copying operation to be emitted.
+ InsertPointTy CreateCopyinClauseBlocks(InsertPointTy IP, Value *MasterAddr,
+ Value *PrivateAddr,
+ llvm::IntegerType *IntPtrTy,
+ bool BranchtoEnd = true);
+
+ /// Create a runtime call for kmpc_Alloc
+ ///
+ /// \param Loc The insert and source location description.
+ /// \param Size Size of allocated memory space
+ /// \param Allocator Allocator information instruction
+ /// \param Name Name of call Instruction for OMP_alloc
+ ///
+ /// \returns CallInst to the OMP_Alloc call
+ CallInst *CreateOMPAlloc(const LocationDescription &Loc, Value *Size,
+ Value *Allocator, std::string Name = "");
+
+ /// Create a runtime call for kmpc_free
+ ///
+ /// \param Loc The insert and source location description.
+ /// \param Addr Address of memory space to be freed
+ /// \param Allocator Allocator information instruction
+ /// \param Name Name of call Instruction for OMP_Free
+ ///
+ /// \returns CallInst to the OMP_Free call
+ CallInst *CreateOMPFree(const LocationDescription &Loc, Value *Addr,
+ Value *Allocator, std::string Name = "");
+
+ /// Create a runtime call for kmpc_threadprivate_cached
+ ///
+ /// \param Loc The insert and source location description.
+ /// \param Pointer pointer to data to be cached
+ /// \param Size size of data to be cached
+ /// \param Name Name of call Instruction for callinst
+ ///
+ /// \returns CallInst to the thread private cache call.
+ CallInst *CreateCachedThreadPrivate(const LocationDescription &Loc,
+ llvm::Value *Pointer,
+ llvm::ConstantInt *Size,
+ const llvm::Twine &Name = Twine(""));
+
+ /// Declarations for LLVM-IR types (simple, array, function and structure) are
+ /// generated below. Their names are defined and used in OpenMPKinds.def. Here
+ /// we provide the declarations, the initializeTypes function will provide the
+ /// values.
+ ///
+ ///{
+#define OMP_TYPE(VarName, InitValue) Type *VarName = nullptr;
+#define OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize) \
+ ArrayType *VarName##Ty = nullptr; \
+ PointerType *VarName##PtrTy = nullptr;
+#define OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, ...) \
+ FunctionType *VarName = nullptr; \
+ PointerType *VarName##Ptr = nullptr;
+#define OMP_STRUCT_TYPE(VarName, StrName, ...) \
+ StructType *VarName = nullptr; \
+ PointerType *VarName##Ptr = nullptr;
+#include "llvm/Frontend/OpenMP/OMPKinds.def"
+
+ ///}
+
+private:
+ /// Create all simple and struct types exposed by the runtime and remember
+ /// the llvm::PointerTypes of them for easy access later.
+ void initializeTypes(Module &M);
+
+ /// Common interface for generating entry calls for OMP Directives.
+ /// if the directive has a region/body, It will set the insertion
+ /// point to the body
+ ///
+ /// \param OMPD Directive to generate entry blocks for
+ /// \param EntryCall Call to the entry OMP Runtime Function
+ /// \param ExitBB block where the region ends.
+ /// \param Conditional indicate if the entry call result will be used
+ /// to evaluate a conditional of whether a thread will execute
+ /// body code or not.
+ ///
+ /// \return The insertion position in exit block
+ InsertPointTy emitCommonDirectiveEntry(omp::Directive OMPD, Value *EntryCall,
+ BasicBlock *ExitBB,
+ bool Conditional = false);
+
+ /// Common interface to finalize the region
+ ///
+ /// \param OMPD Directive to generate exiting code for
+ /// \param FinIP Insertion point for emitting Finalization code and exit call
+ /// \param ExitCall Call to the ending OMP Runtime Function
+ /// \param HasFinalize indicate if the directive will require finalization
+ /// and has a finalization callback in the stack that
+ /// should be called.
+ ///
+ /// \return The insertion position in exit block
+ InsertPointTy emitCommonDirectiveExit(omp::Directive OMPD,
+ InsertPointTy FinIP,
+ Instruction *ExitCall,
+ bool HasFinalize = true);
+
+ /// Common Interface to generate OMP inlined regions
+ ///
+ /// \param OMPD Directive to generate inlined region for
+ /// \param EntryCall Call to the entry OMP Runtime Function
+ /// \param ExitCall Call to the ending OMP Runtime Function
+ /// \param BodyGenCB Body code generation callback.
+ /// \param FiniCB Finalization Callback. Will be called when finalizing region
+ /// \param Conditional indicate if the entry call result will be used
+ /// to evaluate a conditional of whether a thread will execute
+ /// body code or not.
+ /// \param HasFinalize indicate if the directive will require finalization
+ /// and has a finalization callback in the stack that
+ /// should be called.
+ ///
+ /// \return The insertion point after the region
+
+ InsertPointTy
+ EmitOMPInlinedRegion(omp::Directive OMPD, Instruction *EntryCall,
+ Instruction *ExitCall, BodyGenCallbackTy BodyGenCB,
+ FinalizeCallbackTy FiniCB, bool Conditional = false,
+ bool HasFinalize = true);
+
+ /// Get the platform-specific name separator.
+ /// \param Parts different parts of the final name that needs separation
+ /// \param FirstSeparator First separator used between the initial two
+ /// parts of the name.
+ /// \param Separator separator used between all of the rest consecutive
+ /// parts of the name
+ static std::string getNameWithSeparators(ArrayRef<StringRef> Parts,
+ StringRef FirstSeparator,
+ StringRef Separator);
+
+ /// Gets (if variable with the given name already exist) or creates
+ /// internal global variable with the specified Name. The created variable has
+ /// linkage CommonLinkage by default and is initialized by null value.
+ /// \param Ty Type of the global variable. If it is exist already the type
+ /// must be the same.
+ /// \param Name Name of the variable.
+ Constant *getOrCreateOMPInternalVariable(Type *Ty, const Twine &Name,
+ unsigned AddressSpace = 0);
+
+ /// Returns corresponding lock object for the specified critical region
+ /// name. If the lock object does not exist it is created, otherwise the
+ /// reference to the existing copy is returned.
+ /// \param CriticalName Name of the critical region.
+ ///
+ Value *getOMPCriticalRegionLock(StringRef CriticalName);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
index 3ec27e5c08a8..93ea63c1c2e6 100644
--- a/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
+++ b/contrib/llvm-project/llvm/include/llvm/Frontend/OpenMP/OMPKinds.def
@@ -91,6 +91,10 @@ __OMP_DIRECTIVE_EXT(parallel_master_taskloop, "parallel master taskloop")
__OMP_DIRECTIVE_EXT(master_taskloop_simd, "master taskloop simd")
__OMP_DIRECTIVE_EXT(parallel_master_taskloop_simd,
"parallel master taskloop simd")
+__OMP_DIRECTIVE(depobj)
+__OMP_DIRECTIVE(scan)
+__OMP_DIRECTIVE_EXT(begin_declare_variant, "begin declare variant")
+__OMP_DIRECTIVE_EXT(end_declare_variant, "end declare variant")
// Has to be the last because Clang implicitly expects it to be.
__OMP_DIRECTIVE(unknown)
@@ -101,6 +105,120 @@ __OMP_DIRECTIVE(unknown)
///}
+/// OpenMP Clauses
+///
+///{
+
+#ifndef OMP_CLAUSE
+#define OMP_CLAUSE(Enum, Str, Implicit)
+#endif
+#ifndef OMP_CLAUSE_CLASS
+#define OMP_CLAUSE_CLASS(Enum, Str, Class)
+#endif
+#ifndef OMP_CLAUSE_NO_CLASS
+#define OMP_CLAUSE_NO_CLASS(Enum, Str)
+#endif
+
+#define __OMP_CLAUSE(Name, Class) \
+ OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
+ OMP_CLAUSE_CLASS(OMPC_##Name, #Name, Class)
+#define __OMP_CLAUSE_NO_CLASS(Name) \
+ OMP_CLAUSE(OMPC_##Name, #Name, /* Implicit */ false) \
+ OMP_CLAUSE_NO_CLASS(OMPC_##Name, #Name)
+#define __OMP_IMPLICIT_CLAUSE_CLASS(Name, Str, Class) \
+ OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
+ OMP_CLAUSE_CLASS(OMPC_##Name, Str, Class)
+#define __OMP_IMPLICIT_CLAUSE_NO_CLASS(Name, Str) \
+ OMP_CLAUSE(OMPC_##Name, Str, /* Implicit */ true) \
+ OMP_CLAUSE_NO_CLASS(OMPC_##Name, Str)
+
+__OMP_CLAUSE(allocator, OMPAllocatorClause)
+__OMP_CLAUSE(if, OMPIfClause)
+__OMP_CLAUSE(final, OMPFinalClause)
+__OMP_CLAUSE(num_threads, OMPNumThreadsClause)
+__OMP_CLAUSE(safelen, OMPSafelenClause)
+__OMP_CLAUSE(simdlen, OMPSimdlenClause)
+__OMP_CLAUSE(collapse, OMPCollapseClause)
+__OMP_CLAUSE(default, OMPDefaultClause)
+__OMP_CLAUSE(private, OMPPrivateClause)
+__OMP_CLAUSE(firstprivate, OMPFirstprivateClause)
+__OMP_CLAUSE(lastprivate, OMPLastprivateClause)
+__OMP_CLAUSE(shared, OMPSharedClause)
+__OMP_CLAUSE(reduction, OMPReductionClause)
+__OMP_CLAUSE(linear, OMPLinearClause)
+__OMP_CLAUSE(aligned, OMPAlignedClause)
+__OMP_CLAUSE(copyin, OMPCopyinClause)
+__OMP_CLAUSE(copyprivate, OMPCopyprivateClause)
+__OMP_CLAUSE(proc_bind, OMPProcBindClause)
+__OMP_CLAUSE(schedule, OMPScheduleClause)
+__OMP_CLAUSE(ordered, OMPOrderedClause)
+__OMP_CLAUSE(nowait, OMPNowaitClause)
+__OMP_CLAUSE(untied, OMPUntiedClause)
+__OMP_CLAUSE(mergeable, OMPMergeableClause)
+__OMP_CLAUSE(read, OMPReadClause)
+__OMP_CLAUSE(write, OMPWriteClause)
+__OMP_CLAUSE(update, OMPUpdateClause)
+__OMP_CLAUSE(capture, OMPCaptureClause)
+__OMP_CLAUSE(seq_cst, OMPSeqCstClause)
+__OMP_CLAUSE(acq_rel, OMPAcqRelClause)
+__OMP_CLAUSE(acquire, OMPAcquireClause)
+__OMP_CLAUSE(release, OMPReleaseClause)
+__OMP_CLAUSE(relaxed, OMPRelaxedClause)
+__OMP_CLAUSE(depend, OMPDependClause)
+__OMP_CLAUSE(device, OMPDeviceClause)
+__OMP_CLAUSE(threads, OMPThreadsClause)
+__OMP_CLAUSE(simd, OMPSIMDClause)
+__OMP_CLAUSE(map, OMPMapClause)
+__OMP_CLAUSE(num_teams, OMPNumTeamsClause)
+__OMP_CLAUSE(thread_limit, OMPThreadLimitClause)
+__OMP_CLAUSE(priority, OMPPriorityClause)
+__OMP_CLAUSE(grainsize, OMPGrainsizeClause)
+__OMP_CLAUSE(nogroup, OMPNogroupClause)
+__OMP_CLAUSE(num_tasks, OMPNumTasksClause)
+__OMP_CLAUSE(hint, OMPHintClause)
+__OMP_CLAUSE(dist_schedule, OMPDistScheduleClause)
+__OMP_CLAUSE(defaultmap, OMPDefaultmapClause)
+__OMP_CLAUSE(to, OMPToClause)
+__OMP_CLAUSE(from, OMPFromClause)
+__OMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
+__OMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
+__OMP_CLAUSE(task_reduction, OMPTaskReductionClause)
+__OMP_CLAUSE(in_reduction, OMPInReductionClause)
+__OMP_CLAUSE(unified_address, OMPUnifiedAddressClause)
+__OMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause)
+__OMP_CLAUSE(reverse_offload, OMPReverseOffloadClause)
+__OMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause)
+__OMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause)
+__OMP_CLAUSE(allocate, OMPAllocateClause)
+__OMP_CLAUSE(nontemporal, OMPNontemporalClause)
+__OMP_CLAUSE(order, OMPOrderClause)
+__OMP_CLAUSE(destroy, OMPDestroyClause)
+__OMP_CLAUSE(detach, OMPDetachClause)
+__OMP_CLAUSE(inclusive, OMPInclusiveClause)
+__OMP_CLAUSE(exclusive, OMPExclusiveClause)
+__OMP_CLAUSE(uses_allocators, OMPUsesAllocatorsClause)
+__OMP_CLAUSE(affinity, OMPAffinityClause)
+__OMP_CLAUSE(use_device_addr, OMPUseDeviceAddrClause)
+
+__OMP_CLAUSE_NO_CLASS(uniform)
+__OMP_CLAUSE_NO_CLASS(device_type)
+__OMP_CLAUSE_NO_CLASS(match)
+
+__OMP_IMPLICIT_CLAUSE_CLASS(depobj, "depobj", OMPDepobjClause)
+__OMP_IMPLICIT_CLAUSE_CLASS(flush, "flush", OMPFlushClause)
+
+__OMP_IMPLICIT_CLAUSE_NO_CLASS(threadprivate, "threadprivate or thread local")
+__OMP_IMPLICIT_CLAUSE_NO_CLASS(unknown, "unknown")
+
+#undef __OMP_IMPLICIT_CLAUSE_NO_CLASS
+#undef __OMP_IMPLICIT_CLAUSE_CLASS
+#undef __OMP_CLAUSE
+#undef OMP_CLAUSE_NO_CLASS
+#undef OMP_CLAUSE_CLASS
+#undef OMP_CLAUSE
+
+///}
+
/// Types used in runtime structs or runtime functions
///
///{
@@ -112,16 +230,50 @@ __OMP_DIRECTIVE(unknown)
#define __OMP_TYPE(VarName) OMP_TYPE(VarName, Type::get##VarName##Ty(Ctx))
__OMP_TYPE(Void)
+__OMP_TYPE(Int1)
__OMP_TYPE(Int8)
__OMP_TYPE(Int32)
+__OMP_TYPE(Int64)
__OMP_TYPE(Int8Ptr)
__OMP_TYPE(Int32Ptr)
+__OMP_TYPE(Int64Ptr)
+
+OMP_TYPE(SizeTy, M.getDataLayout().getIntPtrType(Ctx))
+
+#define __OMP_PTR_TYPE(NAME, BASE) OMP_TYPE(NAME, BASE->getPointerTo())
+
+__OMP_PTR_TYPE(VoidPtr, Int8)
+__OMP_PTR_TYPE(VoidPtrPtr, VoidPtr)
+__OMP_PTR_TYPE(VoidPtrPtrPtr, VoidPtrPtr)
+
+__OMP_PTR_TYPE(Int8PtrPtr, Int8Ptr)
+__OMP_PTR_TYPE(Int8PtrPtrPtr, Int8PtrPtr)
+
+#undef __OMP_PTR_TYPE
#undef __OMP_TYPE
#undef OMP_TYPE
///}
+/// array types
+///
+///{
+
+#ifndef OMP_ARRAY_TYPE
+#define OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize)
+#endif
+
+#define __OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize) \
+ OMP_ARRAY_TYPE(VarName, ElemTy, ArraySize)
+
+__OMP_ARRAY_TYPE(KmpCriticalName, Int32, 8)
+
+#undef __OMP_ARRAY_TYPE
+#undef OMP_ARRAY_TYPE
+
+///}
+
/// Struct and function types
///
///{
@@ -146,12 +298,64 @@ __OMP_STRUCT_TYPE(Ident, ident_t, Int32, Int32, Int32, Int32, Int8Ptr)
OMP_FUNCTION_TYPE(VarName, IsVarArg, ReturnType, __VA_ARGS__)
__OMP_FUNCTION_TYPE(ParallelTask, true, Void, Int32Ptr, Int32Ptr)
+__OMP_FUNCTION_TYPE(ReduceFunction, false, Void, VoidPtr, VoidPtr)
+__OMP_FUNCTION_TYPE(CopyFunction, false, Void, VoidPtr, VoidPtr)
+__OMP_FUNCTION_TYPE(KmpcCtor, false, VoidPtr, VoidPtr)
+__OMP_FUNCTION_TYPE(KmpcDtor, false, Void, VoidPtr)
+__OMP_FUNCTION_TYPE(KmpcCopyCtor, false, VoidPtr, VoidPtr, VoidPtr)
+__OMP_FUNCTION_TYPE(TaskRoutineEntry, false, Int32, Int32,
+ /* kmp_task_t */ VoidPtr)
#undef __OMP_FUNCTION_TYPE
#undef OMP_FUNCTION_TYPE
///}
+/// Internal Control Variables information
+///
+///{
+
+#ifndef ICV_DATA_ENV
+#define ICV_DATA_ENV(Enum, Name, EnvVarName, Init)
+#endif
+
+#define __ICV_DATA_ENV(Name, EnvVarName, Init) \
+ ICV_DATA_ENV(ICV_##Name, #Name, #EnvVarName, Init)
+
+__ICV_DATA_ENV(nthreads, OMP_NUM_THREADS, ICV_IMPLEMENTATION_DEFINED)
+__ICV_DATA_ENV(active_levels, NONE, ICV_ZERO)
+__ICV_DATA_ENV(cancel, OMP_CANCELLATION, ICV_FALSE)
+__ICV_DATA_ENV(__last, last, ICV_LAST)
+
+#undef __ICV_DATA_ENV
+#undef ICV_DATA_ENV
+
+#ifndef ICV_RT_SET
+#define ICV_RT_SET(Name, RTL)
+#endif
+
+#define __ICV_RT_SET(Name, RTL) ICV_RT_SET(ICV_##Name, OMPRTL_##RTL)
+
+__ICV_RT_SET(nthreads, omp_set_num_threads)
+
+#undef __ICV_RT_SET
+#undef ICV_RT_SET
+
+#ifndef ICV_RT_GET
+#define ICV_RT_GET(Name, RTL)
+#endif
+
+#define __ICV_RT_GET(Name, RTL) ICV_RT_GET(ICV_##Name, OMPRTL_##RTL)
+
+__ICV_RT_GET(nthreads, omp_get_max_threads)
+__ICV_RT_GET(active_levels, omp_get_active_level)
+__ICV_RT_GET(cancel, omp_get_cancellation)
+
+#undef __ICV_RT_GET
+#undef ICV_RT_GET
+
+///}
+
/// Runtime library function (and their attributes)
///
///{
@@ -163,18 +367,229 @@ __OMP_FUNCTION_TYPE(ParallelTask, true, Void, Int32Ptr, Int32Ptr)
#define __OMP_RTL(Name, IsVarArg, ReturnType, ...) \
OMP_RTL(OMPRTL_##Name, #Name, IsVarArg, ReturnType, __VA_ARGS__)
+
+
__OMP_RTL(__kmpc_barrier, false, Void, IdentPtr, Int32)
__OMP_RTL(__kmpc_cancel, false, Int32, IdentPtr, Int32, Int32)
__OMP_RTL(__kmpc_cancel_barrier, false, Int32, IdentPtr, Int32)
+__OMP_RTL(__kmpc_flush, false, Void, IdentPtr)
__OMP_RTL(__kmpc_global_thread_num, false, Int32, IdentPtr)
__OMP_RTL(__kmpc_fork_call, true, Void, IdentPtr, Int32, ParallelTaskPtr)
+__OMP_RTL(__kmpc_omp_taskwait, false, Int32, IdentPtr, Int32)
+__OMP_RTL(__kmpc_omp_taskyield, false, Int32, IdentPtr, Int32, /* Int */ Int32)
__OMP_RTL(__kmpc_push_num_threads, false, Void, IdentPtr, Int32,
/* Int */ Int32)
__OMP_RTL(__kmpc_push_proc_bind, false, Void, IdentPtr, Int32, /* Int */ Int32)
__OMP_RTL(__kmpc_serialized_parallel, false, Void, IdentPtr, Int32)
__OMP_RTL(__kmpc_end_serialized_parallel, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_omp_reg_task_with_affinity, false, Int32, IdentPtr, Int32,
+ Int8Ptr, Int32, Int8Ptr)
__OMP_RTL(omp_get_thread_num, false, Int32, )
+__OMP_RTL(omp_get_num_threads, false, Int32, )
+__OMP_RTL(omp_get_max_threads, false, Int32, )
+__OMP_RTL(omp_in_parallel, false, Int32, )
+__OMP_RTL(omp_get_dynamic, false, Int32, )
+__OMP_RTL(omp_get_cancellation, false, Int32, )
+__OMP_RTL(omp_get_nested, false, Int32, )
+__OMP_RTL(omp_get_schedule, false, Void, Int32Ptr, Int32Ptr)
+__OMP_RTL(omp_get_thread_limit, false, Int32, )
+__OMP_RTL(omp_get_supported_active_levels, false, Int32, )
+__OMP_RTL(omp_get_max_active_levels, false, Int32, )
+__OMP_RTL(omp_get_level, false, Int32, )
+__OMP_RTL(omp_get_ancestor_thread_num, false, Int32, Int32)
+__OMP_RTL(omp_get_team_size, false, Int32, Int32)
+__OMP_RTL(omp_get_active_level, false, Int32, )
+__OMP_RTL(omp_in_final, false, Int32, )
+__OMP_RTL(omp_get_proc_bind, false, Int32, )
+__OMP_RTL(omp_get_num_places, false, Int32, )
+__OMP_RTL(omp_get_num_procs, false, Int32, )
+__OMP_RTL(omp_get_place_proc_ids, false, Void, Int32, Int32Ptr)
+__OMP_RTL(omp_get_place_num, false, Int32, )
+__OMP_RTL(omp_get_partition_num_places, false, Int32, )
+__OMP_RTL(omp_get_partition_place_nums, false, Void, Int32Ptr)
+
+__OMP_RTL(omp_set_num_threads, false, Void, Int32)
+__OMP_RTL(omp_set_dynamic, false, Void, Int32)
+__OMP_RTL(omp_set_nested, false, Void, Int32)
+__OMP_RTL(omp_set_schedule, false, Void, Int32, Int32)
+__OMP_RTL(omp_set_max_active_levels, false, Void, Int32)
+
+__OMP_RTL(__kmpc_master, false, Int32, IdentPtr, Int32)
+__OMP_RTL(__kmpc_end_master, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_critical, false, Void, IdentPtr, Int32, KmpCriticalNamePtrTy)
+__OMP_RTL(__kmpc_critical_with_hint, false, Void, IdentPtr, Int32,
+ KmpCriticalNamePtrTy, Int32)
+__OMP_RTL(__kmpc_end_critical, false, Void, IdentPtr, Int32,
+ KmpCriticalNamePtrTy)
+
+__OMP_RTL(__kmpc_begin, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_end, false, Void, IdentPtr)
+
+__OMP_RTL(__kmpc_reduce, false, Int32, IdentPtr, Int32, Int32, SizeTy, VoidPtr,
+ ReduceFunctionPtr, KmpCriticalNamePtrTy)
+__OMP_RTL(__kmpc_reduce_nowait, false, Int32, IdentPtr, Int32, Int32, SizeTy,
+ VoidPtr, ReduceFunctionPtr, KmpCriticalNamePtrTy)
+__OMP_RTL(__kmpc_end_reduce, false, Void, IdentPtr, Int32,
+ KmpCriticalNamePtrTy)
+__OMP_RTL(__kmpc_end_reduce_nowait, false, Void, IdentPtr, Int32,
+ KmpCriticalNamePtrTy)
+
+__OMP_RTL(__kmpc_ordered, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_end_ordered, false, Void, IdentPtr, Int32)
+
+__OMP_RTL(__kmpc_for_static_init_4, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_for_static_init_4u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_for_static_init_8, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+__OMP_RTL(__kmpc_for_static_init_8u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+__OMP_RTL(__kmpc_for_static_fini, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_dist_dispatch_init_4, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32, Int32, Int32, Int32)
+__OMP_RTL(__kmpc_dist_dispatch_init_4u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32, Int32, Int32, Int32)
+__OMP_RTL(__kmpc_dist_dispatch_init_8, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64, Int64, Int64, Int64)
+__OMP_RTL(__kmpc_dist_dispatch_init_8u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64, Int64, Int64, Int64)
+__OMP_RTL(__kmpc_dispatch_init_4, false, Void, IdentPtr, Int32, Int32, Int32,
+ Int32, Int32, Int32)
+__OMP_RTL(__kmpc_dispatch_init_4u, false, Void, IdentPtr, Int32, Int32, Int32,
+ Int32, Int32, Int32)
+__OMP_RTL(__kmpc_dispatch_init_8, false, Void, IdentPtr, Int32, Int32, Int64,
+ Int64, Int64, Int64)
+__OMP_RTL(__kmpc_dispatch_init_8u, false, Void, IdentPtr, Int32, Int32, Int64,
+ Int64, Int64, Int64)
+__OMP_RTL(__kmpc_dispatch_next_4, false, Int32, IdentPtr, Int32, Int32Ptr,
+ Int32Ptr, Int32Ptr, Int32Ptr)
+__OMP_RTL(__kmpc_dispatch_next_4u, false, Int32, IdentPtr, Int32, Int32Ptr,
+ Int32Ptr, Int32Ptr, Int32Ptr)
+__OMP_RTL(__kmpc_dispatch_next_8, false, Int32, IdentPtr, Int32, Int32Ptr,
+ Int64Ptr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__kmpc_dispatch_next_8u, false, Int32, IdentPtr, Int32, Int32Ptr,
+ Int64Ptr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__kmpc_dispatch_fini_4, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_dispatch_fini_4u, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_dispatch_fini_8, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_dispatch_fini_8u, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_team_static_init_4, false, Void, IdentPtr, Int32, Int32Ptr,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_team_static_init_4u, false, Void, IdentPtr, Int32, Int32Ptr,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_team_static_init_8, false, Void, IdentPtr, Int32, Int32Ptr,
+ Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+__OMP_RTL(__kmpc_team_static_init_8u, false, Void, IdentPtr, Int32, Int32Ptr,
+ Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+__OMP_RTL(__kmpc_dist_for_static_init_4, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_dist_for_static_init_4u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32Ptr, Int32, Int32)
+__OMP_RTL(__kmpc_dist_for_static_init_8, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+__OMP_RTL(__kmpc_dist_for_static_init_8u, false, Void, IdentPtr, Int32, Int32,
+ Int32Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64Ptr, Int64, Int64)
+
+__OMP_RTL(__kmpc_single, false, Int32, IdentPtr, Int32)
+__OMP_RTL(__kmpc_end_single, false, Void, IdentPtr, Int32)
+
+__OMP_RTL(__kmpc_omp_task_alloc, false, /* kmp_task_t */ VoidPtr, IdentPtr,
+ Int32, Int32, SizeTy, SizeTy, TaskRoutineEntryPtr)
+__OMP_RTL(__kmpc_omp_task, false, Int32, IdentPtr, Int32,
+ /* kmp_task_t */ VoidPtr)
+__OMP_RTL(__kmpc_end_taskgroup, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_taskgroup, false, Void, IdentPtr, Int32)
+__OMP_RTL(__kmpc_omp_task_begin_if0, false, Void, IdentPtr, Int32,
+ /* kmp_task_t */ VoidPtr)
+__OMP_RTL(__kmpc_omp_task_complete_if0, false, Void, IdentPtr, Int32,
+ /* kmp_tasK_t */ VoidPtr)
+__OMP_RTL(__kmpc_omp_task_with_deps, false, Int32, IdentPtr, Int32,
+ /* kmp_task_t */ VoidPtr, Int32,
+ /* kmp_depend_info_t */ VoidPtr, Int32,
+ /* kmp_depend_info_t */ VoidPtr)
+__OMP_RTL(__kmpc_taskloop, false, Void, IdentPtr, /* Int */ Int32, VoidPtr,
+ /* Int */ Int32, Int64Ptr, Int64Ptr, Int64, /* Int */ Int32,
+ /* Int */ Int32, Int64, VoidPtr)
+__OMP_RTL(__kmpc_omp_target_task_alloc, false, /* kmp_task_t */ VoidPtr,
+ IdentPtr, Int32, Int32, SizeTy, SizeTy, TaskRoutineEntryPtr, Int64)
+__OMP_RTL(__kmpc_taskred_modifier_init, false, VoidPtr, IdentPtr,
+ /* Int */ Int32, /* Int */ Int32, /* Int */ Int32, VoidPtr)
+__OMP_RTL(__kmpc_taskred_init, false, VoidPtr, /* Int */ Int32,
+ /* Int */ Int32, VoidPtr)
+__OMP_RTL(__kmpc_task_reduction_modifier_fini, false, Void, IdentPtr,
+ /* Int */ Int32, /* Int */ Int32)
+__OMP_RTL(__kmpc_task_reduction_get_th_data, false, VoidPtr, Int32, VoidPtr,
+ VoidPtr)
+__OMP_RTL(__kmpc_task_reduction_init, false, VoidPtr, Int32, Int32, VoidPtr)
+__OMP_RTL(__kmpc_task_reduction_modifier_init, false, VoidPtr, VoidPtr, Int32,
+ Int32, Int32, VoidPtr)
+__OMP_RTL(__kmpc_proxy_task_completed_ooo, false, Void, VoidPtr)
+
+__OMP_RTL(__kmpc_omp_wait_deps, false, Void, IdentPtr, Int32, Int32,
+ /* kmp_depend_info_t */ VoidPtr, Int32, VoidPtr)
+__OMP_RTL(__kmpc_cancellationpoint, false, Int32, IdentPtr, Int32, Int32)
+
+__OMP_RTL(__kmpc_fork_teams, true, Void, IdentPtr, Int32, ParallelTaskPtr)
+__OMP_RTL(__kmpc_push_num_teams, false, Void, IdentPtr, Int32, Int32, Int32)
+
+__OMP_RTL(__kmpc_copyprivate, false, Void, IdentPtr, Int32, SizeTy, VoidPtr,
+ CopyFunctionPtr, Int32)
+__OMP_RTL(__kmpc_threadprivate_cached, false, VoidPtr, IdentPtr, Int32, VoidPtr,
+ SizeTy, VoidPtrPtrPtr)
+__OMP_RTL(__kmpc_threadprivate_register, false, Void, IdentPtr, VoidPtr,
+ KmpcCtorPtr, KmpcCopyCtorPtr, KmpcDtorPtr)
+
+__OMP_RTL(__kmpc_doacross_init, false, Void, IdentPtr, Int32, Int32,
+ /* kmp_dim */ VoidPtr)
+__OMP_RTL(__kmpc_doacross_post, false, Void, IdentPtr, Int32, Int64Ptr)
+__OMP_RTL(__kmpc_doacross_wait, false, Void, IdentPtr, Int32, Int64Ptr)
+__OMP_RTL(__kmpc_doacross_fini, false, Void, IdentPtr, Int32)
+
+__OMP_RTL(__kmpc_alloc, false, VoidPtr, /* Int */ Int32, SizeTy, VoidPtr)
+__OMP_RTL(__kmpc_free, false, Void, /* Int */ Int32, VoidPtr, VoidPtr)
+
+__OMP_RTL(__kmpc_init_allocator, false, /* omp_allocator_handle_t */ VoidPtr,
+ /* Int */ Int32, /* omp_memespace_handle_t */ VoidPtr,
+ /* Int */ Int32, /* omp_alloctrait_t */ VoidPtr)
+__OMP_RTL(__kmpc_destroy_allocator, false, Void, /* Int */ Int32,
+ /* omp_allocator_handle_t */ VoidPtr)
+
+__OMP_RTL(__kmpc_push_target_tripcount, false, Void, Int64, Int64)
+__OMP_RTL(__tgt_target, false, Int32, Int64, VoidPtr, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_nowait, false, Int32, Int64, VoidPtr, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_teams, false, Int32, Int64, VoidPtr, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr, Int32, Int32)
+__OMP_RTL(__tgt_target_teams_nowait, false, Int32, Int64, VoidPtr, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr, Int32, Int32)
+__OMP_RTL(__tgt_register_requires, false, Void, Int64)
+__OMP_RTL(__tgt_target_data_begin, false, Void, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_data_begin_nowait, false, Void, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_data_end, false, Void, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_data_end_nowait, false, Void, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_data_update, false, Void, Int64, Int32, VoidPtrPtr,
+ VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_target_data_update_nowait, false, Void, Int64, Int32,
+ VoidPtrPtr, VoidPtrPtr, Int64Ptr, Int64Ptr)
+__OMP_RTL(__tgt_mapper_num_components, false, Int64, VoidPtr)
+__OMP_RTL(__tgt_push_mapper_component, false, Void, VoidPtr, VoidPtr, VoidPtr,
+ Int64, Int64)
+__OMP_RTL(__kmpc_task_allow_completion_event, false, VoidPtr, IdentPtr,
+ /* Int */ Int32, /* kmp_task_t */ VoidPtr)
+
+/// Note that device runtime functions (in the following) do not necessarily
+/// need attributes as we expect to see the definitions.
+__OMP_RTL(__kmpc_kernel_parallel, false, Int1, VoidPtrPtr)
+__OMP_RTL(__kmpc_kernel_prepare_parallel, false, Void, VoidPtr)
+
+__OMP_RTL(__last, false, Void, )
#undef __OMP_RTL
#undef OMP_RTL
@@ -192,7 +607,17 @@ __OMP_RTL(omp_get_thread_num, false, Int32, )
__OMP_ATTRS_SET(GetterAttrs,
OptimisticAttributes
? AttributeSet(EnumAttr(NoUnwind), EnumAttr(ReadOnly),
- EnumAttr(NoSync), EnumAttr(NoFree))
+ EnumAttr(NoSync), EnumAttr(NoFree), EnumAttr(InaccessibleMemOnly))
+ : AttributeSet(EnumAttr(NoUnwind)))
+__OMP_ATTRS_SET(GetterArgWriteAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(NoSync),
+ EnumAttr(NoFree), EnumAttr(InaccessibleMemOrArgMemOnly))
+ : AttributeSet(EnumAttr(NoUnwind)))
+__OMP_ATTRS_SET(SetterAttrs,
+ OptimisticAttributes
+ ? AttributeSet(EnumAttr(NoUnwind), EnumAttr(WriteOnly),
+ EnumAttr(NoSync), EnumAttr(NoFree), EnumAttr(InaccessibleMemOnly))
: AttributeSet(EnumAttr(NoUnwind)))
#undef __OMP_ATTRS_SET
@@ -205,11 +630,290 @@ __OMP_ATTRS_SET(GetterAttrs,
#define __OMP_RTL_ATTRS(Name, FnAttrSet, RetAttrSet, ArgAttrSets) \
OMP_RTL_ATTRS(OMPRTL_##Name, FnAttrSet, RetAttrSet, ArgAttrSets)
+__OMP_RTL_ATTRS(__kmpc_barrier, AttributeSet(), AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_cancel,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_cancel_barrier, AttributeSet(), AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_flush, AttributeSet(), AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_global_thread_num, GetterAttrs, AttributeSet(), {})
__OMP_RTL_ATTRS(__kmpc_fork_call, AttributeSet(EnumAttr(NoUnwind)),
AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_taskwait, AttributeSet(), AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_taskyield,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_push_num_threads,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_push_proc_bind,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_serialized_parallel,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_serialized_parallel,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
-__OMP_RTL_ATTRS(__kmpc_global_thread_num, GetterAttrs, AttributeSet(), {})
__OMP_RTL_ATTRS(omp_get_thread_num, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_num_threads, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_max_threads, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_in_parallel, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_dynamic, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_cancellation, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_nested, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_schedule, GetterArgWriteAttrs, AttributeSet(),
+ ArrayRef<AttributeSet>(
+ {AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly)),
+ AttributeSet(EnumAttr(NoCapture), EnumAttr(WriteOnly))}))
+__OMP_RTL_ATTRS(omp_get_thread_limit, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_supported_active_levels, GetterAttrs, AttributeSet(),
+ {})
+__OMP_RTL_ATTRS(omp_get_max_active_levels, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_level, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_ancestor_thread_num, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_team_size, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_active_level, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_in_final, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_proc_bind, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_num_places, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_num_procs, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_place_proc_ids, GetterArgWriteAttrs, AttributeSet(),
+ ArrayRef<AttributeSet>({AttributeSet(),
+ AttributeSet(EnumAttr(NoCapture),
+ EnumAttr(WriteOnly))}))
+__OMP_RTL_ATTRS(omp_get_place_num, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_partition_num_places, GetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_get_partition_place_nums, GetterAttrs, AttributeSet(), {})
+
+__OMP_RTL_ATTRS(omp_set_num_threads, SetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_set_dynamic, SetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_set_nested, SetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_set_schedule, SetterAttrs, AttributeSet(), {})
+__OMP_RTL_ATTRS(omp_set_max_active_levels, SetterAttrs, AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_master,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_master,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_critical,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_critical_with_hint,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_critical,
+ AttributeSet(EnumAttr(InaccessibleMemOrArgMemOnly)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_begin, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_reduce, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_reduce_nowait, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_reduce, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_reduce_nowait, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_ordered, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_ordered, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_for_static_init_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_for_static_init_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_for_static_init_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_for_static_init_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_for_static_fini, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_dispatch_init_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_init_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_next_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dispatch_fini_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_team_static_init_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_team_static_init_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_team_static_init_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_team_static_init_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_4u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_dist_for_static_init_8u, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_single, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_single, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_omp_task_alloc, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_task, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_end_taskgroup, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_taskgroup, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_task_begin_if0, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_task_complete_if0, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_task_with_deps, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_taskloop, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_omp_target_task_alloc,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_taskred_modifier_init,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_taskred_init,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_fini,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_reduction_get_th_data,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_reduction_init,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_reduction_modifier_init,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_proxy_task_completed_ooo,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_omp_wait_deps, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_cancellationpoint, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_fork_teams, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_push_num_teams, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_copyprivate, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_threadprivate_cached, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_threadprivate_register, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_doacross_init, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_doacross_post, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_doacross_wait, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_doacross_fini, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_alloc, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_free, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_init_allocator, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_destroy_allocator, AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+
+__OMP_RTL_ATTRS(__kmpc_push_target_tripcount,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_nowait,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_teams,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_teams_nowait,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_register_requires,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_begin,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_begin_nowait,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_end,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_end_nowait,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_update,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_target_data_update_nowait,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_mapper_num_components,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__tgt_push_mapper_component,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
+__OMP_RTL_ATTRS(__kmpc_task_allow_completion_event,
+ AttributeSet(EnumAttr(NoUnwind)),
+ AttributeSet(), {})
#undef __OMP_RTL_ATTRS
#undef OMP_RTL_ATTRS
@@ -266,6 +970,26 @@ __OMP_CANCEL_KIND(taskgroup, 4)
///}
+/// Default kinds
+///
+///{
+
+#ifndef OMP_DEFAULT_KIND
+#define OMP_DEFAULT_KIND(Enum, Str)
+#endif
+
+#define __OMP_DEFAULT_KIND(Name) OMP_DEFAULT_KIND(OMP_DEFAULT_##Name, #Name)
+
+__OMP_DEFAULT_KIND(none)
+__OMP_DEFAULT_KIND(shared)
+__OMP_DEFAULT_KIND(firstprivate)
+__OMP_DEFAULT_KIND(unknown)
+
+#undef __OMP_DEFAULT_KIND
+#undef OMP_DEFAULT_KIND
+
+///}
+
/// Proc bind kinds
///
///{
@@ -287,3 +1011,145 @@ __OMP_PROC_BIND_KIND(unknown, 7)
#undef OMP_PROC_BIND_KIND
///}
+
+/// OpenMP context related definitions:
+/// - trait set selector
+/// - trait selector
+/// - trait property
+///
+///{
+
+#ifndef OMP_TRAIT_SET
+#define OMP_TRAIT_SET(Enum, Str)
+#endif
+#ifndef OMP_TRAIT_SELECTOR
+#define OMP_TRAIT_SELECTOR(Enum, TraitSetEnum, Str, RequiresProperty)
+#endif
+#ifndef OMP_TRAIT_PROPERTY
+#define OMP_TRAIT_PROPERTY(Enum, TraitSetEnum, TraitSelectorEnum, Str)
+#endif
+#ifndef OMP_LAST_TRAIT_PROPERTY
+#define OMP_LAST_TRAIT_PROPERTY(Enum)
+#endif
+
+#define __OMP_TRAIT_SET(Name) OMP_TRAIT_SET(Name, #Name)
+#define __OMP_TRAIT_SELECTOR(TraitSet, Name, RequiresProperty) \
+ OMP_TRAIT_SELECTOR(TraitSet##_##Name, TraitSet, #Name, RequiresProperty)
+#define __OMP_TRAIT_SELECTOR_AND_PROPERTY(TraitSet, Name) \
+ OMP_TRAIT_SELECTOR(TraitSet##_##Name, TraitSet, #Name, false) \
+ OMP_TRAIT_PROPERTY(TraitSet##_##Name##_##Name, TraitSet, TraitSet##_##Name, \
+ #Name)
+#define __OMP_TRAIT_PROPERTY(TraitSet, TraitSelector, Name) \
+ OMP_TRAIT_PROPERTY(TraitSet##_##TraitSelector##_##Name, TraitSet, \
+ TraitSet##_##TraitSelector, #Name)
+
+// "invalid" must go first.
+OMP_TRAIT_SET(invalid, "invalid")
+OMP_TRAIT_SELECTOR(invalid, invalid, "invalid", false)
+OMP_TRAIT_PROPERTY(invalid, invalid, invalid, "invalid")
+
+__OMP_TRAIT_SET(construct)
+__OMP_TRAIT_SELECTOR_AND_PROPERTY(construct, target)
+__OMP_TRAIT_SELECTOR_AND_PROPERTY(construct, teams)
+__OMP_TRAIT_SELECTOR_AND_PROPERTY(construct, parallel)
+__OMP_TRAIT_SELECTOR_AND_PROPERTY(construct, for)
+__OMP_TRAIT_SELECTOR_AND_PROPERTY(construct, simd)
+
+__OMP_TRAIT_SET(device)
+
+__OMP_TRAIT_SELECTOR(device, kind, true)
+
+__OMP_TRAIT_PROPERTY(device, kind, host)
+__OMP_TRAIT_PROPERTY(device, kind, nohost)
+__OMP_TRAIT_PROPERTY(device, kind, cpu)
+__OMP_TRAIT_PROPERTY(device, kind, gpu)
+__OMP_TRAIT_PROPERTY(device, kind, fpga)
+__OMP_TRAIT_PROPERTY(device, kind, any)
+
+__OMP_TRAIT_SELECTOR(device, isa, true)
+
+// TODO: What do we want for ISA?
+
+__OMP_TRAIT_SELECTOR(device, arch, true)
+
+__OMP_TRAIT_PROPERTY(device, arch, arm)
+__OMP_TRAIT_PROPERTY(device, arch, armeb)
+__OMP_TRAIT_PROPERTY(device, arch, aarch64)
+__OMP_TRAIT_PROPERTY(device, arch, aarch64_be)
+__OMP_TRAIT_PROPERTY(device, arch, aarch64_32)
+__OMP_TRAIT_PROPERTY(device, arch, ppc)
+__OMP_TRAIT_PROPERTY(device, arch, ppc64)
+__OMP_TRAIT_PROPERTY(device, arch, ppc64le)
+__OMP_TRAIT_PROPERTY(device, arch, x86)
+__OMP_TRAIT_PROPERTY(device, arch, x86_64)
+__OMP_TRAIT_PROPERTY(device, arch, amdgcn)
+__OMP_TRAIT_PROPERTY(device, arch, nvptx)
+__OMP_TRAIT_PROPERTY(device, arch, nvptx64)
+
+__OMP_TRAIT_SET(implementation)
+
+__OMP_TRAIT_SELECTOR(implementation, vendor, true)
+
+__OMP_TRAIT_PROPERTY(implementation, vendor, amd)
+__OMP_TRAIT_PROPERTY(implementation, vendor, arm)
+__OMP_TRAIT_PROPERTY(implementation, vendor, bsc)
+__OMP_TRAIT_PROPERTY(implementation, vendor, cray)
+__OMP_TRAIT_PROPERTY(implementation, vendor, fujitsu)
+__OMP_TRAIT_PROPERTY(implementation, vendor, gnu)
+__OMP_TRAIT_PROPERTY(implementation, vendor, ibm)
+__OMP_TRAIT_PROPERTY(implementation, vendor, intel)
+__OMP_TRAIT_PROPERTY(implementation, vendor, llvm)
+__OMP_TRAIT_PROPERTY(implementation, vendor, pgi)
+__OMP_TRAIT_PROPERTY(implementation, vendor, ti)
+__OMP_TRAIT_PROPERTY(implementation, vendor, unknown)
+
+__OMP_TRAIT_SELECTOR(implementation, extension, true)
+__OMP_TRAIT_PROPERTY(implementation, extension, match_all)
+__OMP_TRAIT_PROPERTY(implementation, extension, match_any)
+__OMP_TRAIT_PROPERTY(implementation, extension, match_none)
+
+__OMP_TRAIT_SET(user)
+
+__OMP_TRAIT_SELECTOR(user, condition, true)
+
+__OMP_TRAIT_PROPERTY(user, condition, true)
+__OMP_TRAIT_PROPERTY(user, condition, false)
+__OMP_TRAIT_PROPERTY(user, condition, unknown)
+
+#undef OMP_TRAIT_SET
+#undef __OMP_TRAIT_SET
+///}
+
+/// Traits for the requires directive
+///
+/// These will (potentially) become trait selectors for the OpenMP context if
+/// the OMP_REQUIRES_TRAIT macro is not defined.
+///
+///{
+
+#ifdef OMP_REQUIRES_TRAIT
+#define __OMP_REQUIRES_TRAIT(Name) \
+ OMP_REQUIRES_TRAIT(OMP_REQUIRES_TRAIT_##Name, #Name)
+#else
+#define __OMP_REQUIRES_TRAIT(Name) \
+ __OMP_TRAIT_SELECTOR_AND_PROPERTY(implementation, Name)
+#endif
+
+__OMP_REQUIRES_TRAIT(unified_address)
+__OMP_REQUIRES_TRAIT(unified_shared_memory)
+__OMP_REQUIRES_TRAIT(reverse_offload)
+__OMP_REQUIRES_TRAIT(dynamic_allocators)
+__OMP_REQUIRES_TRAIT(atomic_default_mem_order)
+
+OMP_LAST_TRAIT_PROPERTY(
+ implementation_atomic_default_mem_order_atomic_default_mem_order)
+
+#undef __OMP_TRAIT_SELECTOR_AND_PROPERTY
+#undef OMP_TRAIT_SELECTOR
+#undef __OMP_TRAIT_SELECTOR
+#undef OMP_TRAIT_PROPERTY
+#undef OMP_LAST_TRAIT_PROPERTY
+#undef __OMP_TRAIT_PROPERTY
+#undef __OMP_REQUIRES_TRAIT
+#undef OMP_REQUIRES_TRAIT
+///}
diff --git a/contrib/llvm-project/llvm/include/llvm/FuzzMutate/FuzzerCLI.h b/contrib/llvm-project/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
index 2a16e43a6ab3..27eec058b599 100644
--- a/contrib/llvm-project/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
+++ b/contrib/llvm-project/llvm/include/llvm/FuzzMutate/FuzzerCLI.h
@@ -14,12 +14,13 @@
#ifndef LLVM_FUZZMUTATE_FUZZER_CLI_H
#define LLVM_FUZZMUTATE_FUZZER_CLI_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
+class StringRef;
+
/// Parse cl::opts from a fuzz target commandline.
///
/// This handles all arguments after -ignore_remaining_args=1 as cl::opts.
diff --git a/contrib/llvm-project/llvm/include/llvm/FuzzMutate/Random.h b/contrib/llvm-project/llvm/include/llvm/FuzzMutate/Random.h
index 615b15f04ceb..9d3af3accb15 100644
--- a/contrib/llvm-project/llvm/include/llvm/FuzzMutate/Random.h
+++ b/contrib/llvm-project/llvm/include/llvm/FuzzMutate/Random.h
@@ -32,7 +32,7 @@ template <typename T, typename GenT> T uniform(GenT &Gen) {
/// elements, which may each be weighted to be more likely choices.
template <typename T, typename GenT> class ReservoirSampler {
GenT &RandGen;
- typename std::remove_const<T>::type Selection = {};
+ std::remove_const_t<T> Selection = {};
uint64_t TotalWeight = 0;
public:
@@ -70,8 +70,8 @@ public:
};
template <typename GenT, typename RangeT,
- typename ElT = typename std::remove_reference<
- decltype(*std::begin(std::declval<RangeT>()))>::type>
+ typename ElT = std::remove_reference_t<
+ decltype(*std::begin(std::declval<RangeT>()))>>
ReservoirSampler<ElT, GenT> makeSampler(GenT &RandGen, RangeT &&Items) {
ReservoirSampler<ElT, GenT> RS(RandGen);
RS.sample(Items);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/AbstractCallSite.h b/contrib/llvm-project/llvm/include/llvm/IR/AbstractCallSite.h
new file mode 100644
index 000000000000..e8cf05001542
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/AbstractCallSite.h
@@ -0,0 +1,247 @@
+//===- AbstractCallSite.h - Abstract call sites -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the AbstractCallSite class, which is a is a wrapper that
+// allows treating direct, indirect, and callback calls the same.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_ABSTRACTCALLSITE_H
+#define LLVM_IR_ABSTRACTCALLSITE_H
+
+#include "llvm/IR/Function.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Use.h"
+#include "llvm/IR/User.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+
+namespace llvm {
+
+/// AbstractCallSite
+///
+/// An abstract call site is a wrapper that allows to treat direct,
+/// indirect, and callback calls the same. If an abstract call site
+/// represents a direct or indirect call site it behaves like a stripped
+/// down version of a normal call site object. The abstract call site can
+/// also represent a callback call, thus the fact that the initially
+/// called function (=broker) may invoke a third one (=callback callee).
+/// In this case, the abstract call site hides the middle man, hence the
+/// broker function. The result is a representation of the callback call,
+/// inside the broker, but in the context of the original call to the broker.
+///
+/// There are up to three functions involved when we talk about callback call
+/// sites. The caller (1), which invokes the broker function. The broker
+/// function (2), that will invoke the callee zero or more times. And finally
+/// the callee (3), which is the target of the callback call.
+///
+/// The abstract call site will handle the mapping from parameters to arguments
+/// depending on the semantic of the broker function. However, it is important
+/// to note that the mapping is often partial. Thus, some arguments of the
+/// call/invoke instruction are mapped to parameters of the callee while others
+/// are not.
+class AbstractCallSite {
+public:
+
+ /// The encoding of a callback with regards to the underlying instruction.
+ struct CallbackInfo {
+
+ /// For direct/indirect calls the parameter encoding is empty. If it is not,
+ /// the abstract call site represents a callback. In that case, the first
+ /// element of the encoding vector represents which argument of the call
+ /// site CB is the callback callee. The remaining elements map parameters
+ /// (identified by their position) to the arguments that will be passed
+ /// through (also identified by position but in the call site instruction).
+ ///
+ /// NOTE that we use LLVM argument numbers (starting at 0) and not
+ /// clang/source argument numbers (starting at 1). The -1 entries represent
+ /// unknown values that are passed to the callee.
+ using ParameterEncodingTy = SmallVector<int, 0>;
+ ParameterEncodingTy ParameterEncoding;
+
+ };
+
+private:
+
+ /// The underlying call site:
+ /// caller -> callee, if this is a direct or indirect call site
+ /// caller -> broker function, if this is a callback call site
+ CallBase *CB;
+
+ /// The encoding of a callback with regards to the underlying instruction.
+ CallbackInfo CI;
+
+public:
+ /// Sole constructor for abstract call sites (ACS).
+ ///
+ /// An abstract call site can only be constructed through a llvm::Use because
+ /// each operand (=use) of an instruction could potentially be a different
+ /// abstract call site. Furthermore, even if the value of the llvm::Use is the
+ /// same, and the user is as well, the abstract call sites might not be.
+ ///
+ /// If a use is not associated with an abstract call site the constructed ACS
+ /// will evaluate to false if converted to a boolean.
+ ///
+ /// If the use is the callee use of a call or invoke instruction, the
+ /// constructed abstract call site will behave as a llvm::CallSite would.
+ ///
+ /// If the use is not a callee use of a call or invoke instruction, the
+ /// callback metadata is used to determine the argument <-> parameter mapping
+ /// as well as the callee of the abstract call site.
+ AbstractCallSite(const Use *U);
+
+ /// Add operand uses of \p CB that represent callback uses into
+ /// \p CallbackUses.
+ ///
+ /// All uses added to \p CallbackUses can be used to create abstract call
+ /// sites for which AbstractCallSite::isCallbackCall() will return true.
+ static void getCallbackUses(const CallBase &CB,
+ SmallVectorImpl<const Use *> &CallbackUses);
+
+ /// Conversion operator to conveniently check for a valid/initialized ACS.
+ explicit operator bool() const { return CB != nullptr; }
+
+ /// Return the underlying instruction.
+ CallBase *getInstruction() const { return CB; }
+
+ /// Return true if this ACS represents a direct call.
+ bool isDirectCall() const {
+ return !isCallbackCall() && !CB->isIndirectCall();
+ }
+
+ /// Return true if this ACS represents an indirect call.
+ bool isIndirectCall() const {
+ return !isCallbackCall() && CB->isIndirectCall();
+ }
+
+ /// Return true if this ACS represents a callback call.
+ bool isCallbackCall() const {
+ // For a callback call site the callee is ALWAYS stored first in the
+ // transitive values vector. Thus, a non-empty vector indicates a callback.
+ return !CI.ParameterEncoding.empty();
+ }
+
+ /// Return true if @p UI is the use that defines the callee of this ACS.
+ bool isCallee(Value::const_user_iterator UI) const {
+ return isCallee(&UI.getUse());
+ }
+
+ /// Return true if @p U is the use that defines the callee of this ACS.
+ bool isCallee(const Use *U) const {
+ if (isDirectCall())
+ return CB->isCallee(U);
+
+ assert(!CI.ParameterEncoding.empty() &&
+ "Callback without parameter encoding!");
+
+ // If the use is actually in a constant cast expression which itself
+ // has only one use, we look through the constant cast expression.
+ if (auto *CE = dyn_cast<ConstantExpr>(U->getUser()))
+ if (CE->hasOneUse() && CE->isCast())
+ U = &*CE->use_begin();
+
+ return (int)CB->getArgOperandNo(U) == CI.ParameterEncoding[0];
+ }
+
+ /// Return the number of parameters of the callee.
+ unsigned getNumArgOperands() const {
+ if (isDirectCall())
+ return CB->getNumArgOperands();
+ // Subtract 1 for the callee encoding.
+ return CI.ParameterEncoding.size() - 1;
+ }
+
+ /// Return the operand index of the underlying instruction associated with @p
+ /// Arg.
+ int getCallArgOperandNo(Argument &Arg) const {
+ return getCallArgOperandNo(Arg.getArgNo());
+ }
+
+ /// Return the operand index of the underlying instruction associated with
+ /// the function parameter number @p ArgNo or -1 if there is none.
+ int getCallArgOperandNo(unsigned ArgNo) const {
+ if (isDirectCall())
+ return ArgNo;
+ // Add 1 for the callee encoding.
+ return CI.ParameterEncoding[ArgNo + 1];
+ }
+
+ /// Return the operand of the underlying instruction associated with @p Arg.
+ Value *getCallArgOperand(Argument &Arg) const {
+ return getCallArgOperand(Arg.getArgNo());
+ }
+
+ /// Return the operand of the underlying instruction associated with the
+ /// function parameter number @p ArgNo or nullptr if there is none.
+ Value *getCallArgOperand(unsigned ArgNo) const {
+ if (isDirectCall())
+ return CB->getArgOperand(ArgNo);
+ // Add 1 for the callee encoding.
+ return CI.ParameterEncoding[ArgNo + 1] >= 0
+ ? CB->getArgOperand(CI.ParameterEncoding[ArgNo + 1])
+ : nullptr;
+ }
+
+ /// Return the operand index of the underlying instruction associated with the
+ /// callee of this ACS. Only valid for callback calls!
+ int getCallArgOperandNoForCallee() const {
+ assert(isCallbackCall());
+ assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] >= 0);
+ return CI.ParameterEncoding[0];
+ }
+
+ /// Return the use of the callee value in the underlying instruction. Only
+ /// valid for callback calls!
+ const Use &getCalleeUseForCallback() const {
+ int CalleeArgIdx = getCallArgOperandNoForCallee();
+ assert(CalleeArgIdx >= 0 &&
+ unsigned(CalleeArgIdx) < getInstruction()->getNumOperands());
+ return getInstruction()->getOperandUse(CalleeArgIdx);
+ }
+
+ /// Return the pointer to function that is being called.
+ Value *getCalledOperand() const {
+ if (isDirectCall())
+ return CB->getCalledOperand();
+ return CB->getArgOperand(getCallArgOperandNoForCallee());
+ }
+
+ /// Return the function being called if this is a direct call, otherwise
+ /// return null (if it's an indirect call).
+ Function *getCalledFunction() const {
+ Value *V = getCalledOperand();
+ return V ? dyn_cast<Function>(V->stripPointerCasts()) : nullptr;
+ }
+};
+
+/// Apply function Func to each CB's callback call site.
+template <typename UnaryFunction>
+void forEachCallbackCallSite(const CallBase &CB, UnaryFunction Func) {
+ SmallVector<const Use *, 4u> CallbackUses;
+ AbstractCallSite::getCallbackUses(CB, CallbackUses);
+ for (const Use *U : CallbackUses) {
+ AbstractCallSite ACS(U);
+ assert(ACS && ACS.isCallbackCall() && "must be a callback call");
+ Func(ACS);
+ }
+}
+
+/// Apply function Func to each CB's callback function.
+template <typename UnaryFunction>
+void forEachCallbackFunction(const CallBase &CB, UnaryFunction Func) {
+ forEachCallbackCallSite(CB, [&Func](AbstractCallSite &ACS) {
+ if (Function *Callback = ACS.getCalledFunction())
+ Func(Callback);
+ });
+}
+
+} // end namespace llvm
+
+#endif // LLVM_IR_ABSTRACTCALLSITE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Argument.h b/contrib/llvm-project/llvm/include/llvm/IR/Argument.h
index 244878bd3155..af469e8a5d1a 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Argument.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Argument.h
@@ -71,9 +71,13 @@ public:
/// Return true if this argument has the swifterror attribute.
bool hasSwiftErrorAttr() const;
- /// Return true if this argument has the byval attribute or inalloca
+ /// Return true if this argument has the byval, inalloca, or preallocated
/// attribute. These attributes represent arguments being passed by value.
- bool hasByValOrInAllocaAttr() const;
+ bool hasPassPointeeByValueAttr() const;
+
+ /// If this argument satisfies has hasPassPointeeByValueAttr, return the
+ /// in-memory ABI size copied to the stack for the call. Otherwise, return 0.
+ uint64_t getPassPointeeByValueCopySize(const DataLayout &DL) const;
/// If this is a byval or inalloca argument, return its alignment.
/// FIXME: Remove this function once transition to Align is over.
@@ -110,6 +114,9 @@ public:
/// Return true if this argument has the inalloca attribute.
bool hasInAllocaAttr() const;
+ /// Return true if this argument has the preallocated attribute.
+ bool hasPreallocatedAttr() const;
+
/// Return true if this argument has the zext attribute.
bool hasZExtAttr() const;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Attributes.h b/contrib/llvm-project/llvm/include/llvm/IR/Attributes.h
index e6b280465f72..58365aa2b764 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Attributes.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Attributes.h
@@ -17,7 +17,6 @@
#include "llvm-c/Types.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
@@ -38,6 +37,7 @@ class AttributeImpl;
class AttributeListImpl;
class AttributeSetNode;
template<typename T> struct DenseMapInfo;
+class FoldingSetNodeID;
class Function;
class LLVMContext;
class Type;
@@ -70,9 +70,12 @@ public:
enum AttrKind {
// IR-Level Attributes
None, ///< No attributes have been set
- #define GET_ATTR_ENUM
+ #define GET_ATTR_NAMES
+ #define ATTRIBUTE_ENUM(ENUM_NAME, OTHER) ENUM_NAME,
#include "llvm/IR/Attributes.inc"
- EndAttrKinds ///< Sentinal value useful for loops
+ EndAttrKinds, ///< Sentinal value useful for loops
+ EmptyKey, ///< Use as Empty key for DenseMap of AttrKind
+ TombstoneKey, ///< Use as Tombstone key for DenseMap of AttrKind
};
private:
@@ -105,6 +108,18 @@ public:
unsigned ElemSizeArg,
const Optional<unsigned> &NumElemsArg);
static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
+ static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty);
+
+ static Attribute::AttrKind getAttrKindFromName(StringRef AttrName);
+
+ static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind);
+
+ /// Return true if and only if the attribute has an Argument.
+ static bool doesAttrKindHaveArgument(Attribute::AttrKind AttrKind);
+
+ /// Return true if the provided string matches the IR name of an attribute.
+ /// example: "noalias" return true but not "NoAlias"
+ static bool isExistingAttribute(StringRef Name);
//===--------------------------------------------------------------------===//
// Attribute Accessors
@@ -180,9 +195,7 @@ public:
/// Less-than operator. Useful for sorting the attributes list.
bool operator<(Attribute A) const;
- void Profile(FoldingSetNodeID &ID) const {
- ID.AddPointer(pImpl);
- }
+ void Profile(FoldingSetNodeID &ID) const;
/// Return a raw pointer that uniquely identifies this attribute.
void *getRawPointer() const {
@@ -290,6 +303,7 @@ public:
uint64_t getDereferenceableBytes() const;
uint64_t getDereferenceableOrNullBytes() const;
Type *getByValType() const;
+ Type *getPreallocatedType() const;
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
std::string getAsString(bool InAttrGrp = false) const;
@@ -383,6 +397,9 @@ public:
static AttributeList get(LLVMContext &C, unsigned Index,
ArrayRef<Attribute::AttrKind> Kinds);
static AttributeList get(LLVMContext &C, unsigned Index,
+ ArrayRef<Attribute::AttrKind> Kinds,
+ ArrayRef<uint64_t> Values);
+ static AttributeList get(LLVMContext &C, unsigned Index,
ArrayRef<StringRef> Kind);
static AttributeList get(LLVMContext &C, unsigned Index,
const AttrBuilder &B);
@@ -530,9 +547,6 @@ public:
// AttributeList Accessors
//===--------------------------------------------------------------------===//
- /// Retrieve the LLVM context.
- LLVMContext &getContext() const;
-
/// The attributes for the specified index are returned.
AttributeSet getAttributes(unsigned Index) const;
@@ -612,6 +626,9 @@ public:
/// Return the byval type for the specified function parameter.
Type *getParamByValType(unsigned ArgNo) const;
+ /// Return the preallocated type for the specified function parameter.
+ Type *getParamPreallocatedType(unsigned ArgNo) const;
+
/// Get the stack alignment.
MaybeAlign getStackAlignment(unsigned Index) const;
@@ -712,6 +729,7 @@ class AttrBuilder {
uint64_t DerefOrNullBytes = 0;
uint64_t AllocSizeArgs = 0;
Type *ByValType = nullptr;
+ Type *PreallocatedType = nullptr;
public:
AttrBuilder() = default;
@@ -790,6 +808,9 @@ public:
/// Retrieve the byval type.
Type *getByValType() const { return ByValType; }
+ /// Retrieve the preallocated type.
+ Type *getPreallocatedType() const { return PreallocatedType; }
+
/// Retrieve the allocsize args, if the allocsize attribute exists. If it
/// doesn't exist, pair(0, 0) is returned.
std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
@@ -833,6 +854,9 @@ public:
/// This turns a byval type into the form used internally in Attribute.
AttrBuilder &addByValAttr(Type *Ty);
+ /// This turns a preallocated type into the form used internally in Attribute.
+ AttrBuilder &addPreallocatedAttr(Type *Ty);
+
/// Add an allocsize attribute, using the representation returned by
/// Attribute.getIntValue().
AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr);
@@ -843,8 +867,8 @@ public:
// Iterators for target-dependent attributes.
using td_type = std::pair<std::string, std::string>;
- using td_iterator = std::map<std::string, std::string>::iterator;
- using td_const_iterator = std::map<std::string, std::string>::const_iterator;
+ using td_iterator = decltype(TargetDepAttrs)::iterator;
+ using td_const_iterator = decltype(TargetDepAttrs)::const_iterator;
using td_range = iterator_range<td_iterator>;
using td_const_range = iterator_range<td_const_iterator>;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Attributes.td b/contrib/llvm-project/llvm/include/llvm/IR/Attributes.td
index 5d4a5f6743b7..395f9dbfb176 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Attributes.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Attributes.td
@@ -7,18 +7,24 @@ class Attr<string S> {
/// Enum attribute.
class EnumAttr<string S> : Attr<S>;
+/// Int attribute.
+class IntAttr<string S> : Attr<S>;
+
/// StringBool attribute.
class StrBoolAttr<string S> : Attr<S>;
+/// Type attribute.
+class TypeAttr<string S> : Attr<S>;
+
/// Target-independent enum attributes.
/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias.
/// 0 means unaligned (different from align(1)).
-def Alignment : EnumAttr<"align">;
+def Alignment : IntAttr<"align">;
/// The result of the function is guaranteed to point to a number of bytes that
/// we can determine if we know the value of the function's arguments.
-def AllocSize : EnumAttr<"allocsize">;
+def AllocSize : IntAttr<"allocsize">;
/// inline=always.
def AlwaysInline : EnumAttr<"alwaysinline">;
@@ -31,7 +37,10 @@ def ArgMemOnly : EnumAttr<"argmemonly">;
def Builtin : EnumAttr<"builtin">;
/// Pass structure by value.
-def ByVal : EnumAttr<"byval">;
+def ByVal : TypeAttr<"byval">;
+
+/// Parameter or return value may not contain uninitialized or poison bits.
+def NoUndef : EnumAttr<"noundef">;
/// Marks function as being in a cold path.
def Cold : EnumAttr<"cold">;
@@ -40,10 +49,10 @@ def Cold : EnumAttr<"cold">;
def Convergent : EnumAttr<"convergent">;
/// Pointer is known to be dereferenceable.
-def Dereferenceable : EnumAttr<"dereferenceable">;
+def Dereferenceable : IntAttr<"dereferenceable">;
/// Pointer is either null or dereferenceable.
-def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">;
+def DereferenceableOrNull : IntAttr<"dereferenceable_or_null">;
/// Function may only access memory that is inaccessible from IR.
def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">;
@@ -97,6 +106,9 @@ def NoInline : EnumAttr<"noinline">;
/// Function is called early and/or often, so lazy binding isn't worthwhile.
def NonLazyBind : EnumAttr<"nonlazybind">;
+/// Disable merging for call sites
+def NoMerge : EnumAttr<"nomerge">;
+
/// Pointer is known to be not null.
def NonNull : EnumAttr<"nonnull">;
@@ -118,6 +130,9 @@ def NoCfCheck : EnumAttr<"nocf_check">;
/// Function doesn't unwind stack.
def NoUnwind : EnumAttr<"nounwind">;
+/// Null pointer in address space zero is valid.
+def NullPointerIsValid : EnumAttr<"null_pointer_is_valid">;
+
/// Select optimizations for best fuzzing signal.
def OptForFuzzing : EnumAttr<"optforfuzzing">;
@@ -127,6 +142,9 @@ def OptimizeForSize : EnumAttr<"optsize">;
/// Function must not be optimized.
def OptimizeNone : EnumAttr<"optnone">;
+/// Similar to byval but without a copy.
+def Preallocated : TypeAttr<"preallocated">;
+
/// Function does not access memory.
def ReadNone : EnumAttr<"readnone">;
@@ -153,7 +171,7 @@ def SExt : EnumAttr<"signext">;
/// Alignment of stack for function (3 bits) stored as log2 of alignment with
/// +1 bias 0 means unaligned (different from alignstack=(1)).
-def StackAlignment : EnumAttr<"alignstack">;
+def StackAlignment : IntAttr<"alignstack">;
/// Function can be speculated.
def Speculatable : EnumAttr<"speculatable">;
@@ -218,10 +236,12 @@ def ZExt : EnumAttr<"zeroext">;
def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">;
+def NoSignedZerosFPMath : StrBoolAttr<"no-signed-zeros-fp-math">;
def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">;
def NoJumpTables : StrBoolAttr<"no-jump-tables">;
def NoInlineLineTables : StrBoolAttr<"no-inline-line-tables">;
def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">;
+def UseSampleProfile : StrBoolAttr<"use-sample-profile">;
class CompatRule<string F> {
// The name of the function called to check the attribute of the caller and
@@ -240,6 +260,7 @@ def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
def : CompatRule<"isEqual<SanitizeMemTagAttr>">;
def : CompatRule<"isEqual<SafeStackAttr>">;
def : CompatRule<"isEqual<ShadowCallStackAttr>">;
+def : CompatRule<"isEqual<UseSampleProfileAttr>">;
class MergeRule<string F> {
// The name of the function called to merge the attributes of the caller and
@@ -253,6 +274,7 @@ class MergeRule<string F> {
def : MergeRule<"setAND<LessPreciseFPMADAttr>">;
def : MergeRule<"setAND<NoInfsFPMathAttr>">;
def : MergeRule<"setAND<NoNansFPMathAttr>">;
+def : MergeRule<"setAND<NoSignedZerosFPMathAttr>">;
def : MergeRule<"setAND<UnsafeFPMathAttr>">;
def : MergeRule<"setOR<NoImplicitFloatAttr>">;
def : MergeRule<"setOR<NoJumpTablesAttr>">;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/AutoUpgrade.h b/contrib/llvm-project/llvm/include/llvm/IR/AutoUpgrade.h
index 42f50cc991de..f331fc3c413f 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/AutoUpgrade.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/AutoUpgrade.h
@@ -61,6 +61,9 @@ namespace llvm {
void UpgradeSectionAttributes(Module &M);
+ /// Correct any IR that is relying on old function attribute behavior.
+ void UpgradeFunctionAttributes(Function &F);
+
/// If the given TBAA tag uses the scalar TBAA format, create a new node
/// corresponding to the upgrade to the struct-path aware TBAA format.
/// Otherwise return the \p TBAANode itself.
@@ -92,9 +95,8 @@ namespace llvm {
/// pointers.
std::string UpgradeDataLayoutString(StringRef DL, StringRef Triple);
- /// Upgrade function attributes "no-frame-pointer-elim" and
- /// "no-frame-pointer-elim-non-leaf" to "frame-pointer".
- void UpgradeFramePointerAttributes(AttrBuilder &B);
+ /// Upgrade attributes that changed format or kind.
+ void UpgradeAttributes(AttrBuilder &B);
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/BasicBlock.h b/contrib/llvm-project/llvm/include/llvm/IR/BasicBlock.h
index d594145f8636..24d568a728c6 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/BasicBlock.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/BasicBlock.h
@@ -31,6 +31,7 @@
namespace llvm {
+class AssemblyAnnotationWriter;
class CallInst;
class Function;
class LandingPadInst;
@@ -133,6 +134,15 @@ public:
static_cast<const BasicBlock *>(this)->getTerminatingDeoptimizeCall());
}
+ /// Returns the call instruction calling \@llvm.experimental.deoptimize
+ /// that is present either in current basic block or in block that is a unique
+ /// successor to current block, if such call is present. Otherwise, returns null.
+ const CallInst *getPostdominatingDeoptimizeCall() const;
+ CallInst *getPostdominatingDeoptimizeCall() {
+ return const_cast<CallInst *>(
+ static_cast<const BasicBlock *>(this)->getPostdominatingDeoptimizeCall());
+ }
+
/// Returns the call instruction marked 'musttail' prior to the terminating
/// return instruction of this basic block, if such a call is present.
/// Otherwise, returns null.
@@ -267,6 +277,12 @@ public:
static_cast<const BasicBlock *>(this)->getUniqueSuccessor());
}
+ /// Print the basic block to an output stream with an optional
+ /// AssemblyAnnotationWriter.
+ void print(raw_ostream &OS, AssemblyAnnotationWriter *AAW = nullptr,
+ bool ShouldPreserveUseListOrder = false,
+ bool IsForDebug = false) const;
+
//===--------------------------------------------------------------------===//
/// Instruction iterator methods
///
@@ -361,12 +377,12 @@ public:
/// except operator delete.
void dropAllReferences();
- /// Notify the BasicBlock that the predecessor \p Pred is no longer able to
- /// reach it.
+ /// Update PHI nodes in this BasicBlock before removal of predecessor \p Pred.
+ /// Note that this function does not actually remove the predecessor.
///
- /// This is actually not used to update the Predecessor list, but is actually
- /// used to update the PHI nodes that reside in the block. Note that this
- /// should be called while the predecessor still refers to this block.
+ /// If \p KeepOneInputPHIs is true then don't remove PHIs that are left with
+ /// zero or one incoming values, and don't simplify PHIs with all incoming
+ /// values the same.
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs = false);
bool canSplitPredecessors() const;
@@ -393,7 +409,9 @@ public:
/// Returns true if there are any uses of this basic block other than
/// direct branches, switches, etc. to it.
- bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
+ bool hasAddressTaken() const {
+ return getBasicBlockBits().BlockAddressRefCount != 0;
+ }
/// Update all phi nodes in this basic block to refer to basic block \p New
/// instead of basic block \p Old.
@@ -428,16 +446,81 @@ public:
Optional<uint64_t> getIrrLoopHeaderWeight() const;
+ /// Returns true if the Order field of child Instructions is valid.
+ bool isInstrOrderValid() const {
+ return getBasicBlockBits().InstrOrderValid;
+ }
+
+ /// Mark instruction ordering invalid. Done on every instruction insert.
+ void invalidateOrders() {
+ validateInstrOrdering();
+ BasicBlockBits Bits = getBasicBlockBits();
+ Bits.InstrOrderValid = false;
+ setBasicBlockBits(Bits);
+ }
+
+ /// Renumber instructions and mark the ordering as valid.
+ void renumberInstructions();
+
+ /// Asserts that instruction order numbers are marked invalid, or that they
+ /// are in ascending order. This is constant time if the ordering is invalid,
+ /// and linear in the number of instructions if the ordering is valid. Callers
+ /// should be careful not to call this in ways that make common operations
+ /// O(n^2). For example, it takes O(n) time to assign order numbers to
+ /// instructions, so the order should be validated no more than once after
+ /// each ordering to ensure that transforms have the same algorithmic
+ /// complexity when asserts are enabled as when they are disabled.
+ void validateInstrOrdering() const;
+
private:
+#if defined(_AIX) && (!defined(__GNUC__) || defined(__ibmxl__))
+// Except for GCC; by default, AIX compilers store bit-fields in 4-byte words
+// and give the `pack` pragma push semantics.
+#define BEGIN_TWO_BYTE_PACK() _Pragma("pack(2)")
+#define END_TWO_BYTE_PACK() _Pragma("pack(pop)")
+#else
+#define BEGIN_TWO_BYTE_PACK()
+#define END_TWO_BYTE_PACK()
+#endif
+
+ BEGIN_TWO_BYTE_PACK()
+ /// Bitfield to help interpret the bits in Value::SubclassData.
+ struct BasicBlockBits {
+ unsigned short BlockAddressRefCount : 15;
+ unsigned short InstrOrderValid : 1;
+ };
+ END_TWO_BYTE_PACK()
+
+#undef BEGIN_TWO_BYTE_PACK
+#undef END_TWO_BYTE_PACK
+
+ /// Safely reinterpret the subclass data bits to a more useful form.
+ BasicBlockBits getBasicBlockBits() const {
+ static_assert(sizeof(BasicBlockBits) == sizeof(unsigned short),
+ "too many bits for Value::SubclassData");
+ unsigned short ValueData = getSubclassDataFromValue();
+ BasicBlockBits AsBits;
+ memcpy(&AsBits, &ValueData, sizeof(AsBits));
+ return AsBits;
+ }
+
+ /// Reinterpret our subclass bits and store them back into Value.
+ void setBasicBlockBits(BasicBlockBits AsBits) {
+ unsigned short D;
+ memcpy(&D, &AsBits, sizeof(D));
+ Value::setValueSubclassData(D);
+ }
+
/// Increment the internal refcount of the number of BlockAddresses
/// referencing this BasicBlock by \p Amt.
///
/// This is almost always 0, sometimes one possibly, but almost never 2, and
/// inconceivably 3 or more.
void AdjustBlockAddressRefCount(int Amt) {
- setValueSubclassData(getSubclassDataFromValue()+Amt);
- assert((int)(signed char)getSubclassDataFromValue() >= 0 &&
- "Refcount wrap-around");
+ BasicBlockBits Bits = getBasicBlockBits();
+ Bits.BlockAddressRefCount += Amt;
+ setBasicBlockBits(Bits);
+ assert(Bits.BlockAddressRefCount < 255 && "Refcount wrap-around");
}
/// Shadow Value::setValueSubclassData with a private forwarding method so
@@ -454,6 +537,12 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
/// This assumes that \p It is not at the end of a block.
BasicBlock::iterator skipDebugIntrinsics(BasicBlock::iterator It);
+#ifdef NDEBUG
+/// In release builds, this is a no-op. For !NDEBUG builds, the checks are
+/// implemented in the .cpp file to avoid circular header deps.
+inline void BasicBlock::validateInstrOrdering() const {}
+#endif
+
} // end namespace llvm
#endif // LLVM_IR_BASICBLOCK_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/CFG.h b/contrib/llvm-project/llvm/include/llvm/IR/CFG.h
index 55aff7137e86..f798b1af6c83 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/CFG.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/CFG.h
@@ -22,18 +22,19 @@
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
-#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/type_traits.h"
#include <cassert>
#include <cstddef>
#include <iterator>
namespace llvm {
+class BasicBlock;
+class Instruction;
+class Use;
+
//===----------------------------------------------------------------------===//
// BasicBlock pred_iterator definition
//===----------------------------------------------------------------------===//
@@ -103,7 +104,7 @@ using pred_iterator = PredIterator<BasicBlock, Value::user_iterator>;
using const_pred_iterator =
PredIterator<const BasicBlock, Value::const_user_iterator>;
using pred_range = iterator_range<pred_iterator>;
-using pred_const_range = iterator_range<const_pred_iterator>;
+using const_pred_range = iterator_range<const_pred_iterator>;
inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
inline const_pred_iterator pred_begin(const BasicBlock *BB) {
@@ -124,8 +125,8 @@ inline unsigned pred_size(const BasicBlock *BB) {
inline pred_range predecessors(BasicBlock *BB) {
return pred_range(pred_begin(BB), pred_end(BB));
}
-inline pred_const_range predecessors(const BasicBlock *BB) {
- return pred_const_range(pred_begin(BB), pred_end(BB));
+inline const_pred_range predecessors(const BasicBlock *BB) {
+ return const_pred_range(pred_begin(BB), pred_end(BB));
}
//===----------------------------------------------------------------------===//
@@ -238,17 +239,17 @@ public:
};
using succ_iterator = SuccIterator<Instruction, BasicBlock>;
-using succ_const_iterator = SuccIterator<const Instruction, const BasicBlock>;
+using const_succ_iterator = SuccIterator<const Instruction, const BasicBlock>;
using succ_range = iterator_range<succ_iterator>;
-using succ_const_range = iterator_range<succ_const_iterator>;
+using const_succ_range = iterator_range<const_succ_iterator>;
inline succ_iterator succ_begin(Instruction *I) { return succ_iterator(I); }
-inline succ_const_iterator succ_begin(const Instruction *I) {
- return succ_const_iterator(I);
+inline const_succ_iterator succ_begin(const Instruction *I) {
+ return const_succ_iterator(I);
}
inline succ_iterator succ_end(Instruction *I) { return succ_iterator(I, true); }
-inline succ_const_iterator succ_end(const Instruction *I) {
- return succ_const_iterator(I, true);
+inline const_succ_iterator succ_end(const Instruction *I) {
+ return const_succ_iterator(I, true);
}
inline bool succ_empty(const Instruction *I) {
return succ_begin(I) == succ_end(I);
@@ -259,21 +260,21 @@ inline unsigned succ_size(const Instruction *I) {
inline succ_range successors(Instruction *I) {
return succ_range(succ_begin(I), succ_end(I));
}
-inline succ_const_range successors(const Instruction *I) {
- return succ_const_range(succ_begin(I), succ_end(I));
+inline const_succ_range successors(const Instruction *I) {
+ return const_succ_range(succ_begin(I), succ_end(I));
}
inline succ_iterator succ_begin(BasicBlock *BB) {
return succ_iterator(BB->getTerminator());
}
-inline succ_const_iterator succ_begin(const BasicBlock *BB) {
- return succ_const_iterator(BB->getTerminator());
+inline const_succ_iterator succ_begin(const BasicBlock *BB) {
+ return const_succ_iterator(BB->getTerminator());
}
inline succ_iterator succ_end(BasicBlock *BB) {
return succ_iterator(BB->getTerminator(), true);
}
-inline succ_const_iterator succ_end(const BasicBlock *BB) {
- return succ_const_iterator(BB->getTerminator(), true);
+inline const_succ_iterator succ_end(const BasicBlock *BB) {
+ return const_succ_iterator(BB->getTerminator(), true);
}
inline bool succ_empty(const BasicBlock *BB) {
return succ_begin(BB) == succ_end(BB);
@@ -284,8 +285,8 @@ inline unsigned succ_size(const BasicBlock *BB) {
inline succ_range successors(BasicBlock *BB) {
return succ_range(succ_begin(BB), succ_end(BB));
}
-inline succ_const_range successors(const BasicBlock *BB) {
- return succ_const_range(succ_begin(BB), succ_end(BB));
+inline const_succ_range successors(const BasicBlock *BB) {
+ return const_succ_range(succ_begin(BB), succ_end(BB));
}
//===--------------------------------------------------------------------===//
@@ -306,7 +307,7 @@ template <> struct GraphTraits<BasicBlock*> {
template <> struct GraphTraits<const BasicBlock*> {
using NodeRef = const BasicBlock *;
- using ChildIteratorType = succ_const_iterator;
+ using ChildIteratorType = const_succ_iterator;
static NodeRef getEntryNode(const BasicBlock *BB) { return BB; }
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/CFGDiff.h b/contrib/llvm-project/llvm/include/llvm/IR/CFGDiff.h
deleted file mode 100644
index 57b62dd66a47..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/IR/CFGDiff.h
+++ /dev/null
@@ -1,284 +0,0 @@
-//===- CFGDiff.h - Define a CFG snapshot. -----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines specializations of GraphTraits that allows generic
-// algorithms to see a different snapshot of a CFG.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_CFGDIFF_H
-#define LLVM_IR_CFGDIFF_H
-
-#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CFG.h"
-#include "llvm/Support/CFGUpdate.h"
-#include "llvm/Support/type_traits.h"
-#include <cassert>
-#include <cstddef>
-#include <iterator>
-
-// Two booleans are used to define orders in graphs:
-// InverseGraph defines when we need to reverse the whole graph and is as such
-// also equivalent to applying updates in reverse.
-// InverseEdge defines whether we want to change the edges direction. E.g., for
-// a non-inversed graph, the children are naturally the successors when
-// InverseEdge is false and the predecessors when InverseEdge is true.
-
-// We define two base clases that call into GraphDiff, one for successors
-// (CFGSuccessors), where InverseEdge is false, and one for predecessors
-// (CFGPredecessors), where InverseEdge is true.
-// FIXME: Further refactoring may merge the two base classes into a single one
-// templated / parametrized on using succ_iterator/pred_iterator and false/true
-// for the InverseEdge.
-
-// CFGViewSuccessors and CFGViewPredecessors, both can be parametrized to
-// consider the graph inverted or not (i.e. InverseGraph). Successors
-// implicitly has InverseEdge = false and Predecessors implicitly has
-// InverseEdge = true (see calls to GraphDiff methods in there). The GraphTraits
-// instantiations that follow define the value of InverseGraph.
-
-// GraphTraits instantiations:
-// - GraphDiff<BasicBlock *> is equivalent to InverseGraph = false
-// - GraphDiff<Inverse<BasicBlock *>> is equivalent to InverseGraph = true
-// - second pair item is BasicBlock *, then InverseEdge = false (so it inherits
-// from CFGViewSuccessors).
-// - second pair item is Inverse<BasicBlock *>, then InverseEdge = true (so it
-// inherits from CFGViewPredecessors).
-
-// The 4 GraphTraits are as follows:
-// 1. std::pair<const GraphDiff<BasicBlock *> *, BasicBlock *>> :
-// CFGViewSuccessors<false>
-// Regular CFG, children means successors, InverseGraph = false,
-// InverseEdge = false.
-// 2. std::pair<const GraphDiff<Inverse<BasicBlock *>> *, BasicBlock *>> :
-// CFGViewSuccessors<true>
-// Reverse the graph, get successors but reverse-apply updates,
-// InverseGraph = true, InverseEdge = false.
-// 3. std::pair<const GraphDiff<BasicBlock *> *, Inverse<BasicBlock *>>> :
-// CFGViewPredecessors<false>
-// Regular CFG, reverse edges, so children mean predecessors,
-// InverseGraph = false, InverseEdge = true.
-// 4. std::pair<const GraphDiff<Inverse<BasicBlock *>> *, Inverse<BasicBlock *>>
-// : CFGViewPredecessors<true>
-// Reverse the graph and the edges, InverseGraph = true, InverseEdge = true.
-
-namespace llvm {
-
-// GraphDiff defines a CFG snapshot: given a set of Update<NodePtr>, provide
-// utilities to skip edges marked as deleted and return a set of edges marked as
-// newly inserted. The current diff treats the CFG as a graph rather than a
-// multigraph. Added edges are pruned to be unique, and deleted edges will
-// remove all existing edges between two blocks.
-template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
- using UpdateMapType = SmallDenseMap<NodePtr, SmallVector<NodePtr, 2>>;
- UpdateMapType SuccInsert;
- UpdateMapType SuccDelete;
- UpdateMapType PredInsert;
- UpdateMapType PredDelete;
- // Using a singleton empty vector for all BasicBlock requests with no
- // children.
- SmallVector<NodePtr, 1> Empty;
-
- void printMap(raw_ostream &OS, const UpdateMapType &M) const {
- for (auto Pair : M)
- for (auto Child : Pair.second) {
- OS << "(";
- Pair.first->printAsOperand(OS, false);
- OS << ", ";
- Child->printAsOperand(OS, false);
- OS << ") ";
- }
- OS << "\n";
- }
-
-public:
- GraphDiff() {}
- GraphDiff(ArrayRef<cfg::Update<NodePtr>> Updates) {
- SmallVector<cfg::Update<NodePtr>, 4> LegalizedUpdates;
- cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph);
- for (auto U : LegalizedUpdates) {
- if (U.getKind() == cfg::UpdateKind::Insert) {
- SuccInsert[U.getFrom()].push_back(U.getTo());
- PredInsert[U.getTo()].push_back(U.getFrom());
- } else {
- SuccDelete[U.getFrom()].push_back(U.getTo());
- PredDelete[U.getTo()].push_back(U.getFrom());
- }
- }
- }
-
- bool ignoreChild(const NodePtr BB, NodePtr EdgeEnd, bool InverseEdge) const {
- auto &DeleteChildren =
- (InverseEdge != InverseGraph) ? PredDelete : SuccDelete;
- auto It = DeleteChildren.find(BB);
- if (It == DeleteChildren.end())
- return false;
- auto &EdgesForBB = It->second;
- return llvm::find(EdgesForBB, EdgeEnd) != EdgesForBB.end();
- }
-
- iterator_range<typename SmallVectorImpl<NodePtr>::const_iterator>
- getAddedChildren(const NodePtr BB, bool InverseEdge) const {
- auto &InsertChildren =
- (InverseEdge != InverseGraph) ? PredInsert : SuccInsert;
- auto It = InsertChildren.find(BB);
- if (It == InsertChildren.end())
- return make_range(Empty.begin(), Empty.end());
- return make_range(It->second.begin(), It->second.end());
- }
-
- void print(raw_ostream &OS) const {
- OS << "===== GraphDiff: CFG edge changes to create a CFG snapshot. \n"
- "===== (Note: notion of children/inverse_children depends on "
- "the direction of edges and the graph.)\n";
- OS << "Children to insert:\n\t";
- printMap(OS, SuccInsert);
- OS << "Children to delete:\n\t";
- printMap(OS, SuccDelete);
- OS << "Inverse_children to insert:\n\t";
- printMap(OS, PredInsert);
- OS << "Inverse_children to delete:\n\t";
- printMap(OS, PredDelete);
- OS << "\n";
- }
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
-#endif
-};
-
-template <bool InverseGraph = false> struct CFGViewSuccessors {
- using DataRef = const GraphDiff<BasicBlock *, InverseGraph> *;
- using NodeRef = std::pair<DataRef, BasicBlock *>;
-
- using ExistingChildIterator =
- WrappedPairNodeDataIterator<succ_iterator, NodeRef, DataRef>;
- struct DeletedEdgesFilter {
- BasicBlock *BB;
- DeletedEdgesFilter(BasicBlock *BB) : BB(BB){};
- bool operator()(NodeRef N) const {
- return !N.first->ignoreChild(BB, N.second, false);
- }
- };
- using FilterExistingChildrenIterator =
- filter_iterator<ExistingChildIterator, DeletedEdgesFilter>;
-
- using vec_iterator = SmallVectorImpl<BasicBlock *>::const_iterator;
- using AddNewChildrenIterator =
- WrappedPairNodeDataIterator<vec_iterator, NodeRef, DataRef>;
- using ChildIteratorType =
- concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>;
-
- static ChildIteratorType child_begin(NodeRef N) {
- auto InsertVec = N.first->getAddedChildren(N.second, false);
- // filter iterator init:
- auto firstit = make_filter_range(
- make_range<ExistingChildIterator>({succ_begin(N.second), N.first},
- {succ_end(N.second), N.first}),
- DeletedEdgesFilter(N.second));
- // new inserts iterator init:
- auto secondit = make_range<AddNewChildrenIterator>(
- {InsertVec.begin(), N.first}, {InsertVec.end(), N.first});
-
- return concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>(firstit, secondit);
- }
-
- static ChildIteratorType child_end(NodeRef N) {
- auto InsertVec = N.first->getAddedChildren(N.second, false);
- // filter iterator init:
- auto firstit = make_filter_range(
- make_range<ExistingChildIterator>({succ_end(N.second), N.first},
- {succ_end(N.second), N.first}),
- DeletedEdgesFilter(N.second));
- // new inserts iterator init:
- auto secondit = make_range<AddNewChildrenIterator>(
- {InsertVec.end(), N.first}, {InsertVec.end(), N.first});
-
- return concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>(firstit, secondit);
- }
-};
-
-template <bool InverseGraph = false> struct CFGViewPredecessors {
- using DataRef = const GraphDiff<BasicBlock *, InverseGraph> *;
- using NodeRef = std::pair<DataRef, BasicBlock *>;
-
- using ExistingChildIterator =
- WrappedPairNodeDataIterator<pred_iterator, NodeRef, DataRef>;
- struct DeletedEdgesFilter {
- BasicBlock *BB;
- DeletedEdgesFilter(BasicBlock *BB) : BB(BB){};
- bool operator()(NodeRef N) const {
- return !N.first->ignoreChild(BB, N.second, true);
- }
- };
- using FilterExistingChildrenIterator =
- filter_iterator<ExistingChildIterator, DeletedEdgesFilter>;
-
- using vec_iterator = SmallVectorImpl<BasicBlock *>::const_iterator;
- using AddNewChildrenIterator =
- WrappedPairNodeDataIterator<vec_iterator, NodeRef, DataRef>;
- using ChildIteratorType =
- concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>;
-
- static ChildIteratorType child_begin(NodeRef N) {
- auto InsertVec = N.first->getAddedChildren(N.second, true);
- // filter iterator init:
- auto firstit = make_filter_range(
- make_range<ExistingChildIterator>({pred_begin(N.second), N.first},
- {pred_end(N.second), N.first}),
- DeletedEdgesFilter(N.second));
- // new inserts iterator init:
- auto secondit = make_range<AddNewChildrenIterator>(
- {InsertVec.begin(), N.first}, {InsertVec.end(), N.first});
-
- return concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>(firstit, secondit);
- }
-
- static ChildIteratorType child_end(NodeRef N) {
- auto InsertVec = N.first->getAddedChildren(N.second, true);
- // filter iterator init:
- auto firstit = make_filter_range(
- make_range<ExistingChildIterator>({pred_end(N.second), N.first},
- {pred_end(N.second), N.first}),
- DeletedEdgesFilter(N.second));
- // new inserts iterator init:
- auto secondit = make_range<AddNewChildrenIterator>(
- {InsertVec.end(), N.first}, {InsertVec.end(), N.first});
-
- return concat_iterator<NodeRef, FilterExistingChildrenIterator,
- AddNewChildrenIterator>(firstit, secondit);
- }
-};
-
-template <>
-struct GraphTraits<
- std::pair<const GraphDiff<BasicBlock *, false> *, BasicBlock *>>
- : CFGViewSuccessors<false> {};
-template <>
-struct GraphTraits<
- std::pair<const GraphDiff<BasicBlock *, true> *, BasicBlock *>>
- : CFGViewSuccessors<true> {};
-template <>
-struct GraphTraits<
- std::pair<const GraphDiff<BasicBlock *, false> *, Inverse<BasicBlock *>>>
- : CFGViewPredecessors<false> {};
-template <>
-struct GraphTraits<
- std::pair<const GraphDiff<BasicBlock *, true> *, Inverse<BasicBlock *>>>
- : CFGViewPredecessors<true> {};
-} // end namespace llvm
-
-#endif // LLVM_IR_CFGDIFF_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/CallSite.h b/contrib/llvm-project/llvm/include/llvm/IR/CallSite.h
deleted file mode 100644
index 0e957c4797e8..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/IR/CallSite.h
+++ /dev/null
@@ -1,926 +0,0 @@
-//===- CallSite.h - Abstract Call & Invoke instrs ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CallSite class, which is a handy wrapper for code that
-// wants to treat Call, Invoke and CallBr instructions in a generic way. When
-// in non-mutation context (e.g. an analysis) ImmutableCallSite should be used.
-// Finally, when some degree of customization is necessary between these two
-// extremes, CallSiteBase<> can be supplied with fine-tuned parameters.
-//
-// NOTE: These classes are supposed to have "value semantics". So they should be
-// passed by value, not by reference; they should not be "new"ed or "delete"d.
-// They are efficiently copyable, assignable and constructable, with cost
-// equivalent to copying a pointer (notice that they have only a single data
-// member). The internal representation carries a flag which indicates which of
-// the three variants is enclosed. This allows for cheaper checks when various
-// accessors of CallSite are employed.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_CALLSITE_H
-#define LLVM_IR_CALLSITE_H
-
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Use.h"
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
-#include "llvm/Support/Casting.h"
-#include <cassert>
-#include <cstdint>
-#include <iterator>
-
-namespace llvm {
-
-namespace Intrinsic {
-typedef unsigned ID;
-}
-
-template <typename FunTy = const Function, typename BBTy = const BasicBlock,
- typename ValTy = const Value, typename UserTy = const User,
- typename UseTy = const Use, typename InstrTy = const Instruction,
- typename CallTy = const CallInst,
- typename InvokeTy = const InvokeInst,
- typename CallBrTy = const CallBrInst,
- typename IterTy = User::const_op_iterator>
-class CallSiteBase {
-protected:
- PointerIntPair<InstrTy *, 2, int> I;
-
- CallSiteBase() = default;
- CallSiteBase(CallTy *CI) : I(CI, 1) { assert(CI); }
- CallSiteBase(InvokeTy *II) : I(II, 0) { assert(II); }
- CallSiteBase(CallBrTy *CBI) : I(CBI, 2) { assert(CBI); }
- explicit CallSiteBase(ValTy *II) { *this = get(II); }
-
-private:
- /// This static method is like a constructor. It will create an appropriate
- /// call site for a Call, Invoke or CallBr instruction, but it can also create
- /// a null initialized CallSiteBase object for something which is NOT a call
- /// site.
- static CallSiteBase get(ValTy *V) {
- if (InstrTy *II = dyn_cast<InstrTy>(V)) {
- if (II->getOpcode() == Instruction::Call)
- return CallSiteBase(static_cast<CallTy*>(II));
- if (II->getOpcode() == Instruction::Invoke)
- return CallSiteBase(static_cast<InvokeTy*>(II));
- if (II->getOpcode() == Instruction::CallBr)
- return CallSiteBase(static_cast<CallBrTy *>(II));
- }
- return CallSiteBase();
- }
-
-public:
- /// Return true if a CallInst is enclosed.
- bool isCall() const { return I.getInt() == 1; }
-
- /// Return true if a InvokeInst is enclosed. !I.getInt() may also signify a
- /// NULL instruction pointer, so check that.
- bool isInvoke() const { return getInstruction() && I.getInt() == 0; }
-
- /// Return true if a CallBrInst is enclosed.
- bool isCallBr() const { return I.getInt() == 2; }
-
- InstrTy *getInstruction() const { return I.getPointer(); }
- InstrTy *operator->() const { return I.getPointer(); }
- explicit operator bool() const { return I.getPointer(); }
-
- /// Get the basic block containing the call site.
- BBTy* getParent() const { return getInstruction()->getParent(); }
-
- /// Return the pointer to function that is being called.
- ValTy *getCalledValue() const {
- assert(getInstruction() && "Not a call, invoke or callbr instruction!");
- return *getCallee();
- }
-
- /// Return the function being called if this is a direct call, otherwise
- /// return null (if it's an indirect call).
- FunTy *getCalledFunction() const {
- return dyn_cast<FunTy>(getCalledValue());
- }
-
- /// Return true if the callsite is an indirect call.
- bool isIndirectCall() const {
- const Value *V = getCalledValue();
- if (!V)
- return false;
- if (isa<FunTy>(V) || isa<Constant>(V))
- return false;
- if (const CallBase *CB = dyn_cast<CallBase>(getInstruction()))
- if (CB->isInlineAsm())
- return false;
- return true;
- }
-
- /// Set the callee to the specified value. Unlike the function of the same
- /// name on CallBase, does not modify the type!
- void setCalledFunction(Value *V) {
- assert(getInstruction() && "Not a call, callbr, or invoke instruction!");
- assert(cast<PointerType>(V->getType())->getElementType() ==
- cast<CallBase>(getInstruction())->getFunctionType() &&
- "New callee type does not match FunctionType on call");
- *getCallee() = V;
- }
-
- /// Return the intrinsic ID of the intrinsic called by this CallSite,
- /// or Intrinsic::not_intrinsic if the called function is not an
- /// intrinsic, or if this CallSite is an indirect call.
- Intrinsic::ID getIntrinsicID() const {
- if (auto *F = getCalledFunction())
- return F->getIntrinsicID();
- // Don't use Intrinsic::not_intrinsic, as it will require pulling
- // Intrinsics.h into every header that uses CallSite.
- return static_cast<Intrinsic::ID>(0);
- }
-
- /// Determine whether the passed iterator points to the callee operand's Use.
- bool isCallee(Value::const_user_iterator UI) const {
- return isCallee(&UI.getUse());
- }
-
- /// Determine whether this Use is the callee operand's Use.
- bool isCallee(const Use *U) const { return getCallee() == U; }
-
- /// Determine whether the passed iterator points to an argument operand.
- bool isArgOperand(Value::const_user_iterator UI) const {
- return isArgOperand(&UI.getUse());
- }
-
- /// Determine whether the passed use points to an argument operand.
- bool isArgOperand(const Use *U) const {
- assert(getInstruction() == U->getUser());
- return arg_begin() <= U && U < arg_end();
- }
-
- /// Determine whether the passed iterator points to a bundle operand.
- bool isBundleOperand(Value::const_user_iterator UI) const {
- return isBundleOperand(&UI.getUse());
- }
-
- /// Determine whether the passed use points to a bundle operand.
- bool isBundleOperand(const Use *U) const {
- assert(getInstruction() == U->getUser());
- if (!hasOperandBundles())
- return false;
- unsigned OperandNo = U - (*this)->op_begin();
- return getBundleOperandsStartIndex() <= OperandNo &&
- OperandNo < getBundleOperandsEndIndex();
- }
-
- /// Determine whether the passed iterator points to a data operand.
- bool isDataOperand(Value::const_user_iterator UI) const {
- return isDataOperand(&UI.getUse());
- }
-
- /// Determine whether the passed use points to a data operand.
- bool isDataOperand(const Use *U) const {
- return data_operands_begin() <= U && U < data_operands_end();
- }
-
- ValTy *getArgument(unsigned ArgNo) const {
- assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
- return *(arg_begin() + ArgNo);
- }
-
- void setArgument(unsigned ArgNo, Value* newVal) {
- assert(getInstruction() && "Not a call, invoke or callbr instruction!");
- assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
- getInstruction()->setOperand(ArgNo, newVal);
- }
-
- /// Given a value use iterator, returns the argument that corresponds to it.
- /// Iterator must actually correspond to an argument.
- unsigned getArgumentNo(Value::const_user_iterator I) const {
- return getArgumentNo(&I.getUse());
- }
-
- /// Given a use for an argument, get the argument number that corresponds to
- /// it.
- unsigned getArgumentNo(const Use *U) const {
- assert(getInstruction() && "Not a call, invoke or callbr instruction!");
- assert(isArgOperand(U) && "Argument # out of range!");
- return U - arg_begin();
- }
-
- /// The type of iterator to use when looping over actual arguments at this
- /// call site.
- using arg_iterator = IterTy;
-
- iterator_range<IterTy> args() const {
- return make_range(arg_begin(), arg_end());
- }
- bool arg_empty() const { return arg_end() == arg_begin(); }
- unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
-
- /// Given a value use iterator, return the data operand corresponding to it.
- /// Iterator must actually correspond to a data operand.
- unsigned getDataOperandNo(Value::const_user_iterator UI) const {
- return getDataOperandNo(&UI.getUse());
- }
-
- /// Given a use for a data operand, get the data operand number that
- /// corresponds to it.
- unsigned getDataOperandNo(const Use *U) const {
- assert(getInstruction() && "Not a call, invoke or callbr instruction!");
- assert(isDataOperand(U) && "Data operand # out of range!");
- return U - data_operands_begin();
- }
-
- /// Type of iterator to use when looping over data operands at this call site
- /// (see below).
- using data_operand_iterator = IterTy;
-
- /// data_operands_begin/data_operands_end - Return iterators iterating over
- /// the call / invoke / callbr argument list and bundle operands. For invokes,
- /// this is the set of instruction operands except the invoke target and the
- /// two successor blocks; for calls this is the set of instruction operands
- /// except the call target; for callbrs the number of labels to skip must be
- /// determined first.
-
- IterTy data_operands_begin() const {
- assert(getInstruction() && "Not a call or invoke instruction!");
- return cast<CallBase>(getInstruction())->data_operands_begin();
- }
- IterTy data_operands_end() const {
- assert(getInstruction() && "Not a call or invoke instruction!");
- return cast<CallBase>(getInstruction())->data_operands_end();
- }
- iterator_range<IterTy> data_ops() const {
- return make_range(data_operands_begin(), data_operands_end());
- }
- bool data_operands_empty() const {
- return data_operands_end() == data_operands_begin();
- }
- unsigned data_operands_size() const {
- return std::distance(data_operands_begin(), data_operands_end());
- }
-
- /// Return the type of the instruction that generated this call site.
- Type *getType() const { return (*this)->getType(); }
-
- /// Return the caller function for this call site.
- FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
-
- /// Tests if this call site must be tail call optimized. Only a CallInst can
- /// be tail call optimized.
- bool isMustTailCall() const {
- return isCall() && cast<CallInst>(getInstruction())->isMustTailCall();
- }
-
- /// Tests if this call site is marked as a tail call.
- bool isTailCall() const {
- return isCall() && cast<CallInst>(getInstruction())->isTailCall();
- }
-
-#define CALLSITE_DELEGATE_GETTER(METHOD) \
- InstrTy *II = getInstruction(); \
- return isCall() ? cast<CallInst>(II)->METHOD \
- : isCallBr() ? cast<CallBrInst>(II)->METHOD \
- : cast<InvokeInst>(II)->METHOD
-
-#define CALLSITE_DELEGATE_SETTER(METHOD) \
- InstrTy *II = getInstruction(); \
- if (isCall()) \
- cast<CallInst>(II)->METHOD; \
- else if (isCallBr()) \
- cast<CallBrInst>(II)->METHOD; \
- else \
- cast<InvokeInst>(II)->METHOD
-
- unsigned getNumArgOperands() const {
- CALLSITE_DELEGATE_GETTER(getNumArgOperands());
- }
-
- ValTy *getArgOperand(unsigned i) const {
- CALLSITE_DELEGATE_GETTER(getArgOperand(i));
- }
-
- ValTy *getReturnedArgOperand() const {
- CALLSITE_DELEGATE_GETTER(getReturnedArgOperand());
- }
-
- bool isInlineAsm() const {
- return cast<CallBase>(getInstruction())->isInlineAsm();
- }
-
- /// Get the calling convention of the call.
- CallingConv::ID getCallingConv() const {
- CALLSITE_DELEGATE_GETTER(getCallingConv());
- }
- /// Set the calling convention of the call.
- void setCallingConv(CallingConv::ID CC) {
- CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
- }
-
- FunctionType *getFunctionType() const {
- CALLSITE_DELEGATE_GETTER(getFunctionType());
- }
-
- void mutateFunctionType(FunctionType *Ty) const {
- CALLSITE_DELEGATE_SETTER(mutateFunctionType(Ty));
- }
-
- /// Get the parameter attributes of the call.
- AttributeList getAttributes() const {
- CALLSITE_DELEGATE_GETTER(getAttributes());
- }
- /// Set the parameter attributes of the call.
- void setAttributes(AttributeList PAL) {
- CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
- }
-
- void addAttribute(unsigned i, Attribute::AttrKind Kind) {
- CALLSITE_DELEGATE_SETTER(addAttribute(i, Kind));
- }
-
- void addAttribute(unsigned i, Attribute Attr) {
- CALLSITE_DELEGATE_SETTER(addAttribute(i, Attr));
- }
-
- void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- CALLSITE_DELEGATE_SETTER(addParamAttr(ArgNo, Kind));
- }
-
- void removeAttribute(unsigned i, Attribute::AttrKind Kind) {
- CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
- }
-
- void removeAttribute(unsigned i, StringRef Kind) {
- CALLSITE_DELEGATE_SETTER(removeAttribute(i, Kind));
- }
-
- void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) {
- CALLSITE_DELEGATE_SETTER(removeParamAttr(ArgNo, Kind));
- }
-
- /// Return true if this function has the given attribute.
- bool hasFnAttr(Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(hasFnAttr(Kind));
- }
-
- /// Return true if this function has the given attribute.
- bool hasFnAttr(StringRef Kind) const {
- CALLSITE_DELEGATE_GETTER(hasFnAttr(Kind));
- }
-
- /// Return true if this return value has the given attribute.
- bool hasRetAttr(Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(hasRetAttr(Kind));
- }
-
- /// Return true if the call or the callee has the given attribute.
- bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(paramHasAttr(ArgNo, Kind));
- }
-
- Attribute getAttribute(unsigned i, Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(getAttribute(i, Kind));
- }
-
- Attribute getAttribute(unsigned i, StringRef Kind) const {
- CALLSITE_DELEGATE_GETTER(getAttribute(i, Kind));
- }
-
- /// Return true if the data operand at index \p i directly or indirectly has
- /// the attribute \p A.
- ///
- /// Normal call, invoke or callbr arguments have per operand attributes, as
- /// specified in the attribute set attached to this instruction, while operand
- /// bundle operands may have some attributes implied by the type of its
- /// containing operand bundle.
- bool dataOperandHasImpliedAttr(unsigned i, Attribute::AttrKind Kind) const {
- CALLSITE_DELEGATE_GETTER(dataOperandHasImpliedAttr(i, Kind));
- }
-
- /// Extract the alignment of the return value.
- unsigned getRetAlignment() const {
- CALLSITE_DELEGATE_GETTER(getRetAlignment());
- }
-
- /// Extract the alignment for a call or parameter (0=unknown).
- unsigned getParamAlignment(unsigned ArgNo) const {
- CALLSITE_DELEGATE_GETTER(getParamAlignment(ArgNo));
- }
-
- /// Extract the byval type for a call or parameter (nullptr=unknown).
- Type *getParamByValType(unsigned ArgNo) const {
- CALLSITE_DELEGATE_GETTER(getParamByValType(ArgNo));
- }
-
- /// Extract the number of dereferenceable bytes for a call or parameter
- /// (0=unknown).
- uint64_t getDereferenceableBytes(unsigned i) const {
- CALLSITE_DELEGATE_GETTER(getDereferenceableBytes(i));
- }
-
- /// Extract the number of dereferenceable_or_null bytes for a call or
- /// parameter (0=unknown).
- uint64_t getDereferenceableOrNullBytes(unsigned i) const {
- CALLSITE_DELEGATE_GETTER(getDereferenceableOrNullBytes(i));
- }
-
- /// Determine if the return value is marked with NoAlias attribute.
- bool returnDoesNotAlias() const {
- CALLSITE_DELEGATE_GETTER(returnDoesNotAlias());
- }
-
- /// Return true if the call should not be treated as a call to a builtin.
- bool isNoBuiltin() const {
- CALLSITE_DELEGATE_GETTER(isNoBuiltin());
- }
-
- /// Return true if the call requires strict floating point semantics.
- bool isStrictFP() const {
- CALLSITE_DELEGATE_GETTER(isStrictFP());
- }
-
- /// Return true if the call should not be inlined.
- bool isNoInline() const {
- CALLSITE_DELEGATE_GETTER(isNoInline());
- }
- void setIsNoInline(bool Value = true) {
- CALLSITE_DELEGATE_SETTER(setIsNoInline(Value));
- }
-
- /// Determine if the call does not access memory.
- bool doesNotAccessMemory() const {
- CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
- }
- void setDoesNotAccessMemory() {
- CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory());
- }
-
- /// Determine if the call does not access or only reads memory.
- bool onlyReadsMemory() const {
- CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
- }
- void setOnlyReadsMemory() {
- CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory());
- }
-
- /// Determine if the call does not access or only writes memory.
- bool doesNotReadMemory() const {
- CALLSITE_DELEGATE_GETTER(doesNotReadMemory());
- }
- void setDoesNotReadMemory() {
- CALLSITE_DELEGATE_SETTER(setDoesNotReadMemory());
- }
-
- /// Determine if the call can access memmory only using pointers based
- /// on its arguments.
- bool onlyAccessesArgMemory() const {
- CALLSITE_DELEGATE_GETTER(onlyAccessesArgMemory());
- }
- void setOnlyAccessesArgMemory() {
- CALLSITE_DELEGATE_SETTER(setOnlyAccessesArgMemory());
- }
-
- /// Determine if the function may only access memory that is
- /// inaccessible from the IR.
- bool onlyAccessesInaccessibleMemory() const {
- CALLSITE_DELEGATE_GETTER(onlyAccessesInaccessibleMemory());
- }
- void setOnlyAccessesInaccessibleMemory() {
- CALLSITE_DELEGATE_SETTER(setOnlyAccessesInaccessibleMemory());
- }
-
- /// Determine if the function may only access memory that is
- /// either inaccessible from the IR or pointed to by its arguments.
- bool onlyAccessesInaccessibleMemOrArgMem() const {
- CALLSITE_DELEGATE_GETTER(onlyAccessesInaccessibleMemOrArgMem());
- }
- void setOnlyAccessesInaccessibleMemOrArgMem() {
- CALLSITE_DELEGATE_SETTER(setOnlyAccessesInaccessibleMemOrArgMem());
- }
-
- /// Determine if the call cannot return.
- bool doesNotReturn() const {
- CALLSITE_DELEGATE_GETTER(doesNotReturn());
- }
- void setDoesNotReturn() {
- CALLSITE_DELEGATE_SETTER(setDoesNotReturn());
- }
-
- /// Determine if the call cannot unwind.
- bool doesNotThrow() const {
- CALLSITE_DELEGATE_GETTER(doesNotThrow());
- }
- void setDoesNotThrow() {
- CALLSITE_DELEGATE_SETTER(setDoesNotThrow());
- }
-
- /// Determine if the call can be duplicated.
- bool cannotDuplicate() const {
- CALLSITE_DELEGATE_GETTER(cannotDuplicate());
- }
- void setCannotDuplicate() {
- CALLSITE_DELEGATE_SETTER(setCannotDuplicate());
- }
-
- /// Determine if the call is convergent.
- bool isConvergent() const {
- CALLSITE_DELEGATE_GETTER(isConvergent());
- }
- void setConvergent() {
- CALLSITE_DELEGATE_SETTER(setConvergent());
- }
- void setNotConvergent() {
- CALLSITE_DELEGATE_SETTER(setNotConvergent());
- }
-
- unsigned getNumOperandBundles() const {
- CALLSITE_DELEGATE_GETTER(getNumOperandBundles());
- }
-
- bool hasOperandBundles() const {
- CALLSITE_DELEGATE_GETTER(hasOperandBundles());
- }
-
- unsigned getBundleOperandsStartIndex() const {
- CALLSITE_DELEGATE_GETTER(getBundleOperandsStartIndex());
- }
-
- unsigned getBundleOperandsEndIndex() const {
- CALLSITE_DELEGATE_GETTER(getBundleOperandsEndIndex());
- }
-
- unsigned getNumTotalBundleOperands() const {
- CALLSITE_DELEGATE_GETTER(getNumTotalBundleOperands());
- }
-
- OperandBundleUse getOperandBundleAt(unsigned Index) const {
- CALLSITE_DELEGATE_GETTER(getOperandBundleAt(Index));
- }
-
- Optional<OperandBundleUse> getOperandBundle(StringRef Name) const {
- CALLSITE_DELEGATE_GETTER(getOperandBundle(Name));
- }
-
- Optional<OperandBundleUse> getOperandBundle(uint32_t ID) const {
- CALLSITE_DELEGATE_GETTER(getOperandBundle(ID));
- }
-
- unsigned countOperandBundlesOfType(uint32_t ID) const {
- CALLSITE_DELEGATE_GETTER(countOperandBundlesOfType(ID));
- }
-
- bool isBundleOperand(unsigned Idx) const {
- CALLSITE_DELEGATE_GETTER(isBundleOperand(Idx));
- }
-
- IterTy arg_begin() const {
- CALLSITE_DELEGATE_GETTER(arg_begin());
- }
-
- IterTy arg_end() const {
- CALLSITE_DELEGATE_GETTER(arg_end());
- }
-
-#undef CALLSITE_DELEGATE_GETTER
-#undef CALLSITE_DELEGATE_SETTER
-
- void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const {
- // Since this is actually a getter that "looks like" a setter, don't use the
- // above macros to avoid confusion.
- cast<CallBase>(getInstruction())->getOperandBundlesAsDefs(Defs);
- }
-
- /// Determine whether this data operand is not captured.
- bool doesNotCapture(unsigned OpNo) const {
- return dataOperandHasImpliedAttr(OpNo + 1, Attribute::NoCapture);
- }
-
- /// Determine whether this argument is passed by value.
- bool isByValArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo, Attribute::ByVal);
- }
-
- /// Determine whether this argument is passed in an alloca.
- bool isInAllocaArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo, Attribute::InAlloca);
- }
-
- /// Determine whether this argument is passed by value or in an alloca.
- bool isByValOrInAllocaArgument(unsigned ArgNo) const {
- return paramHasAttr(ArgNo, Attribute::ByVal) ||
- paramHasAttr(ArgNo, Attribute::InAlloca);
- }
-
- /// Determine if there are is an inalloca argument. Only the last argument can
- /// have the inalloca attribute.
- bool hasInAllocaArgument() const {
- return !arg_empty() && paramHasAttr(arg_size() - 1, Attribute::InAlloca);
- }
-
- bool doesNotAccessMemory(unsigned OpNo) const {
- return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
- }
-
- bool onlyReadsMemory(unsigned OpNo) const {
- return dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadOnly) ||
- dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
- }
-
- bool doesNotReadMemory(unsigned OpNo) const {
- return dataOperandHasImpliedAttr(OpNo + 1, Attribute::WriteOnly) ||
- dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
- }
-
- /// Return true if the return value is known to be not null.
- /// This may be because it has the nonnull attribute, or because at least
- /// one byte is dereferenceable and the pointer is in addrspace(0).
- bool isReturnNonNull() const {
- if (hasRetAttr(Attribute::NonNull))
- return true;
- else if (getDereferenceableBytes(AttributeList::ReturnIndex) > 0 &&
- !NullPointerIsDefined(getCaller(),
- getType()->getPointerAddressSpace()))
- return true;
-
- return false;
- }
-
- /// Returns true if this CallSite passes the given Value* as an argument to
- /// the called function.
- bool hasArgument(const Value *Arg) const {
- for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
- ++AI)
- if (AI->get() == Arg)
- return true;
- return false;
- }
-
-private:
- IterTy getCallee() const {
- return cast<CallBase>(getInstruction())->op_end() - 1;
- }
-};
-
-class CallSite : public CallSiteBase<Function, BasicBlock, Value, User, Use,
- Instruction, CallInst, InvokeInst,
- CallBrInst, User::op_iterator> {
-public:
- CallSite() = default;
- CallSite(CallSiteBase B) : CallSiteBase(B) {}
- CallSite(CallInst *CI) : CallSiteBase(CI) {}
- CallSite(InvokeInst *II) : CallSiteBase(II) {}
- CallSite(CallBrInst *CBI) : CallSiteBase(CBI) {}
- explicit CallSite(Instruction *II) : CallSiteBase(II) {}
- explicit CallSite(Value *V) : CallSiteBase(V) {}
-
- bool operator==(const CallSite &CS) const { return I == CS.I; }
- bool operator!=(const CallSite &CS) const { return I != CS.I; }
- bool operator<(const CallSite &CS) const {
- return getInstruction() < CS.getInstruction();
- }
-
-private:
- friend struct DenseMapInfo<CallSite>;
-
- User::op_iterator getCallee() const;
-};
-
-/// Establish a view to a call site for examination.
-class ImmutableCallSite : public CallSiteBase<> {
-public:
- ImmutableCallSite() = default;
- ImmutableCallSite(const CallInst *CI) : CallSiteBase(CI) {}
- ImmutableCallSite(const InvokeInst *II) : CallSiteBase(II) {}
- ImmutableCallSite(const CallBrInst *CBI) : CallSiteBase(CBI) {}
- explicit ImmutableCallSite(const Instruction *II) : CallSiteBase(II) {}
- explicit ImmutableCallSite(const Value *V) : CallSiteBase(V) {}
- ImmutableCallSite(CallSite CS) : CallSiteBase(CS.getInstruction()) {}
-};
-
-/// AbstractCallSite
-///
-/// An abstract call site is a wrapper that allows to treat direct,
-/// indirect, and callback calls the same. If an abstract call site
-/// represents a direct or indirect call site it behaves like a stripped
-/// down version of a normal call site object. The abstract call site can
-/// also represent a callback call, thus the fact that the initially
-/// called function (=broker) may invoke a third one (=callback callee).
-/// In this case, the abstract call site hides the middle man, hence the
-/// broker function. The result is a representation of the callback call,
-/// inside the broker, but in the context of the original call to the broker.
-///
-/// There are up to three functions involved when we talk about callback call
-/// sites. The caller (1), which invokes the broker function. The broker
-/// function (2), that will invoke the callee zero or more times. And finally
-/// the callee (3), which is the target of the callback call.
-///
-/// The abstract call site will handle the mapping from parameters to arguments
-/// depending on the semantic of the broker function. However, it is important
-/// to note that the mapping is often partial. Thus, some arguments of the
-/// call/invoke instruction are mapped to parameters of the callee while others
-/// are not.
-class AbstractCallSite {
-public:
-
- /// The encoding of a callback with regards to the underlying instruction.
- struct CallbackInfo {
-
- /// For direct/indirect calls the parameter encoding is empty. If it is not,
- /// the abstract call site represents a callback. In that case, the first
- /// element of the encoding vector represents which argument of the call
- /// site CS is the callback callee. The remaining elements map parameters
- /// (identified by their position) to the arguments that will be passed
- /// through (also identified by position but in the call site instruction).
- ///
- /// NOTE that we use LLVM argument numbers (starting at 0) and not
- /// clang/source argument numbers (starting at 1). The -1 entries represent
- /// unknown values that are passed to the callee.
- using ParameterEncodingTy = SmallVector<int, 0>;
- ParameterEncodingTy ParameterEncoding;
-
- };
-
-private:
-
- /// The underlying call site:
- /// caller -> callee, if this is a direct or indirect call site
- /// caller -> broker function, if this is a callback call site
- CallSite CS;
-
- /// The encoding of a callback with regards to the underlying instruction.
- CallbackInfo CI;
-
-public:
- /// Sole constructor for abstract call sites (ACS).
- ///
- /// An abstract call site can only be constructed through a llvm::Use because
- /// each operand (=use) of an instruction could potentially be a different
- /// abstract call site. Furthermore, even if the value of the llvm::Use is the
- /// same, and the user is as well, the abstract call sites might not be.
- ///
- /// If a use is not associated with an abstract call site the constructed ACS
- /// will evaluate to false if converted to a boolean.
- ///
- /// If the use is the callee use of a call or invoke instruction, the
- /// constructed abstract call site will behave as a llvm::CallSite would.
- ///
- /// If the use is not a callee use of a call or invoke instruction, the
- /// callback metadata is used to determine the argument <-> parameter mapping
- /// as well as the callee of the abstract call site.
- AbstractCallSite(const Use *U);
-
- /// Add operand uses of \p ICS that represent callback uses into \p CBUses.
- ///
- /// All uses added to \p CBUses can be used to create abstract call sites for
- /// which AbstractCallSite::isCallbackCall() will return true.
- static void getCallbackUses(ImmutableCallSite ICS,
- SmallVectorImpl<const Use *> &CBUses);
-
- /// Conversion operator to conveniently check for a valid/initialized ACS.
- explicit operator bool() const { return (bool)CS; }
-
- /// Return the underlying instruction.
- Instruction *getInstruction() const { return CS.getInstruction(); }
-
- /// Return the call site abstraction for the underlying instruction.
- CallSite getCallSite() const { return CS; }
-
- /// Return true if this ACS represents a direct call.
- bool isDirectCall() const {
- return !isCallbackCall() && !CS.isIndirectCall();
- }
-
- /// Return true if this ACS represents an indirect call.
- bool isIndirectCall() const {
- return !isCallbackCall() && CS.isIndirectCall();
- }
-
- /// Return true if this ACS represents a callback call.
- bool isCallbackCall() const {
- // For a callback call site the callee is ALWAYS stored first in the
- // transitive values vector. Thus, a non-empty vector indicates a callback.
- return !CI.ParameterEncoding.empty();
- }
-
- /// Return true if @p UI is the use that defines the callee of this ACS.
- bool isCallee(Value::const_user_iterator UI) const {
- return isCallee(&UI.getUse());
- }
-
- /// Return true if @p U is the use that defines the callee of this ACS.
- bool isCallee(const Use *U) const {
- if (isDirectCall())
- return CS.isCallee(U);
-
- assert(!CI.ParameterEncoding.empty() &&
- "Callback without parameter encoding!");
-
- return (int)CS.getArgumentNo(U) == CI.ParameterEncoding[0];
- }
-
- /// Return the number of parameters of the callee.
- unsigned getNumArgOperands() const {
- if (isDirectCall())
- return CS.getNumArgOperands();
- // Subtract 1 for the callee encoding.
- return CI.ParameterEncoding.size() - 1;
- }
-
- /// Return the operand index of the underlying instruction associated with @p
- /// Arg.
- int getCallArgOperandNo(Argument &Arg) const {
- return getCallArgOperandNo(Arg.getArgNo());
- }
-
- /// Return the operand index of the underlying instruction associated with
- /// the function parameter number @p ArgNo or -1 if there is none.
- int getCallArgOperandNo(unsigned ArgNo) const {
- if (isDirectCall())
- return ArgNo;
- // Add 1 for the callee encoding.
- return CI.ParameterEncoding[ArgNo + 1];
- }
-
- /// Return the operand of the underlying instruction associated with @p Arg.
- Value *getCallArgOperand(Argument &Arg) const {
- return getCallArgOperand(Arg.getArgNo());
- }
-
- /// Return the operand of the underlying instruction associated with the
- /// function parameter number @p ArgNo or nullptr if there is none.
- Value *getCallArgOperand(unsigned ArgNo) const {
- if (isDirectCall())
- return CS.getArgOperand(ArgNo);
- // Add 1 for the callee encoding.
- return CI.ParameterEncoding[ArgNo + 1] >= 0
- ? CS.getArgOperand(CI.ParameterEncoding[ArgNo + 1])
- : nullptr;
- }
-
- /// Return the operand index of the underlying instruction associated with the
- /// callee of this ACS. Only valid for callback calls!
- int getCallArgOperandNoForCallee() const {
- assert(isCallbackCall());
- assert(CI.ParameterEncoding.size() && CI.ParameterEncoding[0] >= 0);
- return CI.ParameterEncoding[0];
- }
-
- /// Return the use of the callee value in the underlying instruction. Only
- /// valid for callback calls!
- const Use &getCalleeUseForCallback() const {
- int CalleeArgIdx = getCallArgOperandNoForCallee();
- assert(CalleeArgIdx >= 0 &&
- unsigned(CalleeArgIdx) < getInstruction()->getNumOperands());
- return getInstruction()->getOperandUse(CalleeArgIdx);
- }
-
- /// Return the pointer to function that is being called.
- Value *getCalledValue() const {
- if (isDirectCall())
- return CS.getCalledValue();
- return CS.getArgOperand(getCallArgOperandNoForCallee());
- }
-
- /// Return the function being called if this is a direct call, otherwise
- /// return null (if it's an indirect call).
- Function *getCalledFunction() const {
- Value *V = getCalledValue();
- return V ? dyn_cast<Function>(V->stripPointerCasts()) : nullptr;
- }
-};
-
-template <> struct DenseMapInfo<CallSite> {
- using BaseInfo = DenseMapInfo<decltype(CallSite::I)>;
-
- static CallSite getEmptyKey() {
- CallSite CS;
- CS.I = BaseInfo::getEmptyKey();
- return CS;
- }
-
- static CallSite getTombstoneKey() {
- CallSite CS;
- CS.I = BaseInfo::getTombstoneKey();
- return CS;
- }
-
- static unsigned getHashValue(const CallSite &CS) {
- return BaseInfo::getHashValue(CS.I);
- }
-
- static bool isEqual(const CallSite &LHS, const CallSite &RHS) {
- return LHS == RHS;
- }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_IR_CALLSITE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Constant.h b/contrib/llvm-project/llvm/include/llvm/IR/Constant.h
index 174e7364c524..9a1d2b80c48e 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Constant.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Constant.h
@@ -43,6 +43,8 @@ protected:
Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps)
: User(ty, vty, Ops, NumOps) {}
+ ~Constant() = default;
+
public:
void operator=(const Constant &) = delete;
Constant(const Constant &) = delete;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ConstantFolder.h b/contrib/llvm-project/llvm/include/llvm/IR/ConstantFolder.h
index 5a5cabfd0206..da4a18e3c181 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ConstantFolder.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ConstantFolder.h
@@ -20,11 +20,14 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
/// ConstantFolder - Create constants with minimum, target independent, folding.
-class ConstantFolder {
+class ConstantFolder final : public IRBuilderFolder {
+ virtual void anchor();
+
public:
explicit ConstantFolder() = default;
@@ -33,87 +36,87 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getAdd(LHS, RHS, HasNUW, HasNSW);
}
- Constant *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFAdd(LHS, RHS);
}
Constant *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getSub(LHS, RHS, HasNUW, HasNSW);
}
- Constant *CreateFSub(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFSub(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFSub(LHS, RHS);
}
Constant *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getMul(LHS, RHS, HasNUW, HasNSW);
}
- Constant *CreateFMul(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFMul(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFMul(LHS, RHS);
}
Constant *CreateUDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
return ConstantExpr::getUDiv(LHS, RHS, isExact);
}
Constant *CreateSDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
return ConstantExpr::getSDiv(LHS, RHS, isExact);
}
- Constant *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFDiv(LHS, RHS);
}
- Constant *CreateURem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateURem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getURem(LHS, RHS);
}
- Constant *CreateSRem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateSRem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getSRem(LHS, RHS);
}
- Constant *CreateFRem(Constant *LHS, Constant *RHS) const {
+ Constant *CreateFRem(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getFRem(LHS, RHS);
}
Constant *CreateShl(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getShl(LHS, RHS, HasNUW, HasNSW);
}
Constant *CreateLShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
return ConstantExpr::getLShr(LHS, RHS, isExact);
}
Constant *CreateAShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
return ConstantExpr::getAShr(LHS, RHS, isExact);
}
- Constant *CreateAnd(Constant *LHS, Constant *RHS) const {
+ Constant *CreateAnd(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getAnd(LHS, RHS);
}
- Constant *CreateOr(Constant *LHS, Constant *RHS) const {
+ Constant *CreateOr(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getOr(LHS, RHS);
}
- Constant *CreateXor(Constant *LHS, Constant *RHS) const {
+ Constant *CreateXor(Constant *LHS, Constant *RHS) const override {
return ConstantExpr::getXor(LHS, RHS);
}
Constant *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
+ Constant *LHS, Constant *RHS) const override {
return ConstantExpr::get(Opc, LHS, RHS);
}
@@ -122,19 +125,19 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false, bool HasNSW = false) const override {
return ConstantExpr::getNeg(C, HasNUW, HasNSW);
}
- Constant *CreateFNeg(Constant *C) const {
+ Constant *CreateFNeg(Constant *C) const override {
return ConstantExpr::getFNeg(C);
}
- Constant *CreateNot(Constant *C) const {
+ Constant *CreateNot(Constant *C) const override {
return ConstantExpr::getNot(C);
}
- Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
+ Constant *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const override {
return ConstantExpr::get(Opc, C);
}
@@ -143,11 +146,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
@@ -155,25 +159,25 @@ public:
}
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ ArrayRef<Value *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ Constant *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const {
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ Constant *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
@@ -182,49 +186,49 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
+ Type *DestTy) const override {
return ConstantExpr::getCast(Op, C, DestTy);
}
- Constant *CreatePointerCast(Constant *C, Type *DestTy) const {
+ Constant *CreatePointerCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getPointerCast(C, DestTy);
}
Constant *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
- Type *DestTy) const {
+ Type *DestTy) const override {
return ConstantExpr::getPointerBitCastOrAddrSpaceCast(C, DestTy);
}
Constant *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
+ bool isSigned) const override {
return ConstantExpr::getIntegerCast(C, DestTy, isSigned);
}
- Constant *CreateFPCast(Constant *C, Type *DestTy) const {
+ Constant *CreateFPCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getFPCast(C, DestTy);
}
- Constant *CreateBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
- Constant *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ Constant *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
- Constant *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ Constant *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
- Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getZExtOrBitCast(C, DestTy);
}
- Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getSExtOrBitCast(C, DestTy);
}
- Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ Constant *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
return ConstantExpr::getTruncOrBitCast(C, DestTy);
}
@@ -233,12 +237,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateICmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
+ Constant *RHS) const override {
return ConstantExpr::getCompare(P, LHS, RHS);
}
Constant *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
- Constant *RHS) const {
+ Constant *RHS) const override {
return ConstantExpr::getCompare(P, LHS, RHS);
}
@@ -246,31 +250,32 @@ public:
// Other Instructions
//===--------------------------------------------------------------------===//
- Constant *CreateSelect(Constant *C, Constant *True, Constant *False) const {
+ Constant *CreateSelect(Constant *C, Constant *True,
+ Constant *False) const override {
return ConstantExpr::getSelect(C, True, False);
}
- Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ Constant *CreateExtractElement(Constant *Vec, Constant *Idx) const override {
return ConstantExpr::getExtractElement(Vec, Idx);
}
Constant *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
+ Constant *Idx) const override {
return ConstantExpr::getInsertElement(Vec, NewElt, Idx);
}
Constant *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
+ ArrayRef<int> Mask) const override {
return ConstantExpr::getShuffleVector(V1, V2, Mask);
}
Constant *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return ConstantExpr::getExtractValue(Agg, IdxList);
}
Constant *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return ConstantExpr::getInsertValue(Agg, Val, IdxList);
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ConstantRange.h b/contrib/llvm-project/llvm/include/llvm/IR/ConstantRange.h
index e6bac8a5f933..8ecb9aa0ce02 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ConstantRange.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ConstantRange.h
@@ -410,6 +410,10 @@ public:
ConstantRange binaryOr(const ConstantRange &Other) const;
/// Return a new range representing the possible values resulting
+ /// from a binary-xor of a value in this range by a value in \p Other.
+ ConstantRange binaryXor(const ConstantRange &Other) const;
+
+ /// Return a new range representing the possible values resulting
/// from a left shift of a value in this range by a value in \p Other.
/// TODO: This isn't fully implemented yet.
ConstantRange shl(const ConstantRange &Other) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Constants.h b/contrib/llvm-project/llvm/include/llvm/IR/Constants.h
index 262ab439df65..8e2dba9b2417 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Constants.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Constants.h
@@ -41,12 +41,6 @@
namespace llvm {
-class ArrayType;
-class IntegerType;
-class PointerType;
-class SequentialType;
-class StructType;
-class VectorType;
template <class ConstantClass> struct ConstantAggrKeyType;
/// Base class for constants with no operands.
@@ -157,6 +151,20 @@ public:
return Val.getSExtValue();
}
+ /// Return the constant as an llvm::MaybeAlign.
+ /// Note that this method can assert if the value does not fit in 64 bits or
+ /// is not a power of two.
+ inline MaybeAlign getMaybeAlignValue() const {
+ return MaybeAlign(getZExtValue());
+ }
+
+ /// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
+ /// Note that this method can assert if the value does not fit in 64 bits or
+ /// is not a power of two.
+ inline Align getAlignValue() const {
+ return getMaybeAlignValue().valueOrOne();
+ }
+
/// A helper method that can be used to determine if the constant contained
/// within is equal to a constant. This only works for very small values,
/// because this is all that can be represented with all types.
@@ -300,6 +308,7 @@ public:
/// Return true if Ty is big enough to represent V.
static bool isValueValidForType(Type *Ty, const APFloat &V);
inline const APFloat &getValueAPF() const { return Val; }
+ inline const APFloat &getValue() const { return Val; }
/// Return true if the value is positive or negative zero.
bool isZero() const { return Val.isZero(); }
@@ -388,7 +397,7 @@ public:
/// use operands.
class ConstantAggregate : public Constant {
protected:
- ConstantAggregate(CompositeType *T, ValueTy VT, ArrayRef<Constant *> V);
+ ConstantAggregate(Type *T, ValueTy VT, ArrayRef<Constant *> V);
public:
/// Transparently provide more efficient getOperand methods.
@@ -456,8 +465,7 @@ public:
static Constant *get(StructType *T, ArrayRef<Constant*> V);
template <typename... Csts>
- static typename std::enable_if<are_base_of<Constant, Csts...>::value,
- Constant *>::type
+ static std::enable_if_t<are_base_of<Constant, Csts...>::value, Constant *>
get(StructType *T, Csts *... Vs) {
SmallVector<Constant *, 8> Values({Vs...});
return get(T, Values);
@@ -514,12 +522,13 @@ private:
public:
/// Return a ConstantVector with the specified constant in each element.
- static Constant *getSplat(unsigned NumElts, Constant *Elt);
+ /// Note that this might not return an instance of ConstantVector
+ static Constant *getSplat(ElementCount EC, Constant *Elt);
- /// Specialize the getType() method to always return a VectorType,
+ /// Specialize the getType() method to always return a FixedVectorType,
/// which reduces the amount of casting needed in parts of the compiler.
- inline VectorType *getType() const {
- return cast<VectorType>(Value::getType());
+ inline FixedVectorType *getType() const {
+ return cast<FixedVectorType>(Value::getType());
}
/// If all elements of the vector constant have the same value, return that
@@ -628,12 +637,6 @@ public:
/// efficient as getElementAsInteger/Float/Double.
Constant *getElementAsConstant(unsigned i) const;
- /// Specialize the getType() method to always return a SequentialType, which
- /// reduces the amount of casting needed in parts of the compiler.
- inline SequentialType *getType() const {
- return cast<SequentialType>(Value::getType());
- }
-
/// Return the element type of the array/vector.
Type *getElementType() const;
@@ -724,14 +727,15 @@ public:
return getImpl(Data, Ty);
}
- /// getFP() constructors - Return a constant with array type with an element
- /// count and element type of float with precision matching the number of
- /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
- /// double for 64bits) Note that this can return a ConstantAggregateZero
- /// object.
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+ /// getFP() constructors - Return a constant of array type with a float
+ /// element type taken from argument `ElementType', and count taken from
+ /// argument `Elts'. The amount of bits of the contained type must match the
+ /// number of bits of the type contained in the passed in ArrayRef.
+ /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
+ /// that this can return a ConstantAggregateZero object.
+ static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts);
/// This method constructs a CDS and initializes it with a text string.
/// The default behavior (AddNull==true) causes a null terminator to
@@ -763,7 +767,12 @@ class ConstantDataVector final : public ConstantDataSequential {
friend class ConstantDataSequential;
explicit ConstantDataVector(Type *ty, const char *Data)
- : ConstantDataSequential(ty, ConstantDataVectorVal, Data) {}
+ : ConstantDataSequential(ty, ConstantDataVectorVal, Data),
+ IsSplatSet(false) {}
+ // Cache whether or not the constant is a splat.
+ mutable bool IsSplatSet : 1;
+ mutable bool IsSplat : 1;
+ bool isSplatData() const;
public:
ConstantDataVector(const ConstantDataVector &) = delete;
@@ -778,14 +787,15 @@ public:
static Constant *get(LLVMContext &Context, ArrayRef<float> Elts);
static Constant *get(LLVMContext &Context, ArrayRef<double> Elts);
- /// getFP() constructors - Return a constant with vector type with an element
- /// count and element type of float with the precision matching the number of
- /// bits in the ArrayRef passed in. (i.e. half for 16bits, float for 32bits,
- /// double for 64bits) Note that this can return a ConstantAggregateZero
- /// object.
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint16_t> Elts);
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint32_t> Elts);
- static Constant *getFP(LLVMContext &Context, ArrayRef<uint64_t> Elts);
+ /// getFP() constructors - Return a constant of vector type with a float
+ /// element type taken from argument `ElementType', and count taken from
+ /// argument `Elts'. The amount of bits of the contained type must match the
+ /// number of bits of the type contained in the passed in ArrayRef.
+ /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
+ /// that this can return a ConstantAggregateZero object.
+ static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts);
+ static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts);
+ static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts);
/// Return a ConstantVector with the specified constant in each element.
/// The specified constant has to be a of a compatible type (i8/i16/
@@ -800,10 +810,10 @@ public:
/// same value, return that value. Otherwise return NULL.
Constant *getSplatValue() const;
- /// Specialize the getType() method to always return a VectorType,
+ /// Specialize the getType() method to always return a FixedVectorType,
/// which reduces the amount of casting needed in parts of the compiler.
- inline VectorType *getType() const {
- return cast<VectorType>(Value::getType());
+ inline FixedVectorType *getType() const {
+ return cast<FixedVectorType>(Value::getType());
}
/// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -900,6 +910,8 @@ protected:
setValueSubclassData(Opcode);
}
+ ~ConstantExpr() = default;
+
public:
// Static methods to construct a ConstantExpr of different kinds. Note that
// these methods may return a object that is not an instance of the
@@ -1198,7 +1210,8 @@ public:
Type *OnlyIfReducedTy = nullptr);
static Constant *getInsertElement(Constant *Vec, Constant *Elt, Constant *Idx,
Type *OnlyIfReducedTy = nullptr);
- static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask,
+ static Constant *getShuffleVector(Constant *V1, Constant *V2,
+ ArrayRef<int> Mask,
Type *OnlyIfReducedTy = nullptr);
static Constant *getExtractValue(Constant *Agg, ArrayRef<unsigned> Idxs,
Type *OnlyIfReducedTy = nullptr);
@@ -1217,6 +1230,16 @@ public:
/// expression and return the list of indices.
ArrayRef<unsigned> getIndices() const;
+ /// Assert that this is a shufflevector and return the mask. See class
+ /// ShuffleVectorInst for a description of the mask representation.
+ ArrayRef<int> getShuffleMask() const;
+
+ /// Assert that this is a shufflevector and return the mask.
+ ///
+ /// TODO: This is a temporary hack until we update the bitcode format for
+ /// shufflevector.
+ Constant *getShuffleMaskForBitcode() const;
+
/// Return a string representation for an opcode.
const char *getOpcodeName() const;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ConstrainedOps.def b/contrib/llvm-project/llvm/include/llvm/IR/ConstrainedOps.def
index 7e24684ca654..ecba68fe0c0e 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ConstrainedOps.def
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ConstrainedOps.def
@@ -11,18 +11,32 @@
//
//===----------------------------------------------------------------------===//
+// DAG_FUNCTION defers to DAG_INSTRUCTION if its defined, otherwise FUNCTION.
+#ifndef DAG_FUNCTION
+#ifdef DAG_INSTRUCTION
+#define DAG_FUNCTION(N,A,R,I,D) DAG_INSTRUCTION(N,A,R,I,D)
+#else
+#define DAG_FUNCTION(N,A,R,I,D) FUNCTION(N,A,R,I)
+#endif
+#endif
+
#ifndef INSTRUCTION
-#define INSTRUCTION(N,A,R,I,D)
+#define INSTRUCTION(N,A,R,I)
+#endif
+
+// DAG_INSTRUCTION is treated like an INSTRUCTION if the DAG node isn't used.
+#ifndef DAG_INSTRUCTION
+#define DAG_INSTRUCTION(N,A,R,I,D) INSTRUCTION(N,A,R,I)
#endif
// In most cases intrinsic function is handled similar to instruction.
#ifndef FUNCTION
-#define FUNCTION INSTRUCTION
+#define FUNCTION(N,A,R,I) INSTRUCTION(N,A,R,I)
#endif
-// Likewise for compare instructions.
+// Compare instruction have a DAG node so they are treated like DAG_INSTRUCTION.
#ifndef CMP_INSTRUCTION
-#define CMP_INSTRUCTION INSTRUCTION
+#define CMP_INSTRUCTION(N,A,R,I,D) DAG_INSTRUCTION(N,A,R,I,D)
#endif
// Arguments of the entries are:
@@ -35,52 +49,59 @@
// These are definitions for instructions, that are converted into constrained
// intrinsics.
//
-INSTRUCTION(FAdd, 2, 1, experimental_constrained_fadd, FADD)
-INSTRUCTION(FSub, 2, 1, experimental_constrained_fsub, FSUB)
-INSTRUCTION(FMul, 2, 1, experimental_constrained_fmul, FMUL)
-INSTRUCTION(FDiv, 2, 1, experimental_constrained_fdiv, FDIV)
-INSTRUCTION(FRem, 2, 1, experimental_constrained_frem, FREM)
-INSTRUCTION(FPExt, 1, 0, experimental_constrained_fpext, FP_EXTEND)
-INSTRUCTION(SIToFP, 1, 1, experimental_constrained_sitofp, SINT_TO_FP)
-INSTRUCTION(UIToFP, 1, 1, experimental_constrained_uitofp, UINT_TO_FP)
-INSTRUCTION(FPToSI, 1, 0, experimental_constrained_fptosi, FP_TO_SINT)
-INSTRUCTION(FPToUI, 1, 0, experimental_constrained_fptoui, FP_TO_UINT)
-INSTRUCTION(FPTrunc, 1, 1, experimental_constrained_fptrunc, FP_ROUND)
+DAG_INSTRUCTION(FAdd, 2, 1, experimental_constrained_fadd, FADD)
+DAG_INSTRUCTION(FSub, 2, 1, experimental_constrained_fsub, FSUB)
+DAG_INSTRUCTION(FMul, 2, 1, experimental_constrained_fmul, FMUL)
+DAG_INSTRUCTION(FDiv, 2, 1, experimental_constrained_fdiv, FDIV)
+DAG_INSTRUCTION(FRem, 2, 1, experimental_constrained_frem, FREM)
+DAG_INSTRUCTION(FPExt, 1, 0, experimental_constrained_fpext, FP_EXTEND)
+DAG_INSTRUCTION(SIToFP, 1, 1, experimental_constrained_sitofp, SINT_TO_FP)
+DAG_INSTRUCTION(UIToFP, 1, 1, experimental_constrained_uitofp, UINT_TO_FP)
+DAG_INSTRUCTION(FPToSI, 1, 0, experimental_constrained_fptosi, FP_TO_SINT)
+DAG_INSTRUCTION(FPToUI, 1, 0, experimental_constrained_fptoui, FP_TO_UINT)
+DAG_INSTRUCTION(FPTrunc, 1, 1, experimental_constrained_fptrunc, FP_ROUND)
// These are definitions for compare instructions (signaling and quiet version).
// Both of these match to FCmp / SETCC.
-CMP_INSTRUCTION(FCmp, 2, 0, experimental_constrained_fcmp, FSETCC)
-CMP_INSTRUCTION(FCmp, 2, 0, experimental_constrained_fcmps, FSETCCS)
+CMP_INSTRUCTION(FCmp, 2, 0, experimental_constrained_fcmp, FSETCC)
+CMP_INSTRUCTION(FCmp, 2, 0, experimental_constrained_fcmps, FSETCCS)
// Theses are definitions for intrinsic functions, that are converted into
// constrained intrinsics.
//
-FUNCTION(ceil, 1, 0, experimental_constrained_ceil, FCEIL)
-FUNCTION(cos, 1, 1, experimental_constrained_cos, FCOS)
-FUNCTION(exp, 1, 1, experimental_constrained_exp, FEXP)
-FUNCTION(exp2, 1, 1, experimental_constrained_exp2, FEXP2)
-FUNCTION(floor, 1, 0, experimental_constrained_floor, FFLOOR)
-FUNCTION(fma, 3, 1, experimental_constrained_fma, FMA)
-FUNCTION(log, 1, 1, experimental_constrained_log, FLOG)
-FUNCTION(log10, 1, 1, experimental_constrained_log10, FLOG10)
-FUNCTION(log2, 1, 1, experimental_constrained_log2, FLOG2)
-FUNCTION(lrint, 1, 1, experimental_constrained_lrint, LRINT)
-FUNCTION(llrint, 1, 1, experimental_constrained_llrint, LLRINT)
-FUNCTION(lround, 1, 0, experimental_constrained_lround, LROUND)
-FUNCTION(llround, 1, 0, experimental_constrained_llround, LLROUND)
-FUNCTION(maxnum, 2, 0, experimental_constrained_maxnum, FMAXNUM)
-FUNCTION(minnum, 2, 0, experimental_constrained_minnum, FMINNUM)
-FUNCTION(maximum, 2, 0, experimental_constrained_maximum, FMAXIMUM)
-FUNCTION(minimum, 2, 0, experimental_constrained_minimum, FMINIMUM)
-FUNCTION(nearbyint, 1, 1, experimental_constrained_nearbyint, FNEARBYINT)
-FUNCTION(pow, 2, 1, experimental_constrained_pow, FPOW)
-FUNCTION(powi, 2, 1, experimental_constrained_powi, FPOWI)
-FUNCTION(rint, 1, 1, experimental_constrained_rint, FRINT)
-FUNCTION(round, 1, 0, experimental_constrained_round, FROUND)
-FUNCTION(sin, 1, 1, experimental_constrained_sin, FSIN)
-FUNCTION(sqrt, 1, 1, experimental_constrained_sqrt, FSQRT)
-FUNCTION(trunc, 1, 0, experimental_constrained_trunc, FTRUNC)
+DAG_FUNCTION(ceil, 1, 0, experimental_constrained_ceil, FCEIL)
+DAG_FUNCTION(cos, 1, 1, experimental_constrained_cos, FCOS)
+DAG_FUNCTION(exp, 1, 1, experimental_constrained_exp, FEXP)
+DAG_FUNCTION(exp2, 1, 1, experimental_constrained_exp2, FEXP2)
+DAG_FUNCTION(floor, 1, 0, experimental_constrained_floor, FFLOOR)
+DAG_FUNCTION(fma, 3, 1, experimental_constrained_fma, FMA)
+DAG_FUNCTION(log, 1, 1, experimental_constrained_log, FLOG)
+DAG_FUNCTION(log10, 1, 1, experimental_constrained_log10, FLOG10)
+DAG_FUNCTION(log2, 1, 1, experimental_constrained_log2, FLOG2)
+DAG_FUNCTION(lrint, 1, 1, experimental_constrained_lrint, LRINT)
+DAG_FUNCTION(llrint, 1, 1, experimental_constrained_llrint, LLRINT)
+DAG_FUNCTION(lround, 1, 0, experimental_constrained_lround, LROUND)
+DAG_FUNCTION(llround, 1, 0, experimental_constrained_llround, LLROUND)
+DAG_FUNCTION(maxnum, 2, 0, experimental_constrained_maxnum, FMAXNUM)
+DAG_FUNCTION(minnum, 2, 0, experimental_constrained_minnum, FMINNUM)
+DAG_FUNCTION(maximum, 2, 0, experimental_constrained_maximum, FMAXIMUM)
+DAG_FUNCTION(minimum, 2, 0, experimental_constrained_minimum, FMINIMUM)
+DAG_FUNCTION(nearbyint, 1, 1, experimental_constrained_nearbyint, FNEARBYINT)
+DAG_FUNCTION(pow, 2, 1, experimental_constrained_pow, FPOW)
+DAG_FUNCTION(powi, 2, 1, experimental_constrained_powi, FPOWI)
+DAG_FUNCTION(rint, 1, 1, experimental_constrained_rint, FRINT)
+DAG_FUNCTION(round, 1, 0, experimental_constrained_round, FROUND)
+DAG_FUNCTION(roundeven, 1, 0, experimental_constrained_roundeven, FROUNDEVEN)
+DAG_FUNCTION(sin, 1, 1, experimental_constrained_sin, FSIN)
+DAG_FUNCTION(sqrt, 1, 1, experimental_constrained_sqrt, FSQRT)
+DAG_FUNCTION(trunc, 1, 0, experimental_constrained_trunc, FTRUNC)
+
+// This is definition for fmuladd intrinsic function, that is converted into
+// constrained FMA or FMUL + FADD intrinsics.
+FUNCTION(fmuladd, 3, 1, experimental_constrained_fmuladd)
#undef INSTRUCTION
#undef FUNCTION
#undef CMP_INSTRUCTION
+#undef DAG_INSTRUCTION
+#undef DAG_FUNCTION
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DIBuilder.h b/contrib/llvm-project/llvm/include/llvm/IR/DIBuilder.h
index f7c242554f6a..d1c7d126b5a9 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DIBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DIBuilder.h
@@ -135,6 +135,9 @@ namespace llvm {
/// profile collection.
/// \param NameTableKind Whether to emit .debug_gnu_pubnames,
/// .debug_pubnames, or no pubnames at all.
+ /// \param SysRoot The clang system root (value of -isysroot).
+ /// \param SDK The SDK name. On Darwin, this is the last component
+ /// of the sysroot.
DICompileUnit *
createCompileUnit(unsigned Lang, DIFile *File, StringRef Producer,
bool isOptimized, StringRef Flags, unsigned RV,
@@ -145,7 +148,8 @@ namespace llvm {
bool DebugInfoForProfiling = false,
DICompileUnit::DebugNameTableKind NameTableKind =
DICompileUnit::DebugNameTableKind::Default,
- bool RangesBaseAddress = false);
+ bool RangesBaseAddress = false, StringRef SysRoot = {},
+ StringRef SDK = {});
/// Create a file descriptor to hold debugging information for a file.
/// \param Filename File name.
@@ -442,19 +446,22 @@ namespace llvm {
/// \param Scope Scope in which this type is defined.
/// \param Name Type parameter name.
/// \param Ty Parameter type.
- DITemplateTypeParameter *
- createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty);
+ /// \param IsDefault Parameter is default or not
+ DITemplateTypeParameter *createTemplateTypeParameter(DIScope *Scope,
+ StringRef Name,
+ DIType *Ty,
+ bool IsDefault);
/// Create debugging information for template
/// value parameter.
/// \param Scope Scope in which this type is defined.
/// \param Name Value parameter name.
/// \param Ty Parameter type.
+ /// \param IsDefault Parameter is default or not
/// \param Val Constant parameter value.
- DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope,
- StringRef Name,
- DIType *Ty,
- Constant *Val);
+ DITemplateValueParameter *
+ createTemplateValueParameter(DIScope *Scope, StringRef Name, DIType *Ty,
+ bool IsDefault, Constant *Val);
/// Create debugging information for a template template parameter.
/// \param Scope Scope in which this type is defined.
@@ -566,6 +573,8 @@ namespace llvm {
/// implicitly uniques the values returned.
DISubrange *getOrCreateSubrange(int64_t Lo, int64_t Count);
DISubrange *getOrCreateSubrange(int64_t Lo, Metadata *CountNode);
+ DISubrange *getOrCreateSubrange(Metadata *Count, Metadata *LowerBound,
+ Metadata *UpperBound, Metadata *Stride);
/// Create a new descriptor for the specified variable.
/// \param Context Variable scope.
@@ -734,11 +743,15 @@ namespace llvm {
/// A space-separated shell-quoted list of -D macro
/// definitions as they would appear on a command line.
/// \param IncludePath The path to the module map file.
- /// \param SysRoot The clang system root (value of -isysroot).
+ /// \param APINotesFile The path to an API notes file for this module.
+ /// \param File Source file of the module declaration. Used for
+ /// Fortran modules.
+ /// \param LineNo Source line number of the module declaration.
+ /// Used for Fortran modules.
DIModule *createModule(DIScope *Scope, StringRef Name,
- StringRef ConfigurationMacros,
- StringRef IncludePath,
- StringRef SysRoot);
+ StringRef ConfigurationMacros, StringRef IncludePath,
+ StringRef APINotesFile = {}, DIFile *File = nullptr,
+ unsigned LineNo = 0);
/// This creates a descriptor for a lexical block with a new file
/// attached. This merely extends the existing
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DataLayout.h b/contrib/llvm-project/llvm/include/llvm/IR/DataLayout.h
index 85093dd218f8..17297bb8b309 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DataLayout.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DataLayout.h
@@ -133,7 +133,8 @@ private:
MM_MachO,
MM_WinCOFF,
MM_WinCOFFX86,
- MM_Mips
+ MM_Mips,
+ MM_XCOFF
};
ManglingModeT ManglingMode;
@@ -262,7 +263,7 @@ public:
/// Returns true if the given alignment exceeds the natural stack alignment.
bool exceedsNaturalStackAlignment(Align Alignment) const {
- return StackNaturalAlign && (Alignment > StackNaturalAlign);
+ return StackNaturalAlign && (Alignment > *StackNaturalAlign);
}
Align getStackAlignment() const {
@@ -309,6 +310,7 @@ public:
case MM_ELF:
case MM_Mips:
case MM_WinCOFF:
+ case MM_XCOFF:
return '\0';
case MM_MachO:
case MM_WinCOFFX86:
@@ -329,6 +331,8 @@ public:
case MM_MachO:
case MM_WinCOFFX86:
return "L";
+ case MM_XCOFF:
+ return "L..";
}
llvm_unreachable("invalid mangling mode");
}
@@ -501,13 +505,17 @@ public:
}
/// Returns the minimum ABI-required alignment for the specified type.
+ /// FIXME: Deprecate this function once migration to Align is over.
unsigned getABITypeAlignment(Type *Ty) const;
+ /// Returns the minimum ABI-required alignment for the specified type.
+ Align getABITypeAlign(Type *Ty) const;
+
/// Helper function to return `Alignment` if it's set or the result of
/// `getABITypeAlignment(Ty)`, in any case the result is a valid alignment.
inline Align getValueOrABITypeAlignment(MaybeAlign Alignment,
Type *Ty) const {
- return Alignment ? *Alignment : Align(getABITypeAlignment(Ty));
+ return Alignment ? *Alignment : getABITypeAlign(Ty);
}
/// Returns the minimum ABI-required alignment for an integer type of
@@ -518,8 +526,15 @@ public:
/// type.
///
/// This is always at least as good as the ABI alignment.
+ /// FIXME: Deprecate this function once migration to Align is over.
unsigned getPrefTypeAlignment(Type *Ty) const;
+ /// Returns the preferred stack/global alignment for the specified
+ /// type.
+ ///
+ /// This is always at least as good as the ABI alignment.
+ Align getPrefTypeAlign(Type *Ty) const;
+
/// Returns an integer type with size at least as big as that of a
/// pointer in the given address space.
IntegerType *getIntPtrType(LLVMContext &C, unsigned AddressSpace = 0) const;
@@ -563,13 +578,26 @@ public:
/// Returns the preferred alignment of the specified global.
///
/// This includes an explicitly requested alignment (if the global has one).
- unsigned getPreferredAlignment(const GlobalVariable *GV) const;
+ Align getPreferredAlign(const GlobalVariable *GV) const;
+
+ /// Returns the preferred alignment of the specified global.
+ ///
+ /// This includes an explicitly requested alignment (if the global has one).
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline unsigned getPreferredAlignment(const GlobalVariable *GV) const,
+ "Use getPreferredAlign instead") {
+ return getPreferredAlign(GV).value();
+ }
/// Returns the preferred alignment of the specified global, returned
/// in log form.
///
/// This includes an explicitly requested alignment (if the global has one).
- unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const;
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const,
+ "Inline where needed") {
+ return Log2(getPreferredAlign(GV));
+ }
};
inline DataLayout *unwrap(LLVMTargetDataRef P) {
@@ -640,6 +668,7 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
case Type::IntegerTyID:
return TypeSize::Fixed(Ty->getIntegerBitWidth());
case Type::HalfTyID:
+ case Type::BFloatTyID:
return TypeSize::Fixed(16);
case Type::FloatTyID:
return TypeSize::Fixed(32);
@@ -653,7 +682,8 @@ inline TypeSize DataLayout::getTypeSizeInBits(Type *Ty) const {
// only 80 bits contain information.
case Type::X86_FP80TyID:
return TypeSize::Fixed(80);
- case Type::VectorTyID: {
+ case Type::FixedVectorTyID:
+ case Type::ScalableVectorTyID: {
VectorType *VTy = cast<VectorType>(Ty);
auto EltCnt = VTy->getElementCount();
uint64_t MinBits = EltCnt.Min *
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DebugInfo.h b/contrib/llvm-project/llvm/include/llvm/IR/DebugInfo.h
index 171e1621889f..e7c1d9a90677 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DebugInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DebugInfo.h
@@ -16,6 +16,7 @@
#ifndef LLVM_IR_DEBUGINFO_H
#define LLVM_IR_DEBUGINFO_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator_range.h"
@@ -23,8 +24,8 @@
namespace llvm {
-class DbgDeclareInst;
-class DbgValueInst;
+class DbgVariableIntrinsic;
+class Instruction;
class Module;
/// Find subprogram that is enclosing this scope.
@@ -50,6 +51,13 @@ bool stripDebugInfo(Function &F);
/// All debug type metadata nodes are unreachable and garbage collected.
bool stripNonLineTableDebugInfo(Module &M);
+/// Update the debug locations contained within the MD_loop metadata attached
+/// to the instruction \p I, if one exists. \p Updater is applied to each debug
+/// location in the MD_loop metadata: the returned value is included in the
+/// updated loop metadata node if it is non-null.
+void updateLoopMetadataDebugLocations(
+ Instruction &I, function_ref<DILocation *(const DILocation &)> Updater);
+
/// Return Debug Info Metadata Version by checking module flags.
unsigned getDebugMetadataVersionFromModule(const Module &M);
@@ -68,10 +76,8 @@ public:
/// Process a single instruction and collect debug info anchors.
void processInstruction(const Module &M, const Instruction &I);
- /// Process DbgDeclareInst.
- void processDeclare(const Module &M, const DbgDeclareInst *DDI);
- /// Process DbgValueInst.
- void processValue(const Module &M, const DbgValueInst *DVI);
+ /// Process DbgVariableIntrinsic.
+ void processVariable(const Module &M, const DbgVariableIntrinsic &DVI);
/// Process debug info location.
void processLocation(const Module &M, const DILocation *Loc);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h b/contrib/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h
index d6bfe504dd94..7d7cc4de7937 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -287,12 +287,8 @@ class DISubrange : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
- int64_t LowerBound;
-
- DISubrange(LLVMContext &C, StorageType Storage, Metadata *Node,
- int64_t LowerBound, ArrayRef<Metadata *> Ops)
- : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops),
- LowerBound(LowerBound) {}
+ DISubrange(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+ : DINode(C, DISubrangeKind, Storage, dwarf::DW_TAG_subrange_type, Ops) {}
~DISubrange() = default;
@@ -304,8 +300,14 @@ class DISubrange : public DINode {
int64_t LowerBound, StorageType Storage,
bool ShouldCreate = true);
+ static DISubrange *getImpl(LLVMContext &Context, Metadata *CountNode,
+ Metadata *LowerBound, Metadata *UpperBound,
+ Metadata *Stride, StorageType Storage,
+ bool ShouldCreate = true);
+
TempDISubrange cloneImpl() const {
- return getTemporary(getContext(), getRawCountNode(), getLowerBound());
+ return getTemporary(getContext(), getRawCountNode(), getRawLowerBound(),
+ getRawUpperBound(), getRawStride());
}
public:
@@ -315,25 +317,33 @@ public:
DEFINE_MDNODE_GET(DISubrange, (Metadata *CountNode, int64_t LowerBound = 0),
(CountNode, LowerBound))
- TempDISubrange clone() const { return cloneImpl(); }
+ DEFINE_MDNODE_GET(DISubrange,
+ (Metadata * CountNode, Metadata *LowerBound,
+ Metadata *UpperBound, Metadata *Stride),
+ (CountNode, LowerBound, UpperBound, Stride))
- int64_t getLowerBound() const { return LowerBound; }
+ TempDISubrange clone() const { return cloneImpl(); }
Metadata *getRawCountNode() const {
return getOperand(0).get();
}
+ Metadata *getRawLowerBound() const { return getOperand(1).get(); }
+
+ Metadata *getRawUpperBound() const { return getOperand(2).get(); }
+
+ Metadata *getRawStride() const { return getOperand(3).get(); }
+
typedef PointerUnion<ConstantInt*, DIVariable*> CountType;
+ typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
- CountType getCount() const {
- if (auto *MD = dyn_cast<ConstantAsMetadata>(getRawCountNode()))
- return CountType(cast<ConstantInt>(MD->getValue()));
+ CountType getCount() const;
- if (auto *DV = dyn_cast<DIVariable>(getRawCountNode()))
- return CountType(DV);
+ BoundType getLowerBound() const;
- return CountType();
- }
+ BoundType getUpperBound() const;
+
+ BoundType getStride() const;
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DISubrangeKind;
@@ -348,22 +358,26 @@ class DIEnumerator : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
- int64_t Value;
- DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
+ APInt Value;
+ DIEnumerator(LLVMContext &C, StorageType Storage, const APInt &Value,
bool IsUnsigned, ArrayRef<Metadata *> Ops)
: DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
Value(Value) {
SubclassData32 = IsUnsigned;
}
+ DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
+ bool IsUnsigned, ArrayRef<Metadata *> Ops)
+ : DIEnumerator(C, Storage, APInt(64, Value, !IsUnsigned), IsUnsigned,
+ Ops) {}
~DIEnumerator() = default;
- static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, StringRef Name,
StorageType Storage, bool ShouldCreate = true) {
return getImpl(Context, Value, IsUnsigned,
getCanonicalMDString(Context, Name), Storage, ShouldCreate);
}
- static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
+ static DIEnumerator *getImpl(LLVMContext &Context, const APInt &Value,
bool IsUnsigned, MDString *Name,
StorageType Storage, bool ShouldCreate = true);
@@ -372,14 +386,22 @@ class DIEnumerator : public DINode {
}
public:
- DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
+ DEFINE_MDNODE_GET(DIEnumerator,
+ (int64_t Value, bool IsUnsigned, StringRef Name),
+ (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
+ DEFINE_MDNODE_GET(DIEnumerator,
+ (int64_t Value, bool IsUnsigned, MDString *Name),
+ (APInt(64, Value, !IsUnsigned), IsUnsigned, Name))
+ DEFINE_MDNODE_GET(DIEnumerator,
+ (APInt Value, bool IsUnsigned, StringRef Name),
(Value, IsUnsigned, Name))
- DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
+ DEFINE_MDNODE_GET(DIEnumerator,
+ (APInt Value, bool IsUnsigned, MDString *Name),
(Value, IsUnsigned, Name))
TempDIEnumerator clone() const { return cloneImpl(); }
- int64_t getValue() const { return Value; }
+ const APInt &getValue() const { return Value; }
bool isUnsigned() const { return SubclassData32; }
StringRef getName() const { return getStringOperand(0); }
@@ -465,7 +487,8 @@ public:
// encoding is reserved.
CSK_MD5 = 1,
CSK_SHA1 = 2,
- CSK_Last = CSK_SHA1 // Should be last enumeration.
+ CSK_SHA256 = 3,
+ CSK_Last = CSK_SHA256 // Should be last enumeration.
};
/// A single checksum, represented by a \a Kind and a \a Value (a string).
@@ -918,13 +941,14 @@ class DICompositeType : public DIType {
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
DITemplateParameterArray TemplateParams, StringRef Identifier,
- DIDerivedType *Discriminator, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(
- Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
- BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
- RuntimeLang, VTableHolder, TemplateParams.get(),
- getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
+ DIDerivedType *Discriminator, Metadata *DataLocation,
+ StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
+ Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
+ Flags, Elements.get(), RuntimeLang, VTableHolder,
+ TemplateParams.get(),
+ getCanonicalMDString(Context, Identifier), Discriminator,
+ DataLocation, Storage, ShouldCreate);
}
static DICompositeType *
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
@@ -932,7 +956,7 @@ class DICompositeType : public DIType {
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
Metadata *VTableHolder, Metadata *TemplateParams,
- MDString *Identifier, Metadata *Discriminator,
+ MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
StorageType Storage, bool ShouldCreate = true);
TempDICompositeType cloneImpl() const {
@@ -940,34 +964,34 @@ class DICompositeType : public DIType {
getScope(), getBaseType(), getSizeInBits(),
getAlignInBits(), getOffsetInBits(), getFlags(),
getElements(), getRuntimeLang(), getVTableHolder(),
- getTemplateParams(), getIdentifier(), getDiscriminator());
+ getTemplateParams(), getIdentifier(),
+ getDiscriminator(), getRawDataLocation());
}
public:
- DEFINE_MDNODE_GET(DICompositeType,
- (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
- DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
- uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
- DINodeArray Elements, unsigned RuntimeLang,
- DIType *VTableHolder,
- DITemplateParameterArray TemplateParams = nullptr,
- StringRef Identifier = "",
- DIDerivedType *Discriminator = nullptr),
- (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
- AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Identifier, Discriminator))
- DEFINE_MDNODE_GET(DICompositeType,
- (unsigned Tag, MDString *Name, Metadata *File,
- unsigned Line, Metadata *Scope, Metadata *BaseType,
- uint64_t SizeInBits, uint32_t AlignInBits,
- uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
- unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams = nullptr,
- MDString *Identifier = nullptr,
- Metadata *Discriminator = nullptr),
- (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
- AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
- VTableHolder, TemplateParams, Identifier, Discriminator))
+ DEFINE_MDNODE_GET(
+ DICompositeType,
+ (unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
+ DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
+ DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
+ DITemplateParameterArray TemplateParams = nullptr,
+ StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
+ Metadata *DataLocation = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
+ Identifier, Discriminator, DataLocation))
+ DEFINE_MDNODE_GET(
+ DICompositeType,
+ (unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
+ Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
+ uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
+ Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
+ Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
+ Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr),
+ (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
+ OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
+ Identifier, Discriminator, DataLocation))
TempDICompositeType clone() const { return cloneImpl(); }
@@ -984,7 +1008,8 @@ public:
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams, Metadata *Discriminator);
+ Metadata *TemplateParams, Metadata *Discriminator,
+ Metadata *DataLocation);
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
MDString &Identifier);
@@ -1003,7 +1028,8 @@ public:
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
unsigned RuntimeLang, Metadata *VTableHolder,
- Metadata *TemplateParams, Metadata *Discriminator);
+ Metadata *TemplateParams, Metadata *Discriminator,
+ Metadata *DataLocation);
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
DINodeArray getElements() const {
@@ -1025,6 +1051,13 @@ public:
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
Metadata *getRawDiscriminator() const { return getOperand(8); }
DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
+ Metadata *getRawDataLocation() const { return getOperand(9); }
+ DIVariable *getDataLocation() const {
+ return dyn_cast_or_null<DIVariable>(getRawDataLocation());
+ }
+ DIExpression *getDataLocationExp() const {
+ return dyn_cast_or_null<DIExpression>(getRawDataLocation());
+ }
/// Replace operands.
///
@@ -1172,16 +1205,17 @@ private:
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
- unsigned NameTableKind, bool RangesBaseAddress, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(Context, SourceLanguage, File,
- getCanonicalMDString(Context, Producer), IsOptimized,
- getCanonicalMDString(Context, Flags), RuntimeVersion,
- getCanonicalMDString(Context, SplitDebugFilename),
- EmissionKind, EnumTypes.get(), RetainedTypes.get(),
- GlobalVariables.get(), ImportedEntities.get(), Macros.get(),
- DWOId, SplitDebugInlining, DebugInfoForProfiling,
- NameTableKind, RangesBaseAddress, Storage, ShouldCreate);
+ unsigned NameTableKind, bool RangesBaseAddress, StringRef SysRoot,
+ StringRef SDK, StorageType Storage, bool ShouldCreate = true) {
+ return getImpl(
+ Context, SourceLanguage, File, getCanonicalMDString(Context, Producer),
+ IsOptimized, getCanonicalMDString(Context, Flags), RuntimeVersion,
+ getCanonicalMDString(Context, SplitDebugFilename), EmissionKind,
+ EnumTypes.get(), RetainedTypes.get(), GlobalVariables.get(),
+ ImportedEntities.get(), Macros.get(), DWOId, SplitDebugInlining,
+ DebugInfoForProfiling, NameTableKind, RangesBaseAddress,
+ getCanonicalMDString(Context, SysRoot),
+ getCanonicalMDString(Context, SDK), Storage, ShouldCreate);
}
static DICompileUnit *
getImpl(LLVMContext &Context, unsigned SourceLanguage, Metadata *File,
@@ -1191,7 +1225,8 @@ private:
Metadata *GlobalVariables, Metadata *ImportedEntities,
Metadata *Macros, uint64_t DWOId, bool SplitDebugInlining,
bool DebugInfoForProfiling, unsigned NameTableKind,
- bool RangesBaseAddress, StorageType Storage, bool ShouldCreate = true);
+ bool RangesBaseAddress, MDString *SysRoot, MDString *SDK,
+ StorageType Storage, bool ShouldCreate = true);
TempDICompileUnit cloneImpl() const {
return getTemporary(
@@ -1200,7 +1235,7 @@ private:
getEmissionKind(), getEnumTypes(), getRetainedTypes(),
getGlobalVariables(), getImportedEntities(), getMacros(), DWOId,
getSplitDebugInlining(), getDebugInfoForProfiling(), getNameTableKind(),
- getRangesBaseAddress());
+ getRangesBaseAddress(), getSysRoot(), getSDK());
}
public:
@@ -1216,11 +1251,13 @@ public:
DIGlobalVariableExpressionArray GlobalVariables,
DIImportedEntityArray ImportedEntities, DIMacroNodeArray Macros,
uint64_t DWOId, bool SplitDebugInlining, bool DebugInfoForProfiling,
- DebugNameTableKind NameTableKind, bool RangesBaseAddress),
+ DebugNameTableKind NameTableKind, bool RangesBaseAddress,
+ StringRef SysRoot, StringRef SDK),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
- DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress))
+ DebugInfoForProfiling, (unsigned)NameTableKind, RangesBaseAddress,
+ SysRoot, SDK))
DEFINE_MDNODE_GET_DISTINCT_TEMPORARY(
DICompileUnit,
(unsigned SourceLanguage, Metadata *File, MDString *Producer,
@@ -1229,11 +1266,12 @@ public:
Metadata *RetainedTypes, Metadata *GlobalVariables,
Metadata *ImportedEntities, Metadata *Macros, uint64_t DWOId,
bool SplitDebugInlining, bool DebugInfoForProfiling,
- unsigned NameTableKind, bool RangesBaseAddress),
+ unsigned NameTableKind, bool RangesBaseAddress, MDString *SysRoot,
+ MDString *SDK),
(SourceLanguage, File, Producer, IsOptimized, Flags, RuntimeVersion,
SplitDebugFilename, EmissionKind, EnumTypes, RetainedTypes,
GlobalVariables, ImportedEntities, Macros, DWOId, SplitDebugInlining,
- DebugInfoForProfiling, NameTableKind, RangesBaseAddress))
+ DebugInfoForProfiling, NameTableKind, RangesBaseAddress, SysRoot, SDK))
TempDICompileUnit clone() const { return cloneImpl(); }
@@ -1250,14 +1288,10 @@ public:
DebugNameTableKind getNameTableKind() const {
return (DebugNameTableKind)NameTableKind;
}
- bool getRangesBaseAddress() const {
- return RangesBaseAddress; }
- StringRef getProducer() const {
- return getStringOperand(1); }
- StringRef getFlags() const {
- return getStringOperand(2); }
- StringRef getSplitDebugFilename() const {
- return getStringOperand(3); }
+ bool getRangesBaseAddress() const { return RangesBaseAddress; }
+ StringRef getProducer() const { return getStringOperand(1); }
+ StringRef getFlags() const { return getStringOperand(2); }
+ StringRef getSplitDebugFilename() const { return getStringOperand(3); }
DICompositeTypeArray getEnumTypes() const {
return cast_or_null<MDTuple>(getRawEnumTypes());
}
@@ -1279,6 +1313,8 @@ public:
void setSplitDebugInlining(bool SplitDebugInlining) {
this->SplitDebugInlining = SplitDebugInlining;
}
+ StringRef getSysRoot() const { return getStringOperand(9); }
+ StringRef getSDK() const { return getStringOperand(10); }
MDString *getRawProducer() const { return getOperandAs<MDString>(1); }
MDString *getRawFlags() const { return getOperandAs<MDString>(2); }
@@ -1290,6 +1326,8 @@ public:
Metadata *getRawGlobalVariables() const { return getOperand(6); }
Metadata *getRawImportedEntities() const { return getOperand(7); }
Metadata *getRawMacros() const { return getOperand(8); }
+ MDString *getRawSysRoot() const { return getOperandAs<MDString>(9); }
+ MDString *getRawSDK() const { return getOperandAs<MDString>(10); }
/// Replace arrays.
///
@@ -1540,6 +1578,13 @@ public:
static const DILocation *getMergedLocation(const DILocation *LocA,
const DILocation *LocB);
+ /// Try to combine the vector of locations passed as input in a single one.
+ /// This function applies getMergedLocation() repeatedly left-to-right.
+ ///
+ /// \p Locs: The locations to be merged.
+ static
+ const DILocation *getMergedLocations(ArrayRef<const DILocation *> Locs);
+
/// Returns the base discriminator for a given encoded discriminator \p D.
static unsigned getBaseDiscriminatorFromDiscriminator(unsigned D) {
return getUnsignedFromPrefixEncoding(D);
@@ -2072,60 +2117,72 @@ public:
}
};
-/// A (clang) module that has been imported by the compile unit.
-///
+/// Represents a module in the programming language, for example, a Clang
+/// module, or a Fortran module.
class DIModule : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
+ unsigned LineNo;
- DIModule(LLVMContext &Context, StorageType Storage, ArrayRef<Metadata *> Ops)
- : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {}
+ DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
+ ArrayRef<Metadata *> Ops)
+ : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
+ LineNo(LineNo) {}
~DIModule() = default;
- static DIModule *getImpl(LLVMContext &Context, DIScope *Scope,
+ static DIModule *getImpl(LLVMContext &Context, DIFile *File, DIScope *Scope,
StringRef Name, StringRef ConfigurationMacros,
- StringRef IncludePath, StringRef SysRoot,
- StorageType Storage, bool ShouldCreate = true) {
- return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
+ StringRef IncludePath, StringRef APINotesFile,
+ unsigned LineNo, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, File, Scope, getCanonicalMDString(Context, Name),
getCanonicalMDString(Context, ConfigurationMacros),
getCanonicalMDString(Context, IncludePath),
- getCanonicalMDString(Context, SysRoot),
- Storage, ShouldCreate);
+ getCanonicalMDString(Context, APINotesFile), LineNo, Storage,
+ ShouldCreate);
}
- static DIModule *getImpl(LLVMContext &Context, Metadata *Scope,
- MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath, MDString *SysRoot,
+ static DIModule *getImpl(LLVMContext &Context, Metadata *File,
+ Metadata *Scope, MDString *Name,
+ MDString *ConfigurationMacros, MDString *IncludePath,
+ MDString *APINotesFile, unsigned LineNo,
StorageType Storage, bool ShouldCreate = true);
TempDIModule cloneImpl() const {
- return getTemporary(getContext(), getScope(), getName(),
+ return getTemporary(getContext(), getFile(), getScope(), getName(),
getConfigurationMacros(), getIncludePath(),
- getSysRoot());
+ getAPINotesFile(), getLineNo());
}
public:
- DEFINE_MDNODE_GET(DIModule, (DIScope *Scope, StringRef Name,
- StringRef ConfigurationMacros, StringRef IncludePath,
- StringRef SysRoot),
- (Scope, Name, ConfigurationMacros, IncludePath, SysRoot))
DEFINE_MDNODE_GET(DIModule,
- (Metadata *Scope, MDString *Name, MDString *ConfigurationMacros,
- MDString *IncludePath, MDString *SysRoot),
- (Scope, Name, ConfigurationMacros, IncludePath, SysRoot))
+ (DIFile * File, DIScope *Scope, StringRef Name,
+ StringRef ConfigurationMacros, StringRef IncludePath,
+ StringRef APINotesFile, unsigned LineNo),
+ (File, Scope, Name, ConfigurationMacros, IncludePath,
+ APINotesFile, LineNo))
+ DEFINE_MDNODE_GET(DIModule,
+ (Metadata * File, Metadata *Scope, MDString *Name,
+ MDString *ConfigurationMacros, MDString *IncludePath,
+ MDString *APINotesFile, unsigned LineNo),
+ (File, Scope, Name, ConfigurationMacros, IncludePath,
+ APINotesFile, LineNo))
TempDIModule clone() const { return cloneImpl(); }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
- StringRef getName() const { return getStringOperand(1); }
- StringRef getConfigurationMacros() const { return getStringOperand(2); }
- StringRef getIncludePath() const { return getStringOperand(3); }
- StringRef getSysRoot() const { return getStringOperand(4); }
+ StringRef getName() const { return getStringOperand(2); }
+ StringRef getConfigurationMacros() const { return getStringOperand(3); }
+ StringRef getIncludePath() const { return getStringOperand(4); }
+ StringRef getAPINotesFile() const { return getStringOperand(5); }
+ unsigned getLineNo() const { return LineNo; }
- Metadata *getRawScope() const { return getOperand(0); }
- MDString *getRawName() const { return getOperandAs<MDString>(1); }
- MDString *getRawConfigurationMacros() const { return getOperandAs<MDString>(2); }
- MDString *getRawIncludePath() const { return getOperandAs<MDString>(3); }
- MDString *getRawSysRoot() const { return getOperandAs<MDString>(4); }
+ Metadata *getRawScope() const { return getOperand(1); }
+ MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ MDString *getRawConfigurationMacros() const {
+ return getOperandAs<MDString>(3);
+ }
+ MDString *getRawIncludePath() const { return getOperandAs<MDString>(4); }
+ MDString *getRawAPINotesFile() const { return getOperandAs<MDString>(5); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIModuleKind;
@@ -2135,9 +2192,11 @@ public:
/// Base class for template parameters.
class DITemplateParameter : public DINode {
protected:
+ bool IsDefault;
+
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
- unsigned Tag, ArrayRef<Metadata *> Ops)
- : DINode(Context, ID, Storage, Tag, Ops) {}
+ unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
+ : DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
~DITemplateParameter() = default;
public:
@@ -2146,6 +2205,7 @@ public:
MDString *getRawName() const { return getOperandAs<MDString>(0); }
Metadata *getRawType() const { return getOperand(1); }
+ bool isDefault() const { return IsDefault; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DITemplateTypeParameterKind ||
@@ -2158,30 +2218,35 @@ class DITemplateTypeParameter : public DITemplateParameter {
friend class MDNode;
DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
- ArrayRef<Metadata *> Ops)
+ bool IsDefault, ArrayRef<Metadata *> Ops)
: DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
- dwarf::DW_TAG_template_type_parameter, Ops) {}
+ dwarf::DW_TAG_template_type_parameter, IsDefault,
+ Ops) {}
~DITemplateTypeParameter() = default;
static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
- DIType *Type, StorageType Storage,
+ DIType *Type, bool IsDefault,
+ StorageType Storage,
bool ShouldCreate = true) {
- return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
- ShouldCreate);
+ return getImpl(Context, getCanonicalMDString(Context, Name), Type,
+ IsDefault, Storage, ShouldCreate);
}
static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
- Metadata *Type, StorageType Storage,
+ Metadata *Type, bool IsDefault,
+ StorageType Storage,
bool ShouldCreate = true);
TempDITemplateTypeParameter cloneImpl() const {
- return getTemporary(getContext(), getName(), getType());
+ return getTemporary(getContext(), getName(), getType(), isDefault());
}
public:
- DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DIType *Type),
- (Name, Type))
- DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
- (Name, Type))
+ DEFINE_MDNODE_GET(DITemplateTypeParameter,
+ (StringRef Name, DIType *Type, bool IsDefault),
+ (Name, Type, IsDefault))
+ DEFINE_MDNODE_GET(DITemplateTypeParameter,
+ (MDString *Name, Metadata *Type, bool IsDefault),
+ (Name, Type, IsDefault))
TempDITemplateTypeParameter clone() const { return cloneImpl(); }
@@ -2195,36 +2260,40 @@ class DITemplateValueParameter : public DITemplateParameter {
friend class MDNode;
DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
- unsigned Tag, ArrayRef<Metadata *> Ops)
+ unsigned Tag, bool IsDefault,
+ ArrayRef<Metadata *> Ops)
: DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
- Ops) {}
+ IsDefault, Ops) {}
~DITemplateValueParameter() = default;
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
StringRef Name, DIType *Type,
- Metadata *Value, StorageType Storage,
+ bool IsDefault, Metadata *Value,
+ StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
- Value, Storage, ShouldCreate);
+ IsDefault, Value, Storage, ShouldCreate);
}
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
MDString *Name, Metadata *Type,
- Metadata *Value, StorageType Storage,
+ bool IsDefault, Metadata *Value,
+ StorageType Storage,
bool ShouldCreate = true);
TempDITemplateValueParameter cloneImpl() const {
return getTemporary(getContext(), getTag(), getName(), getType(),
- getValue());
+ isDefault(), getValue());
}
public:
DEFINE_MDNODE_GET(DITemplateValueParameter,
- (unsigned Tag, StringRef Name, DIType *Type,
+ (unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
Metadata *Value),
- (Tag, Name, Type, Value))
- DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
- Metadata *Type, Metadata *Value),
- (Tag, Name, Type, Value))
+ (Tag, Name, Type, IsDefault, Value))
+ DEFINE_MDNODE_GET(DITemplateValueParameter,
+ (unsigned Tag, MDString *Name, Metadata *Type,
+ bool IsDefault, Metadata *Value),
+ (Tag, Name, Type, IsDefault, Value))
TempDITemplateValueParameter clone() const { return cloneImpl(); }
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DebugLoc.h b/contrib/llvm-project/llvm/include/llvm/IR/DebugLoc.h
index 780d17a33661..4914d733fe0d 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DebugLoc.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DebugLoc.h
@@ -85,7 +85,7 @@ namespace llvm {
/// the chain now is inlined-at the new call site.
/// \param InlinedAt The new outermost inlined-at in the chain.
/// \param ReplaceLast Replace the last location in the inlined-at chain.
- static DebugLoc appendInlinedAt(DebugLoc DL, DILocation *InlinedAt,
+ static DebugLoc appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
LLVMContext &Ctx,
DenseMap<const MDNode *, MDNode *> &Cache,
bool ReplaceLast = false);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DerivedTypes.h b/contrib/llvm-project/llvm/include/llvm/IR/DerivedTypes.h
index 20097ef3f31a..3618447168be 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DerivedTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DerivedTypes.h
@@ -195,26 +195,6 @@ private:
Value *Callee = nullptr;
};
-/// Common super class of ArrayType, StructType and VectorType.
-class CompositeType : public Type {
-protected:
- explicit CompositeType(LLVMContext &C, TypeID tid) : Type(C, tid) {}
-
-public:
- /// Given an index value into the type, return the type of the element.
- Type *getTypeAtIndex(const Value *V) const;
- Type *getTypeAtIndex(unsigned Idx) const;
- bool indexValid(const Value *V) const;
- bool indexValid(unsigned Idx) const;
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast.
- static bool classof(const Type *T) {
- return T->getTypeID() == ArrayTyID ||
- T->getTypeID() == StructTyID ||
- T->getTypeID() == VectorTyID;
- }
-};
-
/// Class to represent struct types. There are two different kinds of struct
/// types: Literal structs and Identified structs.
///
@@ -235,8 +215,8 @@ public:
/// elements as defined by DataLayout (which is required to match what the code
/// generator for a target expects).
///
-class StructType : public CompositeType {
- StructType(LLVMContext &C) : CompositeType(C, StructTyID) {}
+class StructType : public Type {
+ StructType(LLVMContext &C) : Type(C, StructTyID) {}
enum {
/// This is the contents of the SubClassData field.
@@ -267,8 +247,7 @@ public:
StringRef Name, bool isPacked = false);
static StructType *create(LLVMContext &Context, ArrayRef<Type *> Elements);
template <class... Tys>
- static typename std::enable_if<are_base_of<Type, Tys...>::value,
- StructType *>::type
+ static std::enable_if_t<are_base_of<Type, Tys...>::value, StructType *>
create(StringRef Name, Type *elt1, Tys *... elts) {
assert(elt1 && "Cannot create a struct type with no elements with this");
SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
@@ -286,8 +265,7 @@ public:
/// specifying the elements as arguments. Note that this method always returns
/// a non-packed struct, and requires at least one element type.
template <class... Tys>
- static typename std::enable_if<are_base_of<Type, Tys...>::value,
- StructType *>::type
+ static std::enable_if_t<are_base_of<Type, Tys...>::value, StructType *>
get(Type *elt1, Tys *... elts) {
assert(elt1 && "Cannot create a struct type with no elements with this");
LLVMContext &Ctx = elt1->getContext();
@@ -324,7 +302,7 @@ public:
void setBody(ArrayRef<Type*> Elements, bool isPacked = false);
template <typename... Tys>
- typename std::enable_if<are_base_of<Type, Tys...>::value, void>::type
+ std::enable_if_t<are_base_of<Type, Tys...>::value, void>
setBody(Type *elt1, Tys *... elts) {
assert(elt1 && "Cannot create a struct type with no elements with this");
SmallVector<llvm::Type *, 8> StructFields({elt1, elts...});
@@ -352,6 +330,11 @@ public:
assert(N < NumContainedTys && "Element number out of range!");
return ContainedTys[N];
}
+ /// Given an index value into the type, return the type of the element.
+ Type *getTypeAtIndex(const Value *V) const;
+ Type *getTypeAtIndex(unsigned N) const { return getElementType(N); }
+ bool indexValid(const Value *V) const;
+ bool indexValid(unsigned Idx) const { return Idx < getNumElements(); }
/// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Type *T) {
@@ -371,47 +354,22 @@ Type *Type::getStructElementType(unsigned N) const {
return cast<StructType>(this)->getElementType(N);
}
-/// This is the superclass of the array and vector type classes. Both of these
-/// represent "arrays" in memory. The array type represents a specifically sized
-/// array, and the vector type represents a specifically sized array that allows
-/// for use of SIMD instructions. SequentialType holds the common features of
-/// both, which stem from the fact that both lay their components out in memory
-/// identically.
-class SequentialType : public CompositeType {
- Type *ContainedType; ///< Storage for the single contained type.
+/// Class to represent array types.
+class ArrayType : public Type {
+ /// The element type of the array.
+ Type *ContainedType;
+ /// Number of elements in the array.
uint64_t NumElements;
-protected:
- SequentialType(TypeID TID, Type *ElType, uint64_t NumElements)
- : CompositeType(ElType->getContext(), TID), ContainedType(ElType),
- NumElements(NumElements) {
- ContainedTys = &ContainedType;
- NumContainedTys = 1;
- }
-
-public:
- SequentialType(const SequentialType &) = delete;
- SequentialType &operator=(const SequentialType &) = delete;
-
- /// For scalable vectors, this will return the minimum number of elements
- /// in the vector.
- uint64_t getNumElements() const { return NumElements; }
- Type *getElementType() const { return ContainedType; }
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast.
- static bool classof(const Type *T) {
- return T->getTypeID() == ArrayTyID || T->getTypeID() == VectorTyID;
- }
-};
-
-/// Class to represent array types.
-class ArrayType : public SequentialType {
ArrayType(Type *ElType, uint64_t NumEl);
public:
ArrayType(const ArrayType &) = delete;
ArrayType &operator=(const ArrayType &) = delete;
+ uint64_t getNumElements() const { return NumElements; }
+ Type *getElementType() const { return ContainedType; }
+
/// This static method is the primary way to construct an ArrayType
static ArrayType *get(Type *ElementType, uint64_t NumElements);
@@ -428,8 +386,8 @@ uint64_t Type::getArrayNumElements() const {
return cast<ArrayType>(this)->getNumElements();
}
-/// Class to represent vector types.
-class VectorType : public SequentialType {
+/// Base class of all SIMD vector types
+class VectorType : public Type {
/// A fully specified VectorType is of the form <vscale x n x Ty>. 'n' is the
/// minimum number of elements of type Ty contained within the vector, and
/// 'vscale x' indicates that the total element count is an integer multiple
@@ -443,25 +401,69 @@ class VectorType : public SequentialType {
/// <vscale x 4 x i32> - a vector containing an unknown integer multiple
/// of 4 i32s
- VectorType(Type *ElType, unsigned NumEl, bool Scalable = false);
- VectorType(Type *ElType, ElementCount EC);
+ /// The element type of the vector.
+ Type *ContainedType;
- // If true, the total number of elements is an unknown multiple of the
- // minimum 'NumElements' from SequentialType. Otherwise the total number
- // of elements is exactly equal to 'NumElements'.
- bool Scalable;
+protected:
+ /// The element quantity of this vector. The meaning of this value depends
+ /// on the type of vector:
+ /// - For FixedVectorType = <ElementQuantity x ty>, there are
+ /// exactly ElementQuantity elements in this vector.
+ /// - For ScalableVectorType = <vscale x ElementQuantity x ty>,
+ /// there are vscale * ElementQuantity elements in this vector, where
+ /// vscale is a runtime-constant integer greater than 0.
+ const unsigned ElementQuantity;
+
+ VectorType(Type *ElType, unsigned EQ, Type::TypeID TID);
public:
VectorType(const VectorType &) = delete;
VectorType &operator=(const VectorType &) = delete;
+ /// Get the number of elements in this vector. It does not make sense to call
+ /// this function on a scalable vector, and this will be moved into
+ /// FixedVectorType in a future commit
+ unsigned getNumElements() const {
+ ElementCount EC = getElementCount();
+#ifdef STRICT_FIXED_SIZE_VECTORS
+ assert(!EC.Scalable &&
+ "Request for fixed number of elements from scalable vector");
+ return EC.Min;
+#else
+ if (EC.Scalable)
+ WithColor::warning()
+ << "The code that requested the fixed number of elements has made "
+ "the assumption that this vector is not scalable. This assumption "
+ "was not correct, and this may lead to broken code\n";
+ return EC.Min;
+#endif
+ }
+
+ Type *getElementType() const { return ContainedType; }
+
/// This static method is the primary way to construct an VectorType.
static VectorType *get(Type *ElementType, ElementCount EC);
+
+ /// Base class getter that specifically constructs a FixedVectorType. This
+ /// function is deprecated, and will be removed after LLVM 11 ships. Since
+ /// this always returns a FixedVectorType via a base VectorType pointer,
+ /// FixedVectorType::get(Type *, unsigned) is strictly better since no cast is
+ /// required to call getNumElements() on the result.
+ LLVM_ATTRIBUTE_DEPRECATED(
+ inline static VectorType *get(Type *ElementType, unsigned NumElements),
+ "The base class version of get with the scalable argument defaulted to "
+ "false is deprecated. Either call VectorType::get(Type *, unsigned, "
+ "bool) and pass false, or call FixedVectorType::get(Type *, unsigned).");
+
static VectorType *get(Type *ElementType, unsigned NumElements,
- bool Scalable = false) {
+ bool Scalable) {
return VectorType::get(ElementType, {NumElements, Scalable});
}
+ static VectorType *get(Type *ElementType, const VectorType *Other) {
+ return VectorType::get(ElementType, Other->getElementCount());
+ }
+
/// This static method gets a VectorType with the same number of elements as
/// the input type, and the element type is an integer type of the same width
/// as the input element type.
@@ -529,9 +531,8 @@ public:
/// input type and the same element type.
static VectorType *getDoubleElementsVectorType(VectorType *VTy) {
auto EltCnt = VTy->getElementCount();
- assert((VTy->getNumElements() * 2ull) <= UINT_MAX &&
- "Too many elements in vector");
- return VectorType::get(VTy->getElementType(), EltCnt*2);
+ assert((EltCnt.Min * 2ull) <= UINT_MAX && "Too many elements in vector");
+ return VectorType::get(VTy->getElementType(), EltCnt * 2);
}
/// Return true if the specified type is valid as a element type.
@@ -539,40 +540,122 @@ public:
/// Return an ElementCount instance to represent the (possibly scalable)
/// number of elements in the vector.
- ElementCount getElementCount() const {
- uint64_t MinimumEltCnt = getNumElements();
- assert(MinimumEltCnt <= UINT_MAX && "Too many elements in vector");
- return { (unsigned)MinimumEltCnt, Scalable };
+ inline ElementCount getElementCount() const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast.
+ static bool classof(const Type *T) {
+ return T->getTypeID() == FixedVectorTyID ||
+ T->getTypeID() == ScalableVectorTyID;
}
+};
- /// Returns whether or not this is a scalable vector (meaning the total
- /// element count is a multiple of the minimum).
- bool isScalable() const {
- return Scalable;
+inline VectorType *VectorType::get(Type *ElementType, unsigned NumElements) {
+ return VectorType::get(ElementType, NumElements, false);
+}
+
+/// Class to represent fixed width SIMD vectors
+class FixedVectorType : public VectorType {
+protected:
+ FixedVectorType(Type *ElTy, unsigned NumElts)
+ : VectorType(ElTy, NumElts, FixedVectorTyID) {}
+
+public:
+ static FixedVectorType *get(Type *ElementType, unsigned NumElts);
+
+ static FixedVectorType *get(Type *ElementType, const FixedVectorType *FVTy) {
+ return get(ElementType, FVTy->getNumElements());
}
- /// Return the minimum number of bits in the Vector type.
- /// Returns zero when the vector is a vector of pointers.
- unsigned getBitWidth() const {
- return getNumElements() * getElementType()->getPrimitiveSizeInBits();
+ static FixedVectorType *getInteger(FixedVectorType *VTy) {
+ return cast<FixedVectorType>(VectorType::getInteger(VTy));
+ }
+
+ static FixedVectorType *getExtendedElementVectorType(FixedVectorType *VTy) {
+ return cast<FixedVectorType>(VectorType::getExtendedElementVectorType(VTy));
+ }
+
+ static FixedVectorType *getTruncatedElementVectorType(FixedVectorType *VTy) {
+ return cast<FixedVectorType>(
+ VectorType::getTruncatedElementVectorType(VTy));
+ }
+
+ static FixedVectorType *getSubdividedVectorType(FixedVectorType *VTy,
+ int NumSubdivs) {
+ return cast<FixedVectorType>(
+ VectorType::getSubdividedVectorType(VTy, NumSubdivs));
+ }
+
+ static FixedVectorType *getHalfElementsVectorType(FixedVectorType *VTy) {
+ return cast<FixedVectorType>(VectorType::getHalfElementsVectorType(VTy));
+ }
+
+ static FixedVectorType *getDoubleElementsVectorType(FixedVectorType *VTy) {
+ return cast<FixedVectorType>(VectorType::getDoubleElementsVectorType(VTy));
}
- /// Methods for support type inquiry through isa, cast, and dyn_cast.
static bool classof(const Type *T) {
- return T->getTypeID() == VectorTyID;
+ return T->getTypeID() == FixedVectorTyID;
}
};
-unsigned Type::getVectorNumElements() const {
- return cast<VectorType>(this)->getNumElements();
-}
+/// Class to represent scalable SIMD vectors
+class ScalableVectorType : public VectorType {
+protected:
+ ScalableVectorType(Type *ElTy, unsigned MinNumElts)
+ : VectorType(ElTy, MinNumElts, ScalableVectorTyID) {}
-bool Type::getVectorIsScalable() const {
- return cast<VectorType>(this)->isScalable();
-}
+public:
+ static ScalableVectorType *get(Type *ElementType, unsigned MinNumElts);
+
+ static ScalableVectorType *get(Type *ElementType,
+ const ScalableVectorType *SVTy) {
+ return get(ElementType, SVTy->getMinNumElements());
+ }
+
+ static ScalableVectorType *getInteger(ScalableVectorType *VTy) {
+ return cast<ScalableVectorType>(VectorType::getInteger(VTy));
+ }
+
+ static ScalableVectorType *
+ getExtendedElementVectorType(ScalableVectorType *VTy) {
+ return cast<ScalableVectorType>(
+ VectorType::getExtendedElementVectorType(VTy));
+ }
+
+ static ScalableVectorType *
+ getTruncatedElementVectorType(ScalableVectorType *VTy) {
+ return cast<ScalableVectorType>(
+ VectorType::getTruncatedElementVectorType(VTy));
+ }
+
+ static ScalableVectorType *getSubdividedVectorType(ScalableVectorType *VTy,
+ int NumSubdivs) {
+ return cast<ScalableVectorType>(
+ VectorType::getSubdividedVectorType(VTy, NumSubdivs));
+ }
+
+ static ScalableVectorType *
+ getHalfElementsVectorType(ScalableVectorType *VTy) {
+ return cast<ScalableVectorType>(VectorType::getHalfElementsVectorType(VTy));
+ }
+
+ static ScalableVectorType *
+ getDoubleElementsVectorType(ScalableVectorType *VTy) {
+ return cast<ScalableVectorType>(
+ VectorType::getDoubleElementsVectorType(VTy));
+ }
+
+ /// Get the minimum number of elements in this vector. The actual number of
+ /// elements in the vector is an integer multiple of this value.
+ uint64_t getMinNumElements() const { return ElementQuantity; }
-ElementCount Type::getVectorElementCount() const {
- return cast<VectorType>(this)->getElementCount();
+ static bool classof(const Type *T) {
+ return T->getTypeID() == ScalableVectorTyID;
+ }
+};
+
+inline ElementCount VectorType::getElementCount() const {
+ return ElementCount(ElementQuantity, isa<ScalableVectorType>(this));
}
/// Class to represent pointers.
@@ -627,8 +710,8 @@ Type *Type::getWithNewBitWidth(unsigned NewBitWidth) const {
isIntOrIntVectorTy() &&
"Original type expected to be a vector of integers or a scalar integer.");
Type *NewType = getIntNTy(getContext(), NewBitWidth);
- if (isVectorTy())
- NewType = VectorType::get(NewType, getVectorElementCount());
+ if (auto *VTy = dyn_cast<VectorType>(this))
+ NewType = VectorType::get(NewType, VTy->getElementCount());
return NewType;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h b/contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h
index ec469982d378..b7e0ecde8629 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/DiagnosticInfo.h
@@ -55,6 +55,7 @@ enum DiagnosticKind {
DK_ResourceLimit,
DK_StackSize,
DK_Linker,
+ DK_Lowering,
DK_DebugMetadataVersion,
DK_DebugMetadataInvalid,
DK_ISelFallback,
@@ -212,7 +213,7 @@ public:
};
class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit {
- virtual void anchor() override;
+ void anchor() override;
public:
DiagnosticInfoStackSize(const Function &Fn, uint64_t StackSize,
DiagnosticSeverity Severity = DS_Warning,
@@ -363,7 +364,7 @@ public:
/// Common features for diagnostics with an associated location.
class DiagnosticInfoWithLocationBase : public DiagnosticInfo {
- virtual void anchor() override;
+ void anchor() override;
public:
/// \p Fn is the function where the diagnostic is being emitted. \p Loc is
/// the location information to use in the diagnostic.
@@ -531,9 +532,10 @@ protected:
template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>::type S) {
+ StringRef>
+ S) {
R.insert(S);
return R;
}
@@ -543,9 +545,10 @@ operator<<(RemarkT &R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- StringRef>::type S) {
+ StringRef>
+ S) {
R.insert(S);
return R;
}
@@ -553,9 +556,10 @@ operator<<(RemarkT &&R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>::type A) {
+ DiagnosticInfoOptimizationBase::Argument>
+ A) {
R.insert(A);
return R;
}
@@ -563,9 +567,10 @@ operator<<(RemarkT &R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::Argument>::type A) {
+ DiagnosticInfoOptimizationBase::Argument>
+ A) {
R.insert(A);
return R;
}
@@ -573,9 +578,10 @@ operator<<(RemarkT &&R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
+ DiagnosticInfoOptimizationBase::setIsVerbose>
+ V) {
R.insert(V);
return R;
}
@@ -583,9 +589,10 @@ operator<<(RemarkT &R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &&R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setIsVerbose>::type V) {
+ DiagnosticInfoOptimizationBase::setIsVerbose>
+ V) {
R.insert(V);
return R;
}
@@ -593,9 +600,10 @@ operator<<(RemarkT &&R,
template <class RemarkT>
RemarkT &
operator<<(RemarkT &R,
- typename std::enable_if<
+ std::enable_if_t<
std::is_base_of<DiagnosticInfoOptimizationBase, RemarkT>::value,
- DiagnosticInfoOptimizationBase::setExtraArgs>::type EA) {
+ DiagnosticInfoOptimizationBase::setExtraArgs>
+ EA) {
R.insert(EA);
return R;
}
@@ -603,7 +611,7 @@ operator<<(RemarkT &R,
/// Common features for diagnostics dealing with optimization remarks
/// that are used by IR passes.
class DiagnosticInfoIROptimization : public DiagnosticInfoOptimizationBase {
- virtual void anchor() override;
+ void anchor() override;
public:
/// \p PassName is the name of the pass emitting this diagnostic. \p
/// RemarkName is a textual identifier for the remark (single-word,
@@ -824,7 +832,7 @@ private:
/// Diagnostic information for optimization analysis remarks related to
/// floating-point non-commutativity.
class OptimizationRemarkAnalysisFPCommute : public OptimizationRemarkAnalysis {
- virtual void anchor();
+ void anchor() override;
public:
/// \p PassName is the name of the pass emitting this diagnostic. If this name
/// matches the regular expression given in -Rpass-analysis=, then the
@@ -866,7 +874,7 @@ private:
/// Diagnostic information for optimization analysis remarks related to
/// pointer aliasing.
class OptimizationRemarkAnalysisAliasing : public OptimizationRemarkAnalysis {
- virtual void anchor();
+ void anchor() override;
public:
/// \p PassName is the name of the pass emitting this diagnostic. If this name
/// matches the regular expression given in -Rpass-analysis=, then the
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Dominators.h b/contrib/llvm-project/llvm/include/llvm/IR/Dominators.h
index 6a14785a6cc3..71595cb15df4 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Dominators.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Dominators.h
@@ -172,6 +172,8 @@ class DominatorTree : public DominatorTreeBase<BasicBlock, false> {
/// never dominate the use.
bool dominates(const BasicBlockEdge &BBE, const Use &U) const;
bool dominates(const BasicBlockEdge &BBE, const BasicBlock *BB) const;
+ /// Returns true if edge \p BBE1 dominates edge \p BBE2.
+ bool dominates(const BasicBlockEdge &BBE1, const BasicBlockEdge &BBE2) const;
// Ensure base class overloads are visible.
using Base::isReachableFromEntry;
@@ -206,7 +208,8 @@ template <class Node, class ChildIterator> struct DomTreeGraphTraitsBase {
template <>
struct GraphTraits<DomTreeNode *>
- : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::iterator> {};
+ : public DomTreeGraphTraitsBase<DomTreeNode, DomTreeNode::const_iterator> {
+};
template <>
struct GraphTraits<const DomTreeNode *>
@@ -275,7 +278,7 @@ public:
AU.setPreservesAll();
}
- void releaseMemory() override { DT.releaseMemory(); }
+ void releaseMemory() override { DT.reset(); }
void print(raw_ostream &OS, const Module *M = nullptr) const override;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/FPEnv.h b/contrib/llvm-project/llvm/include/llvm/IR/FPEnv.h
index a1e0665d4112..f00cb735932f 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/FPEnv.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/FPEnv.h
@@ -15,27 +15,14 @@
#ifndef LLVM_IR_FLOATINGPOINT_H
#define LLVM_IR_FLOATINGPOINT_H
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include <stdint.h>
namespace llvm {
+class StringRef;
namespace fp {
-/// Rounding mode used for floating point operations.
-///
-/// Each of these values correspond to some metadata argument value of a
-/// constrained floating point intrinsic. See the LLVM Language Reference Manual
-/// for details.
-enum RoundingMode : uint8_t {
- rmDynamic, ///< This corresponds to "fpround.dynamic".
- rmToNearest, ///< This corresponds to "fpround.tonearest".
- rmDownward, ///< This corresponds to "fpround.downward".
- rmUpward, ///< This corresponds to "fpround.upward".
- rmTowardZero ///< This corresponds to "fpround.tozero".
-};
-
/// Exception behavior used for floating point operations.
///
/// Each of these values correspond to some metadata argument value of a
@@ -52,11 +39,11 @@ enum ExceptionBehavior : uint8_t {
/// Returns a valid RoundingMode enumerator when given a string
/// that is valid as input in constrained intrinsic rounding mode
/// metadata.
-Optional<fp::RoundingMode> StrToRoundingMode(StringRef);
+Optional<RoundingMode> StrToRoundingMode(StringRef);
/// For any RoundingMode enumerator, returns a string valid as input in
/// constrained intrinsic rounding mode metadata.
-Optional<StringRef> RoundingModeToStr(fp::RoundingMode);
+Optional<StringRef> RoundingModeToStr(RoundingMode);
/// Returns a valid ExceptionBehavior enumerator when given a string
/// valid as input in constrained intrinsic exception behavior metadata.
@@ -65,6 +52,5 @@ Optional<fp::ExceptionBehavior> StrToExceptionBehavior(StringRef);
/// For any ExceptionBehavior enumerator, returns a string valid as
/// input in constrained intrinsic exception behavior metadata.
Optional<StringRef> ExceptionBehaviorToStr(fp::ExceptionBehavior);
-
}
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Function.h b/contrib/llvm-project/llvm/include/llvm/IR/Function.h
index d9cbcc63fa62..bb4ec13c7610 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Function.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Function.h
@@ -55,6 +55,8 @@ template <typename T> class Optional;
class raw_ostream;
class Type;
class User;
+class BranchProbabilityInfo;
+class BlockFrequencyInfo;
class Function : public GlobalObject, public ilist_node<Function> {
public:
@@ -197,6 +199,11 @@ public:
/// returns Intrinsic::not_intrinsic!
bool isIntrinsic() const { return HasLLVMReservedName; }
+ /// Returns true if the function is one of the "Constrained Floating-Point
+ /// Intrinsics". Returns false if not, and returns false when
+ /// getIntrinsicID() returns Intrinsic::not_intrinsic.
+ bool isConstrainedFPIntrinsic() const;
+
static Intrinsic::ID lookupIntrinsicID(StringRef Name);
/// Recalculate the ID for this function if it is an Intrinsic defined
@@ -349,6 +356,13 @@ public:
return 0;
}
+ /// Return the stack alignment for the function.
+ MaybeAlign getFnStackAlign() const {
+ if (!hasFnAttribute(Attribute::StackAlignment))
+ return None;
+ return AttributeSets.getStackAlignment(AttributeList::FunctionIndex);
+ }
+
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
/// to use during code generation.
bool hasGC() const {
@@ -780,6 +794,10 @@ public:
///
void viewCFG() const;
+ /// Extended form to print edge weights.
+ void viewCFG(bool ViewCFGOnly, const BlockFrequencyInfo *BFI,
+ const BranchProbabilityInfo *BPI) const;
+
/// viewCFGOnly - This function is meant for use from the debugger. It works
/// just like viewCFG, but it does not include the contents of basic blocks
/// into the nodes, just the label. If you are only interested in the CFG
@@ -787,6 +805,10 @@ public:
///
void viewCFGOnly() const;
+ /// Extended form to print edge weights.
+ void viewCFGOnly(const BlockFrequencyInfo *BFI,
+ const BranchProbabilityInfo *BPI) const;
+
/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal;
@@ -808,9 +830,11 @@ public:
/// hasAddressTaken - returns true if there are any uses of this function
/// other than direct calls or invokes to it, or blockaddress expressions.
- /// Optionally passes back an offending user for diagnostic purposes.
+ /// Optionally passes back an offending user for diagnostic purposes and
+ /// ignores callback uses.
///
- bool hasAddressTaken(const User** = nullptr) const;
+ bool hasAddressTaken(const User ** = nullptr,
+ bool IgnoreCallbackUses = false) const;
/// isDefTriviallyDead - Return true if it is trivially safe to remove
/// this function definition from the module (because it isn't externally
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/GetElementPtrTypeIterator.h b/contrib/llvm-project/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
index 9b257abc7c1f..79ea5791b2fd 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/GetElementPtrTypeIterator.h
@@ -75,9 +75,15 @@ namespace llvm {
generic_gep_type_iterator& operator++() { // Preincrement
Type *Ty = getIndexedType();
- if (auto *STy = dyn_cast<SequentialType>(Ty)) {
- CurTy = STy->getElementType();
- NumElements = STy->getNumElements();
+ if (auto *ATy = dyn_cast<ArrayType>(Ty)) {
+ CurTy = ATy->getElementType();
+ NumElements = ATy->getNumElements();
+ } else if (auto *VTy = dyn_cast<VectorType>(Ty)) {
+ CurTy = VTy->getElementType();
+ if (isa<ScalableVectorType>(VTy))
+ NumElements = Unbounded;
+ else
+ NumElements = VTy->getNumElements();
} else
CurTy = dyn_cast<StructType>(Ty);
++OpIt;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/GlobalObject.h b/contrib/llvm-project/llvm/include/llvm/IR/GlobalObject.h
index ce81eb9f0719..3a7b718845cb 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/GlobalObject.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/GlobalObject.h
@@ -70,16 +70,22 @@ private:
public:
GlobalObject(const GlobalObject &) = delete;
+ /// FIXME: Remove this function once transition to Align is over.
unsigned getAlignment() const {
+ MaybeAlign Align = getAlign();
+ return Align ? Align->value() : 0;
+ }
+
+ /// Returns the alignment of the given variable or function.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ MaybeAlign getAlign() const {
unsigned Data = getGlobalValueSubClassData();
unsigned AlignmentData = Data & AlignmentMask;
- MaybeAlign Align = decodeMaybeAlign(AlignmentData);
- return Align ? Align->value() : 0;
+ return decodeMaybeAlign(AlignmentData);
}
- /// FIXME: Remove this setter once the migration to MaybeAlign is over.
- LLVM_ATTRIBUTE_DEPRECATED(void setAlignment(unsigned Align),
- "Please use `void setAlignment(MaybeAlign Align)`");
void setAlignment(MaybeAlign Align);
unsigned getGlobalObjectSubClassData() const {
@@ -178,9 +184,16 @@ public:
void copyMetadata(const GlobalObject *Src, unsigned Offset);
void addTypeMetadata(unsigned Offset, Metadata *TypeID);
- void addVCallVisibilityMetadata(VCallVisibility Visibility);
+ void setVCallVisibilityMetadata(VCallVisibility Visibility);
VCallVisibility getVCallVisibility() const;
+ /// Returns true if the alignment of the value can be unilaterally
+ /// increased.
+ ///
+ /// Note that for functions this is the alignment of the code, not the
+ /// alignment of a function pointer.
+ bool canIncreaseAlignment() const;
+
protected:
void copyAttributesFrom(const GlobalObject *Src);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/GlobalValue.h b/contrib/llvm-project/llvm/include/llvm/IR/GlobalValue.h
index 0171356914d6..cf704d1f2374 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/GlobalValue.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/GlobalValue.h
@@ -146,12 +146,6 @@ private:
llvm_unreachable("Fully covered switch above!");
}
- void maybeSetDsoLocal() {
- if (hasLocalLinkage() ||
- (!hasDefaultVisibility() && !hasExternalWeakLinkage()))
- setDSOLocal(true);
- }
-
protected:
/// The intrinsic ID for this subclass (which must be a Function).
///
@@ -191,7 +185,6 @@ public:
GlobalValue(const GlobalValue &) = delete;
- unsigned getAlignment() const;
unsigned getAddressSpace() const;
enum class UnnamedAddr {
@@ -243,7 +236,8 @@ public:
assert((!hasLocalLinkage() || V == DefaultVisibility) &&
"local linkage requires default visibility");
Visibility = V;
- maybeSetDsoLocal();
+ if (isImplicitDSOLocal())
+ setDSOLocal(true);
}
/// If the value is "Thread Local", its value isn't shared by the threads.
@@ -278,6 +272,11 @@ public:
Type *getValueType() const { return ValueType; }
+ bool isImplicitDSOLocal() const {
+ return hasLocalLinkage() ||
+ (!hasDefaultVisibility() && !hasExternalWeakLinkage());
+ }
+
void setDSOLocal(bool Local) { IsDSOLocal = Local; }
bool isDSOLocal() const {
@@ -423,10 +422,11 @@ public:
}
/// Return true if this global's definition can be substituted with an
- /// *arbitrary* definition at link time. We cannot do any IPO or inlinining
- /// across interposable call edges, since the callee can be replaced with
- /// something arbitrary at link time.
- bool isInterposable() const { return isInterposableLinkage(getLinkage()); }
+ /// *arbitrary* definition at link time or load time. We cannot do any IPO or
+ /// inlining across interposable call edges, since the callee can be
+ /// replaced with something arbitrary.
+ bool isInterposable() const;
+ bool canBenefitFromLocalAlias() const;
bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); }
bool hasAvailableExternallyLinkage() const {
@@ -455,7 +455,8 @@ public:
if (isLocalLinkage(LT))
Visibility = DefaultVisibility;
Linkage = LT;
- maybeSetDsoLocal();
+ if (isImplicitDSOLocal())
+ setDSOLocal(true);
}
LinkageTypes getLinkage() const { return LinkageTypes(Linkage); }
@@ -547,10 +548,6 @@ public:
return !(isDeclarationForLinker() || isWeakForLinker());
}
- // Returns true if the alignment of the value can be unilaterally
- // increased.
- bool canIncreaseAlignment() const;
-
const GlobalObject *getBaseObject() const;
GlobalObject *getBaseObject() {
return const_cast<GlobalObject *>(
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/GlobalVariable.h b/contrib/llvm-project/llvm/include/llvm/IR/GlobalVariable.h
index 2c730bc312e4..12093e337d6e 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/GlobalVariable.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/GlobalVariable.h
@@ -19,7 +19,6 @@
#ifndef LLVM_IR_GLOBALVARIABLE_H
#define LLVM_IR_GLOBALVARIABLE_H
-#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/Attributes.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
index a6252b298001..4552ca016bd7 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilder.h
@@ -59,9 +59,12 @@ class Use;
///
/// By default, this inserts the instruction at the insertion point.
class IRBuilderDefaultInserter {
-protected:
- void InsertHelper(Instruction *I, const Twine &Name,
- BasicBlock *BB, BasicBlock::iterator InsertPt) const {
+public:
+ virtual ~IRBuilderDefaultInserter();
+
+ virtual void InsertHelper(Instruction *I, const Twine &Name,
+ BasicBlock *BB,
+ BasicBlock::iterator InsertPt) const {
if (BB) BB->getInstList().insert(InsertPt, I);
I->setName(Name);
}
@@ -69,16 +72,18 @@ protected:
/// Provides an 'InsertHelper' that calls a user-provided callback after
/// performing the default insertion.
-class IRBuilderCallbackInserter : IRBuilderDefaultInserter {
+class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
std::function<void(Instruction *)> Callback;
public:
+ virtual ~IRBuilderCallbackInserter();
+
IRBuilderCallbackInserter(std::function<void(Instruction *)> Callback)
: Callback(std::move(Callback)) {}
-protected:
void InsertHelper(Instruction *I, const Twine &Name,
- BasicBlock *BB, BasicBlock::iterator InsertPt) const {
+ BasicBlock *BB,
+ BasicBlock::iterator InsertPt) const override {
IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
Callback(I);
}
@@ -92,26 +97,50 @@ protected:
BasicBlock *BB;
BasicBlock::iterator InsertPt;
LLVMContext &Context;
+ const IRBuilderFolder &Folder;
+ const IRBuilderDefaultInserter &Inserter;
MDNode *DefaultFPMathTag;
FastMathFlags FMF;
bool IsFPConstrained;
fp::ExceptionBehavior DefaultConstrainedExcept;
- fp::RoundingMode DefaultConstrainedRounding;
+ RoundingMode DefaultConstrainedRounding;
ArrayRef<OperandBundleDef> DefaultOperandBundles;
public:
- IRBuilderBase(LLVMContext &context, MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : Context(context), DefaultFPMathTag(FPMathTag), IsFPConstrained(false),
+ IRBuilderBase(LLVMContext &context, const IRBuilderFolder &Folder,
+ const IRBuilderDefaultInserter &Inserter,
+ MDNode *FPMathTag, ArrayRef<OperandBundleDef> OpBundles)
+ : Context(context), Folder(Folder), Inserter(Inserter),
+ DefaultFPMathTag(FPMathTag), IsFPConstrained(false),
DefaultConstrainedExcept(fp::ebStrict),
- DefaultConstrainedRounding(fp::rmDynamic),
+ DefaultConstrainedRounding(RoundingMode::Dynamic),
DefaultOperandBundles(OpBundles) {
ClearInsertionPoint();
}
+ /// Insert and return the specified instruction.
+ template<typename InstTy>
+ InstTy *Insert(InstTy *I, const Twine &Name = "") const {
+ Inserter.InsertHelper(I, Name, BB, InsertPt);
+ SetInstDebugLocation(I);
+ return I;
+ }
+
+ /// No-op overload to handle constants.
+ Constant *Insert(Constant *C, const Twine& = "") const {
+ return C;
+ }
+
+ Value *Insert(Value *V, const Twine &Name = "") const {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return Insert(I, Name);
+ assert(isa<Constant>(V));
+ return V;
+ }
+
//===--------------------------------------------------------------------===//
// Builder configuration methods
//===--------------------------------------------------------------------===//
@@ -215,6 +244,8 @@ public:
/// Get the flags to be applied to created floating point ops
FastMathFlags getFastMathFlags() const { return FMF; }
+ FastMathFlags &getFastMathFlags() { return FMF; }
+
/// Clear the fast-math flags.
void clearFastMathFlags() { FMF.clear(); }
@@ -239,7 +270,7 @@ public:
}
/// Set the rounding mode handling to be used with constrained floating point
- void setDefaultConstrainedRounding(fp::RoundingMode NewRounding) {
+ void setDefaultConstrainedRounding(RoundingMode NewRounding) {
DefaultConstrainedRounding = NewRounding;
}
@@ -249,7 +280,7 @@ public:
}
/// Get the rounding mode handling used with constrained floating point
- fp::RoundingMode getDefaultConstrainedRounding() {
+ RoundingMode getDefaultConstrainedRounding() {
return DefaultConstrainedRounding;
}
@@ -267,6 +298,10 @@ public:
I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP);
}
+ void setDefaultOperandBundles(ArrayRef<OperandBundleDef> OpBundles) {
+ DefaultOperandBundles = OpBundles;
+ }
+
//===--------------------------------------------------------------------===//
// RAII helpers.
//===--------------------------------------------------------------------===//
@@ -299,10 +334,16 @@ public:
IRBuilderBase &Builder;
FastMathFlags FMF;
MDNode *FPMathTag;
+ bool IsFPConstrained;
+ fp::ExceptionBehavior DefaultConstrainedExcept;
+ RoundingMode DefaultConstrainedRounding;
public:
FastMathFlagGuard(IRBuilderBase &B)
- : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag) {}
+ : Builder(B), FMF(B.FMF), FPMathTag(B.DefaultFPMathTag),
+ IsFPConstrained(B.IsFPConstrained),
+ DefaultConstrainedExcept(B.DefaultConstrainedExcept),
+ DefaultConstrainedRounding(B.DefaultConstrainedRounding) {}
FastMathFlagGuard(const FastMathFlagGuard &) = delete;
FastMathFlagGuard &operator=(const FastMathFlagGuard &) = delete;
@@ -310,9 +351,31 @@ public:
~FastMathFlagGuard() {
Builder.FMF = FMF;
Builder.DefaultFPMathTag = FPMathTag;
+ Builder.IsFPConstrained = IsFPConstrained;
+ Builder.DefaultConstrainedExcept = DefaultConstrainedExcept;
+ Builder.DefaultConstrainedRounding = DefaultConstrainedRounding;
}
};
+ // RAII object that stores the current default operand bundles and restores
+ // them when the object is destroyed.
+ class OperandBundlesGuard {
+ IRBuilderBase &Builder;
+ ArrayRef<OperandBundleDef> DefaultOperandBundles;
+
+ public:
+ OperandBundlesGuard(IRBuilderBase &B)
+ : Builder(B), DefaultOperandBundles(B.DefaultOperandBundles) {}
+
+ OperandBundlesGuard(const OperandBundlesGuard &) = delete;
+ OperandBundlesGuard &operator=(const OperandBundlesGuard &) = delete;
+
+ ~OperandBundlesGuard() {
+ Builder.DefaultOperandBundles = DefaultOperandBundles;
+ }
+ };
+
+
//===--------------------------------------------------------------------===//
// Miscellaneous creation methods.
//===--------------------------------------------------------------------===//
@@ -414,6 +477,11 @@ public:
return Type::getHalfTy(Context);
}
+ /// Fetch the type representing a 16-bit brain floating point value.
+ Type *getBFloatTy() {
+ return Type::getBFloatTy(Context);
+ }
+
/// Fetch the type representing a 32-bit floating point value.
Type *getFloatTy() {
return Type::getFloatTy(Context);
@@ -468,19 +536,6 @@ public:
/// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
/// specified, it will be added to the instruction. Likewise with alias.scope
/// and noalias tags.
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes Align instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateElementUnorderedAtomicMemSet(
- Value *Ptr, Value *Val, uint64_t Size, unsigned Alignment,
- uint32_t ElementSize, MDNode *TBAATag = nullptr,
- MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),
- "Use the version that takes Align instead of this one") {
- return CreateElementUnorderedAtomicMemSet(Ptr, Val, getInt64(Size),
- Align(Alignment), ElementSize,
- TBAATag, ScopeTag, NoAliasTag);
- }
-
CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val,
uint64_t Size, Align Alignment,
uint32_t ElementSize,
@@ -492,19 +547,6 @@ public:
TBAATag, ScopeTag, NoAliasTag);
}
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes Align instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateElementUnorderedAtomicMemSet(
- Value *Ptr, Value *Val, Value *Size, unsigned Alignment,
- uint32_t ElementSize, MDNode *TBAATag = nullptr,
- MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),
- "Use the version that takes Align instead of this one") {
- return CreateElementUnorderedAtomicMemSet(Ptr, Val, Size, Align(Alignment),
- ElementSize, TBAATag, ScopeTag,
- NoAliasTag);
- }
-
CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val,
Value *Size, Align Alignment,
uint32_t ElementSize,
@@ -517,21 +559,6 @@ public:
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is
/// specified, it will be added to the instruction. Likewise with alias.scope
/// and noalias tags.
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src,
- unsigned SrcAlign, uint64_t Size,
- bool isVolatile = false, MDNode *TBAATag = nullptr,
- MDNode *TBAAStructTag = nullptr,
- MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr),
- "Use the version that takes MaybeAlign instead") {
- return CreateMemCpy(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign),
- getInt64(Size), isVolatile, TBAATag, TBAAStructTag,
- ScopeTag, NoAliasTag);
- }
-
CallInst *CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, uint64_t Size,
bool isVolatile = false, MDNode *TBAATag = nullptr,
@@ -543,16 +570,6 @@ public:
NoAliasTag);
}
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src,
- unsigned SrcAlign, Value *Size,
- bool isVolatile = false, MDNode *TBAATag = nullptr,
- MDNode *TBAAStructTag = nullptr,
- MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr),
- "Use the version that takes MaybeAlign instead");
CallInst *CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, Value *Size,
bool isVolatile = false, MDNode *TBAATag = nullptr,
@@ -560,6 +577,9 @@ public:
MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = nullptr);
+ CallInst *CreateMemCpyInline(Value *Dst, MaybeAlign DstAlign, Value *Src,
+ MaybeAlign SrcAlign, Value *Size);
+
/// Create and insert an element unordered-atomic memcpy between the
/// specified pointers.
///
@@ -569,39 +589,37 @@ public:
/// specified, it will be added to the instruction. Likewise with alias.scope
/// and noalias tags.
CallInst *CreateElementUnorderedAtomicMemCpy(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
- uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr,
- MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr) {
- return CreateElementUnorderedAtomicMemCpy(
- Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag,
- TBAAStructTag, ScopeTag, NoAliasTag);
- }
-
- CallInst *CreateElementUnorderedAtomicMemCpy(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
+ Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
uint32_t ElementSize, MDNode *TBAATag = nullptr,
MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr,
MDNode *NoAliasTag = nullptr);
- /// Create and insert a memmove between the specified
- /// pointers.
- ///
- /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
- /// specified, it will be added to the instruction. Likewise with alias.scope
- /// and noalias tags.
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateMemMove(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
- uint64_t Size, bool isVolatile = false, MDNode *TBAATag = nullptr,
- MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),
- "Use the version that takes MaybeAlign") {
- return CreateMemMove(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign),
- getInt64(Size), isVolatile, TBAATag, ScopeTag,
- NoAliasTag);
+ LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, unsigned DstAlign, Value *Src,
+ unsigned SrcAlign, uint64_t Size,
+ uint32_t ElementSize, MDNode *TBAATag = nullptr,
+ MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr,
+ MDNode *NoAliasTag = nullptr),
+ "Use the version that takes Align instead") {
+ return CreateElementUnorderedAtomicMemCpy(
+ Dst, Align(DstAlign), Src, Align(SrcAlign), getInt64(Size), ElementSize,
+ TBAATag, TBAAStructTag, ScopeTag, NoAliasTag);
+ }
+
+ LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemCpy(
+ Value *Dst, unsigned DstAlign, Value *Src,
+ unsigned SrcAlign, Value *Size,
+ uint32_t ElementSize, MDNode *TBAATag = nullptr,
+ MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr,
+ MDNode *NoAliasTag = nullptr),
+ "Use the version that takes Align instead") {
+ return CreateElementUnorderedAtomicMemCpy(
+ Dst, Align(DstAlign), Src, Align(SrcAlign), Size, ElementSize, TBAATag,
+ TBAAStructTag, ScopeTag, NoAliasTag);
}
+
CallInst *CreateMemMove(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, uint64_t Size,
bool isVolatile = false, MDNode *TBAATag = nullptr,
@@ -610,17 +628,7 @@ public:
return CreateMemMove(Dst, DstAlign, Src, SrcAlign, getInt64(Size),
isVolatile, TBAATag, ScopeTag, NoAliasTag);
}
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LLVM_ATTRIBUTE_DEPRECATED(
- CallInst *CreateMemMove(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
- Value *Size, bool isVolatile = false, MDNode *TBAATag = nullptr,
- MDNode *ScopeTag = nullptr, MDNode *NoAliasTag = nullptr),
- "Use the version that takes MaybeAlign") {
- return CreateMemMove(Dst, MaybeAlign(DstAlign), Src, MaybeAlign(SrcAlign),
- Size, isVolatile, TBAATag, ScopeTag, NoAliasTag);
- }
+
CallInst *CreateMemMove(Value *Dst, MaybeAlign DstAlign, Value *Src,
MaybeAlign SrcAlign, Value *Size,
bool isVolatile = false, MDNode *TBAATag = nullptr,
@@ -637,21 +645,37 @@ public:
/// specified, it will be added to the instruction. Likewise with alias.scope
/// and noalias tags.
CallInst *CreateElementUnorderedAtomicMemMove(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign,
- uint64_t Size, uint32_t ElementSize, MDNode *TBAATag = nullptr,
+ Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
+ uint32_t ElementSize, MDNode *TBAATag = nullptr,
MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr) {
+ MDNode *NoAliasTag = nullptr);
+
+ LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemMove(
+ Value *Dst, unsigned DstAlign, Value *Src,
+ unsigned SrcAlign, uint64_t Size,
+ uint32_t ElementSize, MDNode *TBAATag = nullptr,
+ MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr,
+ MDNode *NoAliasTag = nullptr),
+ "Use the version that takes Align instead") {
return CreateElementUnorderedAtomicMemMove(
- Dst, DstAlign, Src, SrcAlign, getInt64(Size), ElementSize, TBAATag,
+ Dst, Align(DstAlign), Src, Align(SrcAlign), getInt64(Size), ElementSize,
+ TBAATag, TBAAStructTag, ScopeTag, NoAliasTag);
+ }
+
+ LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateElementUnorderedAtomicMemMove(
+ Value *Dst, unsigned DstAlign, Value *Src,
+ unsigned SrcAlign, Value *Size,
+ uint32_t ElementSize, MDNode *TBAATag = nullptr,
+ MDNode *TBAAStructTag = nullptr,
+ MDNode *ScopeTag = nullptr,
+ MDNode *NoAliasTag = nullptr),
+ "Use the version that takes Align instead") {
+ return CreateElementUnorderedAtomicMemMove(
+ Dst, Align(DstAlign), Src, Align(SrcAlign), Size, ElementSize, TBAATag,
TBAAStructTag, ScopeTag, NoAliasTag);
}
- CallInst *CreateElementUnorderedAtomicMemMove(
- Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, Value *Size,
- uint32_t ElementSize, MDNode *TBAATag = nullptr,
- MDNode *TBAAStructTag = nullptr, MDNode *ScopeTag = nullptr,
- MDNode *NoAliasTag = nullptr);
-
/// Create a vector fadd reduction intrinsic of the source vector.
/// The first parameter is a scalar accumulator value for ordered reductions.
CallInst *CreateFAddReduce(Value *Acc, Value *Src);
@@ -707,33 +731,69 @@ public:
CallInst *CreateInvariantStart(Value *Ptr, ConstantInt *Size = nullptr);
/// Create a call to Masked Load intrinsic
- CallInst *CreateMaskedLoad(Value *Ptr, unsigned Align, Value *Mask,
+ LLVM_ATTRIBUTE_DEPRECATED(
+ CallInst *CreateMaskedLoad(Value *Ptr, unsigned Alignment, Value *Mask,
+ Value *PassThru = nullptr,
+ const Twine &Name = ""),
+ "Use the version that takes Align instead") {
+ return CreateMaskedLoad(Ptr, assumeAligned(Alignment), Mask, PassThru,
+ Name);
+ }
+ CallInst *CreateMaskedLoad(Value *Ptr, Align Alignment, Value *Mask,
Value *PassThru = nullptr, const Twine &Name = "");
/// Create a call to Masked Store intrinsic
- CallInst *CreateMaskedStore(Value *Val, Value *Ptr, unsigned Align,
+ LLVM_ATTRIBUTE_DEPRECATED(CallInst *CreateMaskedStore(Value *Val, Value *Ptr,
+ unsigned Alignment,
+ Value *Mask),
+ "Use the version that takes Align instead") {
+ return CreateMaskedStore(Val, Ptr, assumeAligned(Alignment), Mask);
+ }
+
+ CallInst *CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment,
Value *Mask);
/// Create a call to Masked Gather intrinsic
- CallInst *CreateMaskedGather(Value *Ptrs, unsigned Align,
- Value *Mask = nullptr,
- Value *PassThru = nullptr,
- const Twine& Name = "");
+ LLVM_ATTRIBUTE_DEPRECATED(
+ CallInst *CreateMaskedGather(Value *Ptrs, unsigned Alignment,
+ Value *Mask = nullptr,
+ Value *PassThru = nullptr,
+ const Twine &Name = ""),
+ "Use the version that takes Align instead") {
+ return CreateMaskedGather(Ptrs, Align(Alignment), Mask, PassThru, Name);
+ }
+
+ /// Create a call to Masked Gather intrinsic
+ CallInst *CreateMaskedGather(Value *Ptrs, Align Alignment,
+ Value *Mask = nullptr, Value *PassThru = nullptr,
+ const Twine &Name = "");
/// Create a call to Masked Scatter intrinsic
- CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, unsigned Align,
+ LLVM_ATTRIBUTE_DEPRECATED(
+ CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, unsigned Alignment,
+ Value *Mask = nullptr),
+ "Use the version that takes Align instead") {
+ return CreateMaskedScatter(Val, Ptrs, Align(Alignment), Mask);
+ }
+
+ /// Create a call to Masked Scatter intrinsic
+ CallInst *CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment,
Value *Mask = nullptr);
/// Create an assume intrinsic call that allows the optimizer to
/// assume that the provided condition will be true.
- CallInst *CreateAssumption(Value *Cond);
+ ///
+ /// The optional argument \p OpBundles specifies operand bundles that are
+ /// added to the call instruction.
+ CallInst *CreateAssumption(Value *Cond,
+ ArrayRef<OperandBundleDef> OpBundles = llvm::None);
/// Create a call to the experimental.gc.statepoint intrinsic to
/// start a new statepoint sequence.
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee,
ArrayRef<Value *> CallArgs,
- ArrayRef<Value *> DeoptArgs,
+ Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs,
const Twine &Name = "");
@@ -742,8 +802,8 @@ public:
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, uint32_t Flags,
ArrayRef<Use> CallArgs,
- ArrayRef<Use> TransitionArgs,
- ArrayRef<Use> DeoptArgs,
+ Optional<ArrayRef<Use>> TransitionArgs,
+ Optional<ArrayRef<Use>> DeoptArgs,
ArrayRef<Value *> GCArgs,
const Twine &Name = "");
@@ -752,7 +812,7 @@ public:
/// .get()'ed to get the Value pointer.
CallInst *CreateGCStatepointCall(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualCallee, ArrayRef<Use> CallArgs,
- ArrayRef<Value *> DeoptArgs,
+ Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs,
const Twine &Name = "");
@@ -762,7 +822,7 @@ public:
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualInvokee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, ArrayRef<Value *> InvokeArgs,
- ArrayRef<Value *> DeoptArgs,
+ Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name = "");
/// Create an invoke to the experimental.gc.statepoint intrinsic to
@@ -770,8 +830,8 @@ public:
InvokeInst *CreateGCStatepointInvoke(
uint64_t ID, uint32_t NumPatchBytes, Value *ActualInvokee,
BasicBlock *NormalDest, BasicBlock *UnwindDest, uint32_t Flags,
- ArrayRef<Use> InvokeArgs, ArrayRef<Use> TransitionArgs,
- ArrayRef<Use> DeoptArgs, ArrayRef<Value *> GCArgs,
+ ArrayRef<Use> InvokeArgs, Optional<ArrayRef<Use>> TransitionArgs,
+ Optional<ArrayRef<Use>> DeoptArgs, ArrayRef<Value *> GCArgs,
const Twine &Name = "");
// Convenience function for the common case when CallArgs are filled in using
@@ -781,7 +841,7 @@ public:
CreateGCStatepointInvoke(uint64_t ID, uint32_t NumPatchBytes,
Value *ActualInvokee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, ArrayRef<Use> InvokeArgs,
- ArrayRef<Value *> DeoptArgs,
+ Optional<ArrayRef<Value *>> DeoptArgs,
ArrayRef<Value *> GCArgs, const Twine &Name = "");
/// Create a call to the experimental.gc.result intrinsic to extract
@@ -845,85 +905,6 @@ private:
const Twine &Name = "");
Value *getCastedInt8PtrValue(Value *Ptr);
-};
-
-/// This provides a uniform API for creating instructions and inserting
-/// them into a basic block: either at the end of a BasicBlock, or at a specific
-/// iterator location in a block.
-///
-/// Note that the builder does not expose the full generality of LLVM
-/// instructions. For access to extra instruction properties, use the mutators
-/// (e.g. setVolatile) on the instructions after they have been
-/// created. Convenience state exists to specify fast-math flags and fp-math
-/// tags.
-///
-/// The first template argument specifies a class to use for creating constants.
-/// This defaults to creating minimally folded constants. The second template
-/// argument allows clients to specify custom insertion hooks that are called on
-/// every newly created insertion.
-template <typename T = ConstantFolder,
- typename Inserter = IRBuilderDefaultInserter>
-class IRBuilder : public IRBuilderBase, public Inserter {
- T Folder;
-
-public:
- IRBuilder(LLVMContext &C, const T &F, Inserter I = Inserter(),
- MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(C, FPMathTag, OpBundles), Inserter(std::move(I)),
- Folder(F) {}
-
- explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(C, FPMathTag, OpBundles) {}
-
- explicit IRBuilder(BasicBlock *TheBB, const T &F, MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) {
- SetInsertPoint(TheBB);
- }
-
- explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
- SetInsertPoint(TheBB);
- }
-
- explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(IP->getContext(), FPMathTag, OpBundles) {
- SetInsertPoint(IP);
- }
-
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T &F,
- MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles), Folder(F) {
- SetInsertPoint(TheBB, IP);
- }
-
- IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
- MDNode *FPMathTag = nullptr,
- ArrayRef<OperandBundleDef> OpBundles = None)
- : IRBuilderBase(TheBB->getContext(), FPMathTag, OpBundles) {
- SetInsertPoint(TheBB, IP);
- }
-
- /// Get the constant folder being used.
- const T &getFolder() { return Folder; }
-
- /// Insert and return the specified instruction.
- template<typename InstTy>
- InstTy *Insert(InstTy *I, const Twine &Name = "") const {
- this->InsertHelper(I, Name, BB, InsertPt);
- this->SetInstDebugLocation(I);
- return I;
- }
-
- /// No-op overload to handle constants.
- Constant *Insert(Constant *C, const Twine& = "") const {
- return C;
- }
//===--------------------------------------------------------------------===//
// Instruction creation methods: Terminators
@@ -1045,28 +1026,6 @@ public:
NormalDest, UnwindDest, Args, Name);
}
- // Deprecated [opaque pointer types]
- InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> OpBundles,
- const Twine &Name = "") {
- return CreateInvoke(
- cast<FunctionType>(
- cast<PointerType>(Callee->getType())->getElementType()),
- Callee, NormalDest, UnwindDest, Args, OpBundles, Name);
- }
-
- // Deprecated [opaque pointer types]
- InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
- BasicBlock *UnwindDest,
- ArrayRef<Value *> Args = None,
- const Twine &Name = "") {
- return CreateInvoke(
- cast<FunctionType>(
- cast<PointerType>(Callee->getType())->getElementType()),
- Callee, NormalDest, UnwindDest, Args, Name);
- }
-
/// \brief Create a callbr instruction.
CallBrInst *CreateCallBr(FunctionType *Ty, Value *Callee,
BasicBlock *DefaultDest,
@@ -1169,8 +1128,8 @@ private:
return (LC && RC) ? Insert(Folder.CreateBinOp(Opc, LC, RC), Name) : nullptr;
}
- Value *getConstrainedFPRounding(Optional<fp::RoundingMode> Rounding) {
- fp::RoundingMode UseRounding = DefaultConstrainedRounding;
+ Value *getConstrainedFPRounding(Optional<RoundingMode> Rounding) {
+ RoundingMode UseRounding = DefaultConstrainedRounding;
if (Rounding.hasValue())
UseRounding = Rounding.getValue();
@@ -1561,21 +1520,8 @@ public:
CallInst *CreateConstrainedFPBinOp(
Intrinsic::ID ID, Value *L, Value *R, Instruction *FMFSource = nullptr,
const Twine &Name = "", MDNode *FPMathTag = nullptr,
- Optional<fp::RoundingMode> Rounding = None,
- Optional<fp::ExceptionBehavior> Except = None) {
- Value *RoundingV = getConstrainedFPRounding(Rounding);
- Value *ExceptV = getConstrainedFPExcept(Except);
-
- FastMathFlags UseFMF = FMF;
- if (FMFSource)
- UseFMF = FMFSource->getFastMathFlags();
-
- CallInst *C = CreateIntrinsic(ID, {L->getType()},
- {L, R, RoundingV, ExceptV}, nullptr, Name);
- setConstrainedFPCallAttr(C);
- setFPAttrs(C, FPMathTag, UseFMF);
- return C;
- }
+ Optional<RoundingMode> Rounding = None,
+ Optional<fp::ExceptionBehavior> Except = None);
Value *CreateNeg(Value *V, const Twine &Name = "",
bool HasNUW = false, bool HasNSW = false) {
@@ -1634,20 +1580,7 @@ public:
/// Create either a UnaryOperator or BinaryOperator depending on \p Opc.
/// Correct number of operands must be passed accordingly.
Value *CreateNAryOp(unsigned Opc, ArrayRef<Value *> Ops,
- const Twine &Name = "",
- MDNode *FPMathTag = nullptr) {
- if (Instruction::isBinaryOp(Opc)) {
- assert(Ops.size() == 2 && "Invalid number of operands!");
- return CreateBinOp(static_cast<Instruction::BinaryOps>(Opc),
- Ops[0], Ops[1], Name, FPMathTag);
- }
- if (Instruction::isUnaryOp(Opc)) {
- assert(Ops.size() == 1 && "Invalid number of operands!");
- return CreateUnOp(static_cast<Instruction::UnaryOps>(Opc),
- Ops[0], Name, FPMathTag);
- }
- llvm_unreachable("Unexpected opcode!");
- }
+ const Twine &Name = "", MDNode *FPMathTag = nullptr);
//===--------------------------------------------------------------------===//
// Instruction creation methods: Memory Instructions
@@ -1655,28 +1588,32 @@ public:
AllocaInst *CreateAlloca(Type *Ty, unsigned AddrSpace,
Value *ArraySize = nullptr, const Twine &Name = "") {
- return Insert(new AllocaInst(Ty, AddrSpace, ArraySize), Name);
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align AllocaAlign = DL.getPrefTypeAlign(Ty);
+ return Insert(new AllocaInst(Ty, AddrSpace, ArraySize, AllocaAlign), Name);
}
AllocaInst *CreateAlloca(Type *Ty, Value *ArraySize = nullptr,
const Twine &Name = "") {
- const DataLayout &DL = BB->getParent()->getParent()->getDataLayout();
- return Insert(new AllocaInst(Ty, DL.getAllocaAddrSpace(), ArraySize), Name);
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align AllocaAlign = DL.getPrefTypeAlign(Ty);
+ unsigned AddrSpace = DL.getAllocaAddrSpace();
+ return Insert(new AllocaInst(Ty, AddrSpace, ArraySize, AllocaAlign), Name);
}
/// Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of
/// converting the string to 'bool' for the isVolatile parameter.
LoadInst *CreateLoad(Type *Ty, Value *Ptr, const char *Name) {
- return Insert(new LoadInst(Ty, Ptr), Name);
+ return CreateAlignedLoad(Ty, Ptr, MaybeAlign(), Name);
}
LoadInst *CreateLoad(Type *Ty, Value *Ptr, const Twine &Name = "") {
- return Insert(new LoadInst(Ty, Ptr), Name);
+ return CreateAlignedLoad(Ty, Ptr, MaybeAlign(), Name);
}
LoadInst *CreateLoad(Type *Ty, Value *Ptr, bool isVolatile,
const Twine &Name = "") {
- return Insert(new LoadInst(Ty, Ptr, Twine(), isVolatile), Name);
+ return CreateAlignedLoad(Ty, Ptr, MaybeAlign(), isVolatile, Name);
}
// Deprecated [opaque pointer types]
@@ -1696,65 +1633,71 @@ public:
}
StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
- return Insert(new StoreInst(Val, Ptr, isVolatile));
+ return CreateAlignedStore(Val, Ptr, MaybeAlign(), isVolatile);
}
- /// Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")'
- /// correctly, instead of converting the string to 'bool' for the isVolatile
- /// parameter.
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
- const char *Name) {
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr,
+ unsigned Align,
+ const char *Name),
+ "Use the version that takes NaybeAlign instead") {
return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), Name);
}
LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align,
const char *Name) {
- LoadInst *LI = CreateLoad(Ty, Ptr, Name);
- LI->setAlignment(Align);
- return LI;
+ return CreateAlignedLoad(Ty, Ptr, Align, /*isVolatile*/false, Name);
}
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
- const Twine &Name = "") {
+
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr,
+ unsigned Align,
+ const Twine &Name = ""),
+ "Use the version that takes MaybeAlign instead") {
return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), Name);
}
LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align,
const Twine &Name = "") {
- LoadInst *LI = CreateLoad(Ty, Ptr, Name);
- LI->setAlignment(Align);
- return LI;
+ return CreateAlignedLoad(Ty, Ptr, Align, /*isVolatile*/false, Name);
}
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, unsigned Align,
- bool isVolatile, const Twine &Name = "") {
+
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr,
+ unsigned Align,
+ bool isVolatile,
+ const Twine &Name = ""),
+ "Use the version that takes MaybeAlign instead") {
return CreateAlignedLoad(Ty, Ptr, MaybeAlign(Align), isVolatile, Name);
}
LoadInst *CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align,
bool isVolatile, const Twine &Name = "") {
- LoadInst *LI = CreateLoad(Ty, Ptr, isVolatile, Name);
- LI->setAlignment(Align);
- return LI;
+ if (!Align) {
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align = DL.getABITypeAlign(Ty);
+ }
+ return Insert(new LoadInst(Ty, Ptr, Twine(), isVolatile, *Align), Name);
}
// Deprecated [opaque pointer types]
- LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) {
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Value *Ptr,
+ unsigned Align,
+ const char *Name),
+ "Use the version that takes MaybeAlign instead") {
return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr,
- Align, Name);
+ MaybeAlign(Align), Name);
}
// Deprecated [opaque pointer types]
- LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align,
- const Twine &Name = "") {
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Value *Ptr,
+ unsigned Align,
+ const Twine &Name = ""),
+ "Use the version that takes MaybeAlign instead") {
return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr,
- Align, Name);
+ MaybeAlign(Align), Name);
}
// Deprecated [opaque pointer types]
- LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, bool isVolatile,
- const Twine &Name = "") {
+ LLVM_ATTRIBUTE_DEPRECATED(LoadInst *CreateAlignedLoad(Value *Ptr,
+ unsigned Align,
+ bool isVolatile,
+ const Twine &Name = ""),
+ "Use the version that takes MaybeAlign instead") {
return CreateAlignedLoad(Ptr->getType()->getPointerElementType(), Ptr,
- Align, isVolatile, Name);
+ MaybeAlign(Align), isVolatile, Name);
}
// Deprecated [opaque pointer types]
LoadInst *CreateAlignedLoad(Value *Ptr, MaybeAlign Align, const char *Name) {
@@ -1774,15 +1717,19 @@ public:
Align, isVolatile, Name);
}
- StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align,
- bool isVolatile = false) {
- StoreInst *SI = CreateStore(Val, Ptr, isVolatile);
- SI->setAlignment(MaybeAlign(Align));
- return SI;
+ LLVM_ATTRIBUTE_DEPRECATED(
+ StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align,
+ bool isVolatile = false),
+ "Use the version that takes MaybeAlign instead") {
+ return CreateAlignedStore(Val, Ptr, MaybeAlign(Align), isVolatile);
}
StoreInst *CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align,
bool isVolatile = false) {
- return CreateAlignedStore(Val, Ptr, Align ? Align->value() : 0, isVolatile);
+ if (!Align) {
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align = DL.getABITypeAlign(Val->getType());
+ }
+ return Insert(new StoreInst(Val, Ptr, isVolatile, *Align));
}
FenceInst *CreateFence(AtomicOrdering Ordering,
SyncScope::ID SSID = SyncScope::System,
@@ -1790,19 +1737,21 @@ public:
return Insert(new FenceInst(Context, Ordering, SSID), Name);
}
- AtomicCmpXchgInst *
- CreateAtomicCmpXchg(Value *Ptr, Value *Cmp, Value *New,
- AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SyncScope::ID SSID = SyncScope::System) {
- return Insert(new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering,
- FailureOrdering, SSID));
+ AtomicCmpXchgInst *CreateAtomicCmpXchg(
+ Value *Ptr, Value *Cmp, Value *New, AtomicOrdering SuccessOrdering,
+ AtomicOrdering FailureOrdering, SyncScope::ID SSID = SyncScope::System) {
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align Alignment(DL.getTypeStoreSize(New->getType()));
+ return Insert(new AtomicCmpXchgInst(
+ Ptr, Cmp, New, Alignment, SuccessOrdering, FailureOrdering, SSID));
}
AtomicRMWInst *CreateAtomicRMW(AtomicRMWInst::BinOp Op, Value *Ptr, Value *Val,
AtomicOrdering Ordering,
SyncScope::ID SSID = SyncScope::System) {
- return Insert(new AtomicRMWInst(Op, Ptr, Val, Ordering, SSID));
+ const DataLayout &DL = BB->getModule()->getDataLayout();
+ Align Alignment(DL.getTypeStoreSize(Val->getType()));
+ return Insert(new AtomicRMWInst(Op, Ptr, Val, Alignment, Ordering, SSID));
}
Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
@@ -2200,39 +2149,8 @@ public:
Intrinsic::ID ID, Value *V, Type *DestTy,
Instruction *FMFSource = nullptr, const Twine &Name = "",
MDNode *FPMathTag = nullptr,
- Optional<fp::RoundingMode> Rounding = None,
- Optional<fp::ExceptionBehavior> Except = None) {
- Value *ExceptV = getConstrainedFPExcept(Except);
-
- FastMathFlags UseFMF = FMF;
- if (FMFSource)
- UseFMF = FMFSource->getFastMathFlags();
-
- CallInst *C;
- bool HasRoundingMD = false;
- switch (ID) {
- default:
- break;
-#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
- case Intrinsic::INTRINSIC: \
- HasRoundingMD = ROUND_MODE; \
- break;
-#include "llvm/IR/ConstrainedOps.def"
- }
- if (HasRoundingMD) {
- Value *RoundingV = getConstrainedFPRounding(Rounding);
- C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, RoundingV, ExceptV},
- nullptr, Name);
- } else
- C = CreateIntrinsic(ID, {DestTy, V->getType()}, {V, ExceptV}, nullptr,
- Name);
-
- setConstrainedFPCallAttr(C);
-
- if (isa<FPMathOperator>(C))
- setFPAttrs(C, FPMathTag, UseFMF);
- return C;
- }
+ Optional<RoundingMode> Rounding = None,
+ Optional<fp::ExceptionBehavior> Except = None);
// Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
// compile time error, instead of converting the string to bool for the
@@ -2366,14 +2284,14 @@ public:
// Note that this differs from CreateFCmpS only if IsFPConstrained is true.
Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPCmp(Intrinsic::experimental_constrained_fcmp,
- P, LHS, RHS, Name);
+ return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, false);
+ }
- if (auto *LC = dyn_cast<Constant>(LHS))
- if (auto *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFCmp(P, LC, RC), Name);
- return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
+ Value *CreateCmp(CmpInst::Predicate Pred, Value *LHS, Value *RHS,
+ const Twine &Name = "", MDNode *FPMathTag = nullptr) {
+ return CmpInst::isFPPredicate(Pred)
+ ? CreateFCmp(Pred, LHS, RHS, Name, FPMathTag)
+ : CreateICmp(Pred, LHS, RHS, Name);
}
// Create a signaling floating-point comparison (i.e. one that raises an FP
@@ -2381,28 +2299,19 @@ public:
// Note that this differs from CreateFCmp only if IsFPConstrained is true.
Value *CreateFCmpS(CmpInst::Predicate P, Value *LHS, Value *RHS,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- if (IsFPConstrained)
- return CreateConstrainedFPCmp(Intrinsic::experimental_constrained_fcmps,
- P, LHS, RHS, Name);
-
- if (auto *LC = dyn_cast<Constant>(LHS))
- if (auto *RC = dyn_cast<Constant>(RHS))
- return Insert(Folder.CreateFCmp(P, LC, RC), Name);
- return Insert(setFPAttrs(new FCmpInst(P, LHS, RHS), FPMathTag, FMF), Name);
+ return CreateFCmpHelper(P, LHS, RHS, Name, FPMathTag, true);
}
+private:
+ // Helper routine to create either a signaling or a quiet FP comparison.
+ Value *CreateFCmpHelper(CmpInst::Predicate P, Value *LHS, Value *RHS,
+ const Twine &Name, MDNode *FPMathTag,
+ bool IsSignaling);
+
+public:
CallInst *CreateConstrainedFPCmp(
Intrinsic::ID ID, CmpInst::Predicate P, Value *L, Value *R,
- const Twine &Name = "",
- Optional<fp::ExceptionBehavior> Except = None) {
- Value *PredicateV = getConstrainedFPPredicate(P);
- Value *ExceptV = getConstrainedFPExcept(Except);
-
- CallInst *C = CreateIntrinsic(ID, {L->getType()},
- {L, R, PredicateV, ExceptV}, nullptr, Name);
- setConstrainedFPCallAttr(C);
- return C;
- }
+ const Twine &Name = "", Optional<fp::ExceptionBehavior> Except = None);
//===--------------------------------------------------------------------===//
// Instruction creation methods: Other Instructions
@@ -2451,67 +2360,13 @@ public:
OpBundles, Name, FPMathTag);
}
- // Deprecated [opaque pointer types]
- CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args = None,
- const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- return CreateCall(
- cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee,
- Args, Name, FPMathTag);
- }
-
- // Deprecated [opaque pointer types]
- CallInst *CreateCall(Value *Callee, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> OpBundles,
- const Twine &Name = "", MDNode *FPMathTag = nullptr) {
- return CreateCall(
- cast<FunctionType>(Callee->getType()->getPointerElementType()), Callee,
- Args, OpBundles, Name, FPMathTag);
- }
-
CallInst *CreateConstrainedFPCall(
Function *Callee, ArrayRef<Value *> Args, const Twine &Name = "",
- Optional<fp::RoundingMode> Rounding = None,
- Optional<fp::ExceptionBehavior> Except = None) {
- llvm::SmallVector<Value *, 6> UseArgs;
-
- for (auto *OneArg : Args)
- UseArgs.push_back(OneArg);
- bool HasRoundingMD = false;
- switch (Callee->getIntrinsicID()) {
- default:
- break;
-#define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC, DAGN) \
- case Intrinsic::INTRINSIC: \
- HasRoundingMD = ROUND_MODE; \
- break;
-#include "llvm/IR/ConstrainedOps.def"
- }
- if (HasRoundingMD)
- UseArgs.push_back(getConstrainedFPRounding(Rounding));
- UseArgs.push_back(getConstrainedFPExcept(Except));
-
- CallInst *C = CreateCall(Callee, UseArgs, Name);
- setConstrainedFPCallAttr(C);
- return C;
- }
+ Optional<RoundingMode> Rounding = None,
+ Optional<fp::ExceptionBehavior> Except = None);
Value *CreateSelect(Value *C, Value *True, Value *False,
- const Twine &Name = "", Instruction *MDFrom = nullptr) {
- if (auto *CC = dyn_cast<Constant>(C))
- if (auto *TC = dyn_cast<Constant>(True))
- if (auto *FC = dyn_cast<Constant>(False))
- return Insert(Folder.CreateSelect(CC, TC, FC), Name);
-
- SelectInst *Sel = SelectInst::Create(C, True, False);
- if (MDFrom) {
- MDNode *Prof = MDFrom->getMetadata(LLVMContext::MD_prof);
- MDNode *Unpred = MDFrom->getMetadata(LLVMContext::MD_unpredictable);
- Sel = addBranchMetadata(Sel, Prof, Unpred);
- }
- if (isa<FPMathOperator>(Sel))
- setFPAttrs(Sel, nullptr /* MDNode* */, FMF);
- return Insert(Sel, Name);
- }
+ const Twine &Name = "", Instruction *MDFrom = nullptr);
VAArgInst *CreateVAArg(Value *List, Type *Ty, const Twine &Name = "") {
return Insert(new VAArgInst(List, Ty), Name);
@@ -2546,17 +2401,27 @@ public:
Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
const Twine &Name = "") {
- if (auto *V1C = dyn_cast<Constant>(V1))
- if (auto *V2C = dyn_cast<Constant>(V2))
- if (auto *MC = dyn_cast<Constant>(Mask))
- return Insert(Folder.CreateShuffleVector(V1C, V2C, MC), Name);
- return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
+ SmallVector<int, 16> IntMask;
+ ShuffleVectorInst::getShuffleMask(cast<Constant>(Mask), IntMask);
+ return CreateShuffleVector(V1, V2, IntMask, Name);
+ }
+
+ LLVM_ATTRIBUTE_DEPRECATED(Value *CreateShuffleVector(Value *V1, Value *V2,
+ ArrayRef<uint32_t> Mask,
+ const Twine &Name = ""),
+ "Pass indices as 'int' instead") {
+ SmallVector<int, 16> IntMask;
+ IntMask.assign(Mask.begin(), Mask.end());
+ return CreateShuffleVector(V1, V2, IntMask, Name);
}
- Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<uint32_t> IntMask,
+ /// See class ShuffleVectorInst for a description of the mask representation.
+ Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<int> Mask,
const Twine &Name = "") {
- Value *Mask = ConstantDataVector::get(Context, IntMask);
- return CreateShuffleVector(V1, V2, Mask, Name);
+ if (auto *V1C = dyn_cast<Constant>(V1))
+ if (auto *V2C = dyn_cast<Constant>(V2))
+ return Insert(Folder.CreateShuffleVector(V1C, V2C, Mask), Name);
+ return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
}
Value *CreateExtractValue(Value *Agg,
@@ -2607,219 +2472,45 @@ public:
/// This is intended to implement C-style pointer subtraction. As such, the
/// pointers must be appropriately aligned for their element types and
/// pointing into the same object.
- Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
- assert(LHS->getType() == RHS->getType() &&
- "Pointer subtraction operand types must match!");
- auto *ArgType = cast<PointerType>(LHS->getType());
- Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
- Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
- Value *Difference = CreateSub(LHS_int, RHS_int);
- return CreateExactSDiv(Difference,
- ConstantExpr::getSizeOf(ArgType->getElementType()),
- Name);
- }
+ Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "");
/// Create a launder.invariant.group intrinsic call. If Ptr type is
/// different from pointer to i8, it's casted to pointer to i8 in the same
/// address space before call and casted back to Ptr type after call.
- Value *CreateLaunderInvariantGroup(Value *Ptr) {
- assert(isa<PointerType>(Ptr->getType()) &&
- "launder.invariant.group only applies to pointers.");
- // FIXME: we could potentially avoid casts to/from i8*.
- auto *PtrType = Ptr->getType();
- auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
- if (PtrType != Int8PtrTy)
- Ptr = CreateBitCast(Ptr, Int8PtrTy);
- Module *M = BB->getParent()->getParent();
- Function *FnLaunderInvariantGroup = Intrinsic::getDeclaration(
- M, Intrinsic::launder_invariant_group, {Int8PtrTy});
-
- assert(FnLaunderInvariantGroup->getReturnType() == Int8PtrTy &&
- FnLaunderInvariantGroup->getFunctionType()->getParamType(0) ==
- Int8PtrTy &&
- "LaunderInvariantGroup should take and return the same type");
-
- CallInst *Fn = CreateCall(FnLaunderInvariantGroup, {Ptr});
-
- if (PtrType != Int8PtrTy)
- return CreateBitCast(Fn, PtrType);
- return Fn;
- }
+ Value *CreateLaunderInvariantGroup(Value *Ptr);
/// \brief Create a strip.invariant.group intrinsic call. If Ptr type is
/// different from pointer to i8, it's casted to pointer to i8 in the same
/// address space before call and casted back to Ptr type after call.
- Value *CreateStripInvariantGroup(Value *Ptr) {
- assert(isa<PointerType>(Ptr->getType()) &&
- "strip.invariant.group only applies to pointers.");
-
- // FIXME: we could potentially avoid casts to/from i8*.
- auto *PtrType = Ptr->getType();
- auto *Int8PtrTy = getInt8PtrTy(PtrType->getPointerAddressSpace());
- if (PtrType != Int8PtrTy)
- Ptr = CreateBitCast(Ptr, Int8PtrTy);
- Module *M = BB->getParent()->getParent();
- Function *FnStripInvariantGroup = Intrinsic::getDeclaration(
- M, Intrinsic::strip_invariant_group, {Int8PtrTy});
-
- assert(FnStripInvariantGroup->getReturnType() == Int8PtrTy &&
- FnStripInvariantGroup->getFunctionType()->getParamType(0) ==
- Int8PtrTy &&
- "StripInvariantGroup should take and return the same type");
-
- CallInst *Fn = CreateCall(FnStripInvariantGroup, {Ptr});
-
- if (PtrType != Int8PtrTy)
- return CreateBitCast(Fn, PtrType);
- return Fn;
- }
+ Value *CreateStripInvariantGroup(Value *Ptr);
/// Return a vector value that contains \arg V broadcasted to \p
/// NumElts elements.
- Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") {
- assert(NumElts > 0 && "Cannot splat to an empty vector!");
-
- // First insert it into an undef vector so we can shuffle it.
- Type *I32Ty = getInt32Ty();
- Value *Undef = UndefValue::get(VectorType::get(V->getType(), NumElts));
- V = CreateInsertElement(Undef, V, ConstantInt::get(I32Ty, 0),
- Name + ".splatinsert");
-
- // Shuffle the value across the desired number of elements.
- Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32Ty, NumElts));
- return CreateShuffleVector(V, Undef, Zeros, Name + ".splat");
- }
+ Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "");
/// Return a value that has been extracted from a larger integer type.
Value *CreateExtractInteger(const DataLayout &DL, Value *From,
IntegerType *ExtractedTy, uint64_t Offset,
- const Twine &Name) {
- auto *IntTy = cast<IntegerType>(From->getType());
- assert(DL.getTypeStoreSize(ExtractedTy) + Offset <=
- DL.getTypeStoreSize(IntTy) &&
- "Element extends past full value");
- uint64_t ShAmt = 8 * Offset;
- Value *V = From;
- if (DL.isBigEndian())
- ShAmt = 8 * (DL.getTypeStoreSize(IntTy) -
- DL.getTypeStoreSize(ExtractedTy) - Offset);
- if (ShAmt) {
- V = CreateLShr(V, ShAmt, Name + ".shift");
- }
- assert(ExtractedTy->getBitWidth() <= IntTy->getBitWidth() &&
- "Cannot extract to a larger integer!");
- if (ExtractedTy != IntTy) {
- V = CreateTrunc(V, ExtractedTy, Name + ".trunc");
- }
- return V;
- }
+ const Twine &Name);
Value *CreatePreserveArrayAccessIndex(Type *ElTy, Value *Base,
unsigned Dimension, unsigned LastIndex,
- MDNode *DbgInfo) {
- assert(isa<PointerType>(Base->getType()) &&
- "Invalid Base ptr type for preserve.array.access.index.");
- auto *BaseType = Base->getType();
-
- Value *LastIndexV = getInt32(LastIndex);
- Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
- SmallVector<Value *, 4> IdxList;
- for (unsigned I = 0; I < Dimension; ++I)
- IdxList.push_back(Zero);
- IdxList.push_back(LastIndexV);
-
- Type *ResultType =
- GetElementPtrInst::getGEPReturnType(ElTy, Base, IdxList);
-
- Module *M = BB->getParent()->getParent();
- Function *FnPreserveArrayAccessIndex = Intrinsic::getDeclaration(
- M, Intrinsic::preserve_array_access_index, {ResultType, BaseType});
-
- Value *DimV = getInt32(Dimension);
- CallInst *Fn =
- CreateCall(FnPreserveArrayAccessIndex, {Base, DimV, LastIndexV});
- if (DbgInfo)
- Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
-
- return Fn;
- }
+ MDNode *DbgInfo);
Value *CreatePreserveUnionAccessIndex(Value *Base, unsigned FieldIndex,
- MDNode *DbgInfo) {
- assert(isa<PointerType>(Base->getType()) &&
- "Invalid Base ptr type for preserve.union.access.index.");
- auto *BaseType = Base->getType();
-
- Module *M = BB->getParent()->getParent();
- Function *FnPreserveUnionAccessIndex = Intrinsic::getDeclaration(
- M, Intrinsic::preserve_union_access_index, {BaseType, BaseType});
-
- Value *DIIndex = getInt32(FieldIndex);
- CallInst *Fn =
- CreateCall(FnPreserveUnionAccessIndex, {Base, DIIndex});
- if (DbgInfo)
- Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
-
- return Fn;
- }
+ MDNode *DbgInfo);
Value *CreatePreserveStructAccessIndex(Type *ElTy, Value *Base,
unsigned Index, unsigned FieldIndex,
- MDNode *DbgInfo) {
- assert(isa<PointerType>(Base->getType()) &&
- "Invalid Base ptr type for preserve.struct.access.index.");
- auto *BaseType = Base->getType();
-
- Value *GEPIndex = getInt32(Index);
- Constant *Zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
- Type *ResultType =
- GetElementPtrInst::getGEPReturnType(ElTy, Base, {Zero, GEPIndex});
-
- Module *M = BB->getParent()->getParent();
- Function *FnPreserveStructAccessIndex = Intrinsic::getDeclaration(
- M, Intrinsic::preserve_struct_access_index, {ResultType, BaseType});
-
- Value *DIIndex = getInt32(FieldIndex);
- CallInst *Fn = CreateCall(FnPreserveStructAccessIndex,
- {Base, GEPIndex, DIIndex});
- if (DbgInfo)
- Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
-
- return Fn;
- }
+ MDNode *DbgInfo);
private:
/// Helper function that creates an assume intrinsic call that
- /// represents an alignment assumption on the provided Ptr, Mask, Type
- /// and Offset. It may be sometimes useful to do some other logic
- /// based on this alignment check, thus it can be stored into 'TheCheck'.
+ /// represents an alignment assumption on the provided pointer \p PtrValue
+ /// with offset \p OffsetValue and alignment value \p AlignValue.
CallInst *CreateAlignmentAssumptionHelper(const DataLayout &DL,
- Value *PtrValue, Value *Mask,
- Type *IntPtrTy, Value *OffsetValue,
- Value **TheCheck) {
- Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
-
- if (OffsetValue) {
- bool IsOffsetZero = false;
- if (const auto *CI = dyn_cast<ConstantInt>(OffsetValue))
- IsOffsetZero = CI->isZero();
-
- if (!IsOffsetZero) {
- if (OffsetValue->getType() != IntPtrTy)
- OffsetValue = CreateIntCast(OffsetValue, IntPtrTy, /*isSigned*/ true,
- "offsetcast");
- PtrIntValue = CreateSub(PtrIntValue, OffsetValue, "offsetptr");
- }
- }
-
- Value *Zero = ConstantInt::get(IntPtrTy, 0);
- Value *MaskedPtr = CreateAnd(PtrIntValue, Mask, "maskedptr");
- Value *InvCond = CreateICmpEQ(MaskedPtr, Zero, "maskcond");
- if (TheCheck)
- *TheCheck = InvCond;
-
- return CreateAssumption(InvCond);
- }
+ Value *PtrValue, Value *AlignValue,
+ Value *OffsetValue);
public:
/// Create an assume intrinsic call that represents an alignment
@@ -2828,23 +2519,9 @@ public:
/// An optional offset can be provided, and if it is provided, the offset
/// must be subtracted from the provided pointer to get the pointer with the
/// specified alignment.
- ///
- /// It may be sometimes useful to do some other logic
- /// based on this alignment check, thus it can be stored into 'TheCheck'.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
unsigned Alignment,
- Value *OffsetValue = nullptr,
- Value **TheCheck = nullptr) {
- assert(isa<PointerType>(PtrValue->getType()) &&
- "trying to create an alignment assumption on a non-pointer?");
- assert(Alignment != 0 && "Invalid Alignment");
- auto *PtrTy = cast<PointerType>(PtrValue->getType());
- Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
-
- Value *Mask = ConstantInt::get(IntPtrTy, Alignment - 1);
- return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
- OffsetValue, TheCheck);
- }
+ Value *OffsetValue = nullptr);
/// Create an assume intrinsic call that represents an alignment
/// assumption on the provided pointer.
@@ -2853,29 +2530,88 @@ public:
/// must be subtracted from the provided pointer to get the pointer with the
/// specified alignment.
///
- /// It may be sometimes useful to do some other logic
- /// based on this alignment check, thus it can be stored into 'TheCheck'.
- ///
/// This overload handles the condition where the Alignment is dependent
/// on an existing value rather than a static value.
CallInst *CreateAlignmentAssumption(const DataLayout &DL, Value *PtrValue,
Value *Alignment,
- Value *OffsetValue = nullptr,
- Value **TheCheck = nullptr) {
- assert(isa<PointerType>(PtrValue->getType()) &&
- "trying to create an alignment assumption on a non-pointer?");
- auto *PtrTy = cast<PointerType>(PtrValue->getType());
- Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
+ Value *OffsetValue = nullptr);
+};
+
+/// This provides a uniform API for creating instructions and inserting
+/// them into a basic block: either at the end of a BasicBlock, or at a specific
+/// iterator location in a block.
+///
+/// Note that the builder does not expose the full generality of LLVM
+/// instructions. For access to extra instruction properties, use the mutators
+/// (e.g. setVolatile) on the instructions after they have been
+/// created. Convenience state exists to specify fast-math flags and fp-math
+/// tags.
+///
+/// The first template argument specifies a class to use for creating constants.
+/// This defaults to creating minimally folded constants. The second template
+/// argument allows clients to specify custom insertion hooks that are called on
+/// every newly created insertion.
+template <typename FolderTy = ConstantFolder,
+ typename InserterTy = IRBuilderDefaultInserter>
+class IRBuilder : public IRBuilderBase {
+private:
+ FolderTy Folder;
+ InserterTy Inserter;
+
+public:
+ IRBuilder(LLVMContext &C, FolderTy Folder, InserterTy Inserter = InserterTy(),
+ MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag, OpBundles),
+ Folder(Folder), Inserter(Inserter) {}
+
+ explicit IRBuilder(LLVMContext &C, MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(C, this->Folder, this->Inserter, FPMathTag, OpBundles) {}
+
+ explicit IRBuilder(BasicBlock *TheBB, FolderTy Folder,
+ MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
+ FPMathTag, OpBundles), Folder(Folder) {
+ SetInsertPoint(TheBB);
+ }
- if (Alignment->getType() != IntPtrTy)
- Alignment = CreateIntCast(Alignment, IntPtrTy, /*isSigned*/ false,
- "alignmentcast");
+ explicit IRBuilder(BasicBlock *TheBB, MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
+ FPMathTag, OpBundles) {
+ SetInsertPoint(TheBB);
+ }
- Value *Mask = CreateSub(Alignment, ConstantInt::get(IntPtrTy, 1), "mask");
+ explicit IRBuilder(Instruction *IP, MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(IP->getContext(), this->Folder, this->Inserter,
+ FPMathTag, OpBundles) {
+ SetInsertPoint(IP);
+ }
- return CreateAlignmentAssumptionHelper(DL, PtrValue, Mask, IntPtrTy,
- OffsetValue, TheCheck);
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, FolderTy Folder,
+ MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
+ FPMathTag, OpBundles), Folder(Folder) {
+ SetInsertPoint(TheBB, IP);
}
+
+ IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP,
+ MDNode *FPMathTag = nullptr,
+ ArrayRef<OperandBundleDef> OpBundles = None)
+ : IRBuilderBase(TheBB->getContext(), this->Folder, this->Inserter,
+ FPMathTag, OpBundles) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ /// Avoid copying the full IRBuilder. Prefer using InsertPointGuard
+ /// or FastMathFlagGuard instead.
+ IRBuilder(const IRBuilder &) = delete;
+
+ InserterTy &getInserter() { return Inserter; }
};
// Create wrappers for C Binding types (see CBindingWrapping.h).
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IRBuilderFolder.h b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilderFolder.h
new file mode 100644
index 000000000000..e781e8e094af
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IRBuilderFolder.h
@@ -0,0 +1,141 @@
+//===- IRBuilderFolder.h - Const folder interface for IRBuilder -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines for constant folding interface used by IRBuilder.
+// It is implemented by ConstantFolder (default), TargetFolder and NoFoler.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_IRBUILDERFOLDER_H
+#define LLVM_IR_IRBUILDERFOLDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+
+namespace llvm {
+
+/// IRBuilderFolder - Interface for constant folding in IRBuilder.
+class IRBuilderFolder {
+public:
+ virtual ~IRBuilderFolder();
+
+ //===--------------------------------------------------------------------===//
+ // Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateAdd(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const = 0;
+ virtual Value *CreateFAdd(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateSub(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const = 0;
+ virtual Value *CreateFSub(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateMul(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const = 0;
+ virtual Value *CreateFMul(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateUDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const = 0;
+ virtual Value *CreateSDiv(Constant *LHS, Constant *RHS,
+ bool isExact = false) const = 0;
+ virtual Value *CreateFDiv(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateURem(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateSRem(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateFRem(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateShl(Constant *LHS, Constant *RHS,
+ bool HasNUW = false, bool HasNSW = false) const = 0;
+ virtual Value *CreateLShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const = 0;
+ virtual Value *CreateAShr(Constant *LHS, Constant *RHS,
+ bool isExact = false) const = 0;
+ virtual Value *CreateAnd(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateOr(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateXor(Constant *LHS, Constant *RHS) const = 0;
+ virtual Value *CreateBinOp(Instruction::BinaryOps Opc,
+ Constant *LHS, Constant *RHS) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Unary Operators
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateNeg(Constant *C,
+ bool HasNUW = false, bool HasNSW = false) const = 0;
+ virtual Value *CreateFNeg(Constant *C) const = 0;
+ virtual Value *CreateNot(Constant *C) const = 0;
+ virtual Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Constant *> IdxList) const = 0;
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const = 0;
+ virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
+ ArrayRef<Value *> IdxList) const = 0;
+ virtual Value *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const = 0;
+ // This form of the function only exists to avoid ambiguous overload
+ // warnings about whether to convert Idx to ArrayRef<Constant *> or
+ // ArrayRef<Value *>.
+ virtual Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const = 0;
+ virtual Value *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateCast(Instruction::CastOps Op, Constant *C,
+ Type *DestTy) const = 0;
+ virtual Value *CreatePointerCast(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreatePointerBitCastOrAddrSpaceCast(Constant *C,
+ Type *DestTy) const = 0;
+ virtual Value *CreateIntCast(Constant *C, Type *DestTy,
+ bool isSigned) const = 0;
+ virtual Value *CreateFPCast(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreateBitCast(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreateIntToPtr(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreatePtrToInt(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreateZExtOrBitCast(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreateSExtOrBitCast(Constant *C, Type *DestTy) const = 0;
+ virtual Value *CreateTruncOrBitCast(Constant *C, Type *DestTy) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateICmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const = 0;
+ virtual Value *CreateFCmp(CmpInst::Predicate P, Constant *LHS,
+ Constant *RHS) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ virtual Value *CreateSelect(Constant *C, Constant *True,
+ Constant *False) const = 0;
+ virtual Value *CreateExtractElement(Constant *Vec, Constant *Idx) const = 0;
+ virtual Value *CreateInsertElement(Constant *Vec, Constant *NewElt,
+ Constant *Idx) const = 0;
+ virtual Value *CreateShuffleVector(Constant *V1, Constant *V2,
+ ArrayRef<int> Mask) const = 0;
+ virtual Value *CreateExtractValue(Constant *Agg,
+ ArrayRef<unsigned> IdxList) const = 0;
+ virtual Value *CreateInsertValue(Constant *Agg, Constant *Val,
+ ArrayRef<unsigned> IdxList) const = 0;
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_IRBUILDERFOLDER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IRPrintingPasses.h b/contrib/llvm-project/llvm/include/llvm/IR/IRPrintingPasses.h
index 230db988f737..3a1c489ee09f 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IRPrintingPasses.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IRPrintingPasses.h
@@ -19,17 +19,10 @@
#define LLVM_IR_IRPRINTINGPASSES_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/PassManager.h"
#include <string>
namespace llvm {
-class Pass;
-class Function;
-class FunctionPass;
-class Module;
-class ModulePass;
-class PreservedAnalyses;
-class raw_ostream;
-template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
/// Create and return a pass that writes the module to the specified
/// \c raw_ostream.
@@ -71,7 +64,7 @@ extern bool shouldPrintAfterPass(StringRef);
///
/// Note: This pass is for use with the new pass manager. Use the create...Pass
/// functions above to create passes for use with the legacy pass manager.
-class PrintModulePass {
+class PrintModulePass : public PassInfoMixin<PrintModulePass> {
raw_ostream &OS;
std::string Banner;
bool ShouldPreserveUseListOrder;
@@ -82,15 +75,13 @@ public:
bool ShouldPreserveUseListOrder = false);
PreservedAnalyses run(Module &M, AnalysisManager<Module> &);
-
- static StringRef name() { return "PrintModulePass"; }
};
/// Pass for printing a Function as LLVM's text IR assembly.
///
/// Note: This pass is for use with the new pass manager. Use the create...Pass
/// functions above to create passes for use with the legacy pass manager.
-class PrintFunctionPass {
+class PrintFunctionPass : public PassInfoMixin<PrintFunctionPass> {
raw_ostream &OS;
std::string Banner;
@@ -99,8 +90,6 @@ public:
PrintFunctionPass(raw_ostream &OS, const std::string &Banner = "");
PreservedAnalyses run(Function &F, AnalysisManager<Function> &);
-
- static StringRef name() { return "PrintFunctionPass"; }
};
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h b/contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h
index 72d8ad1501ae..b6f377093337 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/InlineAsm.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cassert>
#include <string>
#include <vector>
@@ -359,6 +360,96 @@ public:
RC = High - 1;
return true;
}
+
+ static std::vector<StringRef> getExtraInfoNames(unsigned ExtraInfo) {
+ std::vector<StringRef> Result;
+ if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
+ Result.push_back("sideeffect");
+ if (ExtraInfo & InlineAsm::Extra_MayLoad)
+ Result.push_back("mayload");
+ if (ExtraInfo & InlineAsm::Extra_MayStore)
+ Result.push_back("maystore");
+ if (ExtraInfo & InlineAsm::Extra_IsConvergent)
+ Result.push_back("isconvergent");
+ if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
+ Result.push_back("alignstack");
+
+ AsmDialect Dialect =
+ InlineAsm::AsmDialect((ExtraInfo & InlineAsm::Extra_AsmDialect));
+
+ if (Dialect == InlineAsm::AD_ATT)
+ Result.push_back("attdialect");
+ if (Dialect == InlineAsm::AD_Intel)
+ Result.push_back("inteldialect");
+
+ return Result;
+ }
+
+ static StringRef getKindName(unsigned Kind) {
+ switch (Kind) {
+ case InlineAsm::Kind_RegUse:
+ return "reguse";
+ case InlineAsm::Kind_RegDef:
+ return "regdef";
+ case InlineAsm::Kind_RegDefEarlyClobber:
+ return "regdef-ec";
+ case InlineAsm::Kind_Clobber:
+ return "clobber";
+ case InlineAsm::Kind_Imm:
+ return "imm";
+ case InlineAsm::Kind_Mem:
+ return "mem";
+ default:
+ llvm_unreachable("Unknown operand kind");
+ }
+ }
+
+ static StringRef getMemConstraintName(unsigned Constraint) {
+ switch (Constraint) {
+ case InlineAsm::Constraint_es:
+ return "es";
+ case InlineAsm::Constraint_i:
+ return "i";
+ case InlineAsm::Constraint_m:
+ return "m";
+ case InlineAsm::Constraint_o:
+ return "o";
+ case InlineAsm::Constraint_v:
+ return "v";
+ case InlineAsm::Constraint_Q:
+ return "Q";
+ case InlineAsm::Constraint_R:
+ return "R";
+ case InlineAsm::Constraint_S:
+ return "S";
+ case InlineAsm::Constraint_T:
+ return "T";
+ case InlineAsm::Constraint_Um:
+ return "Um";
+ case InlineAsm::Constraint_Un:
+ return "Un";
+ case InlineAsm::Constraint_Uq:
+ return "Uq";
+ case InlineAsm::Constraint_Us:
+ return "Us";
+ case InlineAsm::Constraint_Ut:
+ return "Ut";
+ case InlineAsm::Constraint_Uv:
+ return "Uv";
+ case InlineAsm::Constraint_Uy:
+ return "Uy";
+ case InlineAsm::Constraint_X:
+ return "X";
+ case InlineAsm::Constraint_Z:
+ return "Z";
+ case InlineAsm::Constraint_ZC:
+ return "ZC";
+ case InlineAsm::Constraint_Zy:
+ return "Zy";
+ default:
+ llvm_unreachable("Unknown memory constraint");
+ }
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h b/contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h
index 6168c877a2be..4dbdc66d1366 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/InstVisitor.h
@@ -10,7 +10,6 @@
#ifndef LLVM_IR_INSTVISITOR_H
#define LLVM_IR_INSTVISITOR_H
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
@@ -217,18 +216,9 @@ public:
RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); }
RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); }
RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); }
-
- // Call, Invoke and CallBr are slightly different as they delegate first
- // through a generic CallSite visitor.
- RetTy visitCallInst(CallInst &I) {
- return static_cast<SubClass*>(this)->visitCallSite(&I);
- }
- RetTy visitInvokeInst(InvokeInst &I) {
- return static_cast<SubClass*>(this)->visitCallSite(&I);
- }
- RetTy visitCallBrInst(CallBrInst &I) {
- return static_cast<SubClass *>(this)->visitCallSite(&I);
- }
+ RetTy visitCallInst(CallInst &I) { DELEGATE(CallBase); }
+ RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(CallBase); }
+ RetTy visitCallBrInst(CallBrInst &I) { DELEGATE(CallBase); }
// While terminators don't have a distinct type modeling them, we support
// intercepting them with dedicated a visitor callback.
@@ -280,16 +270,6 @@ public:
DELEGATE(Instruction);
}
- // Provide a legacy visitor for a 'callsite' that visits calls, invokes,
- // and calbrs.
- //
- // Prefer overriding the type system based `CallBase` instead.
- RetTy visitCallSite(CallSite CS) {
- assert(CS);
- Instruction &I = *CS.getInstruction();
- DELEGATE(CallBase);
- }
-
// If the user wants a 'default' case, they can choose to override this
// function. If this function is not overloaded in the user's subclass, then
// this instruction just gets ignored.
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/InstrTypes.h b/contrib/llvm-project/llvm/include/llvm/IR/InstrTypes.h
index b2cdd58a5046..07af00ec9240 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/InstrTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/InstrTypes.h
@@ -154,18 +154,20 @@ public:
}
#include "llvm/IR/Instruction.def"
- static UnaryOperator *CreateWithCopiedFlags(UnaryOps Opc,
- Value *V,
- Instruction *CopyO,
- const Twine &Name = "") {
- UnaryOperator *UO = Create(Opc, V, Name);
+ static UnaryOperator *
+ CreateWithCopiedFlags(UnaryOps Opc, Value *V, Instruction *CopyO,
+ const Twine &Name = "",
+ Instruction *InsertBefore = nullptr) {
+ UnaryOperator *UO = Create(Opc, V, Name, InsertBefore);
UO->copyIRFlags(CopyO);
return UO;
}
static UnaryOperator *CreateFNegFMF(Value *Op, Instruction *FMFSource,
- const Twine &Name = "") {
- return CreateWithCopiedFlags(Instruction::FNeg, Op, FMFSource, Name);
+ const Twine &Name = "",
+ Instruction *InsertBefore = nullptr) {
+ return CreateWithCopiedFlags(Instruction::FNeg, Op, FMFSource, Name,
+ InsertBefore);
}
UnaryOps getOpcode() const {
@@ -280,11 +282,6 @@ public:
const Twine &Name = "") {
return CreateWithCopiedFlags(Instruction::FRem, V1, V2, FMFSource, Name);
}
- static BinaryOperator *CreateFNegFMF(Value *Op, Instruction *FMFSource,
- const Twine &Name = "") {
- Value *Zero = ConstantFP::getNegativeZero(Op->getType());
- return CreateWithCopiedFlags(Instruction::FSub, Zero, Op, FMFSource, Name);
- }
static BinaryOperator *CreateNSW(BinaryOps Opc, Value *V1, Value *V2,
const Twine &Name = "") {
@@ -390,10 +387,6 @@ public:
Instruction *InsertBefore = nullptr);
static BinaryOperator *CreateNUWNeg(Value *Op, const Twine &Name,
BasicBlock *InsertAtEnd);
- static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name = "",
- Instruction *InsertBefore = nullptr);
- static BinaryOperator *CreateFNeg(Value *Op, const Twine &Name,
- BasicBlock *InsertAtEnd);
static BinaryOperator *CreateNot(Value *Op, const Twine &Name = "",
Instruction *InsertBefore = nullptr);
static BinaryOperator *CreateNot(Value *Op, const Twine &Name,
@@ -729,41 +722,43 @@ public:
/// Some passes (e.g. InstCombine) depend on the bit-wise characteristics of
/// FCMP_* values. Changing the bit patterns requires a potential change to
/// those passes.
- enum Predicate {
- // Opcode U L G E Intuitive operation
- FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
- FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
- FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
- FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
- FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
- FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
- FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
- FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
- FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
- FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
- FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
- FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
- FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
- FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
- FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
- FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
+ enum Predicate : unsigned {
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT = 10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE = 11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT = 12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE = 13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE = 14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE = 15, ///< 1 1 1 1 Always true (always folded)
FIRST_FCMP_PREDICATE = FCMP_FALSE,
LAST_FCMP_PREDICATE = FCMP_TRUE,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
- ICMP_EQ = 32, ///< equal
- ICMP_NE = 33, ///< not equal
- ICMP_UGT = 34, ///< unsigned greater than
- ICMP_UGE = 35, ///< unsigned greater or equal
- ICMP_ULT = 36, ///< unsigned less than
- ICMP_ULE = 37, ///< unsigned less or equal
- ICMP_SGT = 38, ///< signed greater than
- ICMP_SGE = 39, ///< signed greater or equal
- ICMP_SLT = 40, ///< signed less than
- ICMP_SLE = 41, ///< signed less or equal
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
FIRST_ICMP_PREDICATE = ICMP_EQ,
LAST_ICMP_PREDICATE = ICMP_SLE,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
};
+ using PredicateField =
+ Bitfield::Element<Predicate, 0, 6, LAST_ICMP_PREDICATE>;
protected:
CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred,
@@ -804,15 +799,15 @@ public:
}
/// Return the predicate for this instruction.
- Predicate getPredicate() const {
- return Predicate(getSubclassDataFromInstruction());
- }
+ Predicate getPredicate() const { return getSubclassData<PredicateField>(); }
/// Set the predicate for this instruction to the specified value.
- void setPredicate(Predicate P) { setInstructionSubclassData(P); }
+ void setPredicate(Predicate P) { setSubclassData<PredicateField>(P); }
static bool isFPPredicate(Predicate P) {
- return P >= FIRST_FCMP_PREDICATE && P <= LAST_FCMP_PREDICATE;
+ assert(FIRST_FCMP_PREDICATE == 0 &&
+ "FIRST_FCMP_PREDICATE is required to be 0");
+ return P <= LAST_FCMP_PREDICATE;
}
static bool isIntPredicate(Predicate P) {
@@ -1066,7 +1061,7 @@ public:
: Tag(std::move(Tag)), Inputs(Inputs) {}
explicit OperandBundleDefT(const OperandBundleUse &OBU) {
- Tag = OBU.getTagName();
+ Tag = std::string(OBU.getTagName());
Inputs.insert(Inputs.end(), OBU.Inputs.begin(), OBU.Inputs.end());
}
@@ -1104,6 +1099,15 @@ using ConstOperandBundleDef = OperandBundleDefT<const Value *>;
/// as cheap as most other operations on the base class.
class CallBase : public Instruction {
protected:
+ // The first two bits are reserved by CallInst for fast retrieval,
+ using CallInstReservedField = Bitfield::Element<unsigned, 0, 2>;
+ using CallingConvField =
+ Bitfield::Element<CallingConv::ID, CallInstReservedField::NextBit, 10,
+ CallingConv::MaxID>;
+ static_assert(
+ Bitfield::areContiguous<CallInstReservedField, CallingConvField>(),
+ "Bitfields must be contiguous");
+
/// The last operand is the called operand.
static constexpr int CalledOperandOpEndIdx = -1;
@@ -1137,6 +1141,15 @@ protected:
public:
using Instruction::getContext;
+ /// Create a clone of \p CB with a different set of operand bundles and
+ /// insert it before \p InsertPt.
+ ///
+ /// The returned call instruction is identical \p CB in every way except that
+ /// the operand bundles for the new instruction are set to the operand bundles
+ /// in \p Bundles.
+ static CallBase *Create(CallBase *CB, ArrayRef<OperandBundleDef> Bundles,
+ Instruction *InsertPt = nullptr);
+
static bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Call ||
I->getOpcode() == Instruction::Invoke ||
@@ -1293,10 +1306,6 @@ public:
Value *getCalledOperand() const { return Op<CalledOperandOpEndIdx>(); }
- // DEPRECATED: This routine will be removed in favor of `getCalledOperand` in
- // the near future.
- Value *getCalledValue() const { return getCalledOperand(); }
-
const Use &getCalledOperandUse() const { return Op<CalledOperandOpEndIdx>(); }
Use &getCalledOperandUse() { return Op<CalledOperandOpEndIdx>(); }
@@ -1360,14 +1369,11 @@ public:
}
CallingConv::ID getCallingConv() const {
- return static_cast<CallingConv::ID>(getSubclassDataFromInstruction() >> 2);
+ return getSubclassData<CallingConvField>();
}
void setCallingConv(CallingConv::ID CC) {
- auto ID = static_cast<unsigned>(CC);
- assert(!(ID & ~CallingConv::MaxID) && "Unsupported calling convention");
- setInstructionSubclassData((getSubclassDataFromInstruction() & 3) |
- (ID << 2));
+ setSubclassData<CallingConvField>(CC);
}
/// Check if this call is an inline asm statement.
@@ -1552,10 +1558,12 @@ public:
return paramHasAttr(ArgNo, Attribute::InAlloca);
}
- /// Determine whether this argument is passed by value or in an alloca.
- bool isByValOrInAllocaArgument(unsigned ArgNo) const {
+ /// Determine whether this argument is passed by value, in an alloca, or is
+ /// preallocated.
+ bool isPassPointeeByValueArgument(unsigned ArgNo) const {
return paramHasAttr(ArgNo, Attribute::ByVal) ||
- paramHasAttr(ArgNo, Attribute::InAlloca);
+ paramHasAttr(ArgNo, Attribute::InAlloca) ||
+ paramHasAttr(ArgNo, Attribute::Preallocated);
}
/// Determine if there are is an inalloca argument. Only the last argument can
@@ -1584,10 +1592,8 @@ public:
dataOperandHasImpliedAttr(OpNo + 1, Attribute::ReadNone);
}
- /// Extract the alignment of the return value.
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getRetAlign() instead.
- unsigned getRetAlignment() const {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getRetAlignment() const,
+ "Use getRetAlign() instead") {
if (const auto MA = Attrs.getRetAlignment())
return MA->value();
return 0;
@@ -1597,9 +1603,8 @@ public:
MaybeAlign getRetAlign() const { return Attrs.getRetAlignment(); }
/// Extract the alignment for a call or parameter (0=unknown).
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getParamAlign() instead.
- unsigned getParamAlignment(unsigned ArgNo) const {
+ LLVM_ATTRIBUTE_DEPRECATED(unsigned getParamAlignment(unsigned ArgNo) const,
+ "Use getParamAlign() instead") {
if (const auto MA = Attrs.getParamAlignment(ArgNo))
return MA->value();
return 0;
@@ -1616,6 +1621,12 @@ public:
return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType();
}
+ /// Extract the preallocated type for a call or parameter.
+ Type *getParamPreallocatedType(unsigned ArgNo) const {
+ Type *Ty = Attrs.getParamPreallocatedType(ArgNo);
+ return Ty ? Ty : getArgOperand(ArgNo)->getType()->getPointerElementType();
+ }
+
/// Extract the number of dereferenceable bytes for a call or
/// parameter (0=unknown).
uint64_t getDereferenceableBytes(unsigned i) const {
@@ -1727,6 +1738,12 @@ public:
addAttribute(AttributeList::FunctionIndex, Attribute::NoDuplicate);
}
+ /// Determine if the call cannot be tail merged.
+ bool cannotMerge() const { return hasFnAttr(Attribute::NoMerge); }
+ void setCannotMerge() {
+ addAttribute(AttributeList::FunctionIndex, Attribute::NoMerge);
+ }
+
/// Determine if the invoke is convergent
bool isConvergent() const { return hasFnAttr(Attribute::Convergent); }
void setConvergent() {
@@ -1876,10 +1893,7 @@ public:
/// OperandBundleUser to a vector of OperandBundleDefs. Note:
/// OperandBundeUses and OperandBundleDefs are non-trivially *different*
/// representations of operand bundles (see documentation above).
- void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const {
- for (unsigned i = 0, e = getNumOperandBundles(); i != e; ++i)
- Defs.emplace_back(getOperandBundleAt(i));
- }
+ void getOperandBundlesAsDefs(SmallVectorImpl<OperandBundleDef> &Defs) const;
/// Return the operand bundle for the operand at index OpIdx.
///
@@ -2107,16 +2121,14 @@ public:
op_iterator populateBundleOperandInfos(ArrayRef<OperandBundleDef> Bundles,
const unsigned BeginIndex);
+public:
/// Return the BundleOpInfo for the operand at index OpIdx.
///
/// It is an error to call this with an OpIdx that does not correspond to an
/// bundle operand.
+ BundleOpInfo &getBundleOpInfoForOperand(unsigned OpIdx);
const BundleOpInfo &getBundleOpInfoForOperand(unsigned OpIdx) const {
- for (auto &BOI : bundle_op_infos())
- if (BOI.Begin <= OpIdx && OpIdx < BOI.End)
- return BOI;
-
- llvm_unreachable("Did not find operand bundle for operand!");
+ return const_cast<CallBase *>(this)->getBundleOpInfoForOperand(OpIdx);
}
protected:
@@ -2136,7 +2148,7 @@ private:
bool hasFnAttrOnCalledFunction(StringRef Kind) const;
template <typename AttrKind> bool hasFnAttrImpl(AttrKind Kind) const {
- if (Attrs.hasAttribute(AttributeList::FunctionIndex, Kind))
+ if (Attrs.hasFnAttribute(Kind))
return true;
// Operand bundles override attributes on the called function, but don't
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Instruction.h b/contrib/llvm-project/llvm/include/llvm/IR/Instruction.h
index 3bfa0e4afc39..a03eac0ad40d 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Instruction.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Instruction.h
@@ -15,6 +15,7 @@
#define LLVM_IR_INSTRUCTION_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Bitfields.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/ilist_node.h"
@@ -22,6 +23,7 @@
#include "llvm/IR/SymbolTableListTraits.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
+#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
@@ -45,11 +47,37 @@ class Instruction : public User,
BasicBlock *Parent;
DebugLoc DbgLoc; // 'dbg' Metadata cache.
- enum {
- /// This is a bit stored in the SubClassData field which indicates whether
- /// this instruction has metadata attached to it or not.
- HasMetadataBit = 1 << 15
- };
+ /// Relative order of this instruction in its parent basic block. Used for
+ /// O(1) local dominance checks between instructions.
+ mutable unsigned Order = 0;
+
+protected:
+ // The 15 first bits of `Value::SubclassData` are available for subclasses of
+ // `Instruction` to use.
+ using OpaqueField = Bitfield::Element<uint16_t, 0, 15>;
+
+ // Template alias so that all Instruction storing alignment use the same
+ // definiton.
+ // Valid alignments are powers of two from 2^0 to 2^MaxAlignmentExponent =
+ // 2^29. We store them as Log2(Alignment), so we need 5 bits to encode the 30
+ // possible values.
+ template <unsigned Offset>
+ using AlignmentBitfieldElementT =
+ typename Bitfield::Element<unsigned, Offset, 5,
+ Value::MaxAlignmentExponent>;
+
+ template <unsigned Offset>
+ using BoolBitfieldElementT = typename Bitfield::Element<bool, Offset, 1>;
+
+ template <unsigned Offset>
+ using AtomicOrderingBitfieldElementT =
+ typename Bitfield::Element<AtomicOrdering, Offset, 3,
+ AtomicOrdering::LAST>;
+
+private:
+ // The last bit is used to store whether the instruction has metadata attached
+ // or not.
+ using HasMetadataField = Bitfield::Element<bool, 15, 1>;
protected:
~Instruction(); // Use deleteValue() to delete a generic Instruction.
@@ -117,6 +145,13 @@ public:
/// the basic block that MovePos lives in, right after MovePos.
void moveAfter(Instruction *MovePos);
+ /// Given an instruction Other in the same basic block as this instruction,
+ /// return true if this instruction comes before Other. In this worst case,
+ /// this takes linear time in the number of instructions in the block. The
+ /// results are cached, so in common cases when the block remains unmodified,
+ /// it takes constant time.
+ bool comesBefore(const Instruction *Other) const;
+
//===--------------------------------------------------------------------===//
// Subclass classification.
//===--------------------------------------------------------------------===//
@@ -321,9 +356,6 @@ public:
/// Returns false if no metadata was found.
bool extractProfTotalWeight(uint64_t &TotalVal) const;
- /// Sets the branch_weights metadata to \p W for CallInst.
- void setProfWeight(uint64_t W);
-
/// Set the debug location information for this instruction.
void setDebugLoc(DebugLoc Loc) { DbgLoc = std::move(Loc); }
@@ -385,6 +417,11 @@ public:
/// this flag.
void setHasAllowReciprocal(bool B);
+ /// Set or clear the allow-contract flag on this instruction, which must be
+ /// an operator which supports this flag. See LangRef.html for the meaning of
+ /// this flag.
+ void setHasAllowContract(bool B);
+
/// Set or clear the approximate-math-functions flag on this instruction,
/// which must be an operator which supports this flag. See LangRef.html for
/// the meaning of this flag.
@@ -458,7 +495,7 @@ public:
private:
/// Return true if we have an entry in the on-the-side metadata hash.
bool hasMetadataHashEntry() const {
- return (getSubclassDataFromValue() & HasMetadataBit) != 0;
+ return Bitfield::test<HasMetadataField>(getSubclassDataFromValue());
}
// These are all implemented in Metadata.cpp.
@@ -738,6 +775,7 @@ public:
private:
friend class SymbolTableListTraits<Instruction>;
+ friend class BasicBlock; // For renumbering.
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.
@@ -749,10 +787,7 @@ private:
return Value::getSubclassDataFromValue();
}
- void setHasMetadataHashEntry(bool V) {
- setValueSubclassData((getSubclassDataFromValue() & ~HasMetadataBit) |
- (V ? HasMetadataBit : 0));
- }
+ void setHasMetadataHashEntry(bool V) { setSubclassData<HasMetadataField>(V); }
void setParent(BasicBlock *P);
@@ -760,14 +795,24 @@ protected:
// Instruction subclasses can stick up to 15 bits of stuff into the
// SubclassData field of instruction with these members.
- // Verify that only the low 15 bits are used.
- void setInstructionSubclassData(unsigned short D) {
- assert((D & HasMetadataBit) == 0 && "Out of range value put into field");
- setValueSubclassData((getSubclassDataFromValue() & HasMetadataBit) | D);
- }
-
- unsigned getSubclassDataFromInstruction() const {
- return getSubclassDataFromValue() & ~HasMetadataBit;
+ template <typename BitfieldElement>
+ typename BitfieldElement::Type getSubclassData() const {
+ static_assert(
+ std::is_same<BitfieldElement, HasMetadataField>::value ||
+ !Bitfield::isOverlapping<BitfieldElement, HasMetadataField>(),
+ "Must not overlap with the metadata bit");
+ return Bitfield::get<BitfieldElement>(getSubclassDataFromValue());
+ }
+
+ template <typename BitfieldElement>
+ void setSubclassData(typename BitfieldElement::Type Value) {
+ static_assert(
+ std::is_same<BitfieldElement, HasMetadataField>::value ||
+ !Bitfield::isOverlapping<BitfieldElement, HasMetadataField>(),
+ "Must not overlap with the metadata bit");
+ auto Storage = getSubclassDataFromValue();
+ Bitfield::set<BitfieldElement>(Storage, Value);
+ setValueSubclassData(Storage);
}
Instruction(Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Instructions.h b/contrib/llvm-project/llvm/include/llvm/IR/Instructions.h
index b73d5274238c..0afc585dfbe5 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Instructions.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Instructions.h
@@ -16,6 +16,7 @@
#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Bitfields.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
@@ -59,6 +60,13 @@ class LLVMContext;
class AllocaInst : public UnaryInstruction {
Type *AllocatedType;
+ using AlignmentField = AlignmentBitfieldElementT<0>;
+ using UsedWithInAllocaField = BoolBitfieldElementT<AlignmentField::NextBit>;
+ using SwiftErrorField = BoolBitfieldElementT<UsedWithInAllocaField::NextBit>;
+ static_assert(Bitfield::areContiguous<AlignmentField, UsedWithInAllocaField,
+ SwiftErrorField>(),
+ "Bitfields must be contiguous");
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -66,21 +74,19 @@ protected:
AllocaInst *cloneImpl() const;
public:
- explicit AllocaInst(Type *Ty, unsigned AddrSpace,
- Value *ArraySize = nullptr,
- const Twine &Name = "",
- Instruction *InsertBefore = nullptr);
+ explicit AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
+ const Twine &Name, Instruction *InsertBefore);
AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize,
const Twine &Name, BasicBlock *InsertAtEnd);
- AllocaInst(Type *Ty, unsigned AddrSpace,
- const Twine &Name, Instruction *InsertBefore = nullptr);
+ AllocaInst(Type *Ty, unsigned AddrSpace, const Twine &Name,
+ Instruction *InsertBefore);
AllocaInst(Type *Ty, unsigned AddrSpace,
const Twine &Name, BasicBlock *InsertAtEnd);
- AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, MaybeAlign Align,
+ AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, Align Align,
const Twine &Name = "", Instruction *InsertBefore = nullptr);
- AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, MaybeAlign Align,
+ AllocaInst(Type *Ty, unsigned AddrSpace, Value *ArraySize, Align Align,
const Twine &Name, BasicBlock *InsertAtEnd);
/// Return true if there is an allocation size parameter to the allocation
@@ -109,12 +115,16 @@ public:
/// Return the alignment of the memory that is being allocated by the
/// instruction.
- unsigned getAlignment() const {
- if (const auto MA = decodeMaybeAlign(getSubclassDataFromInstruction() & 31))
- return MA->value();
- return 0;
+ Align getAlign() const {
+ return Align(1ULL << getSubclassData<AlignmentField>());
}
- void setAlignment(MaybeAlign Align);
+
+ void setAlignment(Align Align) {
+ setSubclassData<AlignmentField>(Log2(Align));
+ }
+
+ // FIXME: Remove this one transition to Align is over.
+ unsigned getAlignment() const { return getAlign().value(); }
/// Return true if this alloca is in the entry block of the function and is a
/// constant size. If so, the code generator will fold it into the
@@ -124,25 +134,18 @@ public:
/// Return true if this alloca is used as an inalloca argument to a call. Such
/// allocas are never considered static even if they are in the entry block.
bool isUsedWithInAlloca() const {
- return getSubclassDataFromInstruction() & 32;
+ return getSubclassData<UsedWithInAllocaField>();
}
/// Specify whether this alloca is used to represent the arguments to a call.
void setUsedWithInAlloca(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~32) |
- (V ? 32 : 0));
+ setSubclassData<UsedWithInAllocaField>(V);
}
/// Return true if this alloca is used as a swifterror argument to a call.
- bool isSwiftError() const {
- return getSubclassDataFromInstruction() & 64;
- }
-
+ bool isSwiftError() const { return getSubclassData<SwiftErrorField>(); }
/// Specify whether this alloca is used to represent a swifterror.
- void setSwiftError(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~64) |
- (V ? 64 : 0));
- }
+ void setSwiftError(bool V) { setSubclassData<SwiftErrorField>(V); }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Instruction *I) {
@@ -155,8 +158,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
};
@@ -167,6 +171,13 @@ private:
/// An instruction for reading from memory. This uses the SubclassData field in
/// Value to store whether or not the load is volatile.
class LoadInst : public UnaryInstruction {
+ using VolatileField = BoolBitfieldElementT<0>;
+ using AlignmentField = AlignmentBitfieldElementT<VolatileField::NextBit>;
+ using OrderingField = AtomicOrderingBitfieldElementT<AlignmentField::NextBit>;
+ static_assert(
+ Bitfield::areContiguous<VolatileField, AlignmentField, OrderingField>(),
+ "Bitfields must be contiguous");
+
void AssertOK();
protected:
@@ -176,94 +187,53 @@ protected:
LoadInst *cloneImpl() const;
public:
- LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr);
+ LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr,
+ Instruction *InsertBefore);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
- Instruction *InsertBefore = nullptr);
+ Instruction *InsertBefore);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
BasicBlock *InsertAtEnd);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
- MaybeAlign Align, Instruction *InsertBefore = nullptr);
+ Align Align, Instruction *InsertBefore = nullptr);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
- MaybeAlign Align, BasicBlock *InsertAtEnd);
+ Align Align, BasicBlock *InsertAtEnd);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
- MaybeAlign Align, AtomicOrdering Order,
+ Align Align, AtomicOrdering Order,
SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr);
LoadInst(Type *Ty, Value *Ptr, const Twine &NameStr, bool isVolatile,
- MaybeAlign Align, AtomicOrdering Order, SyncScope::ID SSID,
+ Align Align, AtomicOrdering Order, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
- // Deprecated [opaque pointer types]
- explicit LoadInst(Value *Ptr, const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- InsertBefore) {}
- LoadInst(Value *Ptr, const Twine &NameStr, BasicBlock *InsertAtEnd)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- InsertAtEnd) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
- Instruction *InsertBefore = nullptr)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, InsertBefore) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile,
- BasicBlock *InsertAtEnd)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, InsertAtEnd) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align,
- Instruction *InsertBefore = nullptr)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, Align, InsertBefore) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align,
- BasicBlock *InsertAtEnd)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, Align, InsertAtEnd) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align,
- AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System,
- Instruction *InsertBefore = nullptr)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, Align, Order, SSID, InsertBefore) {}
- LoadInst(Value *Ptr, const Twine &NameStr, bool isVolatile, MaybeAlign Align,
- AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd)
- : LoadInst(Ptr->getType()->getPointerElementType(), Ptr, NameStr,
- isVolatile, Align, Order, SSID, InsertAtEnd) {}
-
/// Return true if this is a load from a volatile memory location.
- bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+ bool isVolatile() const { return getSubclassData<VolatileField>(); }
/// Specify whether this is a volatile load or not.
- void setVolatile(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- (V ? 1 : 0));
- }
+ void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
/// Return the alignment of the access that is being performed.
/// FIXME: Remove this function once transition to Align is over.
/// Use getAlign() instead.
- unsigned getAlignment() const {
- if (const auto MA = getAlign())
- return MA->value();
- return 0;
- }
+ unsigned getAlignment() const { return getAlign().value(); }
/// Return the alignment of the access that is being performed.
- MaybeAlign getAlign() const {
- return decodeMaybeAlign((getSubclassDataFromInstruction() >> 1) & 31);
+ Align getAlign() const {
+ return Align(1ULL << (getSubclassData<AlignmentField>()));
}
- void setAlignment(MaybeAlign Alignment);
+ void setAlignment(Align Align) {
+ setSubclassData<AlignmentField>(Log2(Align));
+ }
/// Returns the ordering constraint of this load instruction.
AtomicOrdering getOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+ return getSubclassData<OrderingField>();
}
-
/// Sets the ordering constraint of this load instruction. May not be Release
/// or AcquireRelease.
void setOrdering(AtomicOrdering Ordering) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
- ((unsigned)Ordering << 7));
+ setSubclassData<OrderingField>(Ordering);
}
/// Returns the synchronization scope ID of this load instruction.
@@ -313,8 +283,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
/// The synchronization scope ID of this load instruction. Not quite enough
@@ -329,6 +300,13 @@ private:
/// An instruction for storing to memory.
class StoreInst : public Instruction {
+ using VolatileField = BoolBitfieldElementT<0>;
+ using AlignmentField = AlignmentBitfieldElementT<VolatileField::NextBit>;
+ using OrderingField = AtomicOrderingBitfieldElementT<AlignmentField::NextBit>;
+ static_assert(
+ Bitfield::areContiguous<VolatileField, AlignmentField, OrderingField>(),
+ "Bitfields must be contiguous");
+
void AssertOK();
protected:
@@ -340,17 +318,16 @@ protected:
public:
StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
- StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
- Instruction *InsertBefore = nullptr);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Instruction *InsertBefore);
StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
- StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align,
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
Instruction *InsertBefore = nullptr);
- StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align,
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
BasicBlock *InsertAtEnd);
- StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align,
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
AtomicOrdering Order, SyncScope::ID SSID = SyncScope::System,
Instruction *InsertBefore = nullptr);
- StoreInst(Value *Val, Value *Ptr, bool isVolatile, MaybeAlign Align,
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, Align Align,
AtomicOrdering Order, SyncScope::ID SSID, BasicBlock *InsertAtEnd);
// allocate space for exactly two operands
@@ -359,13 +336,10 @@ public:
}
/// Return true if this is a store to a volatile memory location.
- bool isVolatile() const { return getSubclassDataFromInstruction() & 1; }
+ bool isVolatile() const { return getSubclassData<VolatileField>(); }
/// Specify whether this is a volatile store or not.
- void setVolatile(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- (V ? 1 : 0));
- }
+ void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
@@ -373,28 +347,25 @@ public:
/// Return the alignment of the access that is being performed
/// FIXME: Remove this function once transition to Align is over.
/// Use getAlign() instead.
- unsigned getAlignment() const {
- if (const auto MA = getAlign())
- return MA->value();
- return 0;
- }
+ unsigned getAlignment() const { return getAlign().value(); }
- MaybeAlign getAlign() const {
- return decodeMaybeAlign((getSubclassDataFromInstruction() >> 1) & 31);
+ Align getAlign() const {
+ return Align(1ULL << (getSubclassData<AlignmentField>()));
}
- void setAlignment(MaybeAlign Alignment);
+ void setAlignment(Align Align) {
+ setSubclassData<AlignmentField>(Log2(Align));
+ }
/// Returns the ordering constraint of this store instruction.
AtomicOrdering getOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 7) & 7);
+ return getSubclassData<OrderingField>();
}
/// Sets the ordering constraint of this store instruction. May not be
/// Acquire or AcquireRelease.
void setOrdering(AtomicOrdering Ordering) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 7)) |
- ((unsigned)Ordering << 7));
+ setSubclassData<OrderingField>(Ordering);
}
/// Returns the synchronization scope ID of this store instruction.
@@ -447,8 +418,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
/// The synchronization scope ID of this store instruction. Not quite enough
@@ -469,6 +441,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(StoreInst, Value)
/// An instruction for ordering other memory operations.
class FenceInst : public Instruction {
+ using OrderingField = AtomicOrderingBitfieldElementT<0>;
+
void Init(AtomicOrdering Ordering, SyncScope::ID SSID);
protected:
@@ -493,14 +467,13 @@ public:
/// Returns the ordering constraint of this fence instruction.
AtomicOrdering getOrdering() const {
- return AtomicOrdering(getSubclassDataFromInstruction() >> 1);
+ return getSubclassData<OrderingField>();
}
/// Sets the ordering constraint of this fence instruction. May only be
/// Acquire, Release, AcquireRelease, or SequentiallyConsistent.
void setOrdering(AtomicOrdering Ordering) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & 1) |
- ((unsigned)Ordering << 1));
+ setSubclassData<OrderingField>(Ordering);
}
/// Returns the synchronization scope ID of this fence instruction.
@@ -524,8 +497,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
/// The synchronization scope ID of this fence instruction. Not quite enough
@@ -545,10 +519,15 @@ private:
/// failure (false) as second element.
///
class AtomicCmpXchgInst : public Instruction {
- void Init(Value *Ptr, Value *Cmp, Value *NewVal,
+ void Init(Value *Ptr, Value *Cmp, Value *NewVal, Align Align,
AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
SyncScope::ID SSID);
+ template <unsigned Offset>
+ using AtomicOrderingBitfieldElement =
+ typename Bitfield::Element<AtomicOrdering, Offset, 3,
+ AtomicOrdering::LAST>;
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -556,71 +535,82 @@ protected:
AtomicCmpXchgInst *cloneImpl() const;
public:
- AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+ AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, Align Alignment,
AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SyncScope::ID SSID, Instruction *InsertBefore = nullptr);
- AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal,
+ AtomicOrdering FailureOrdering, SyncScope::ID SSID,
+ Instruction *InsertBefore = nullptr);
+ AtomicCmpXchgInst(Value *Ptr, Value *Cmp, Value *NewVal, Align Alignment,
AtomicOrdering SuccessOrdering,
- AtomicOrdering FailureOrdering,
- SyncScope::ID SSID, BasicBlock *InsertAtEnd);
+ AtomicOrdering FailureOrdering, SyncScope::ID SSID,
+ BasicBlock *InsertAtEnd);
// allocate space for exactly three operands
void *operator new(size_t s) {
return User::operator new(s, 3);
}
+ using VolatileField = BoolBitfieldElementT<0>;
+ using WeakField = BoolBitfieldElementT<VolatileField::NextBit>;
+ using SuccessOrderingField =
+ AtomicOrderingBitfieldElementT<WeakField::NextBit>;
+ using FailureOrderingField =
+ AtomicOrderingBitfieldElementT<SuccessOrderingField::NextBit>;
+ using AlignmentField =
+ AlignmentBitfieldElementT<FailureOrderingField::NextBit>;
+ static_assert(
+ Bitfield::areContiguous<VolatileField, WeakField, SuccessOrderingField,
+ FailureOrderingField, AlignmentField>(),
+ "Bitfields must be contiguous");
+
+ /// Return the alignment of the memory that is being allocated by the
+ /// instruction.
+ Align getAlign() const {
+ return Align(1ULL << getSubclassData<AlignmentField>());
+ }
+
+ void setAlignment(Align Align) {
+ setSubclassData<AlignmentField>(Log2(Align));
+ }
+
/// Return true if this is a cmpxchg from a volatile memory
/// location.
///
- bool isVolatile() const {
- return getSubclassDataFromInstruction() & 1;
- }
+ bool isVolatile() const { return getSubclassData<VolatileField>(); }
/// Specify whether this is a volatile cmpxchg.
///
- void setVolatile(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- (unsigned)V);
- }
+ void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
/// Return true if this cmpxchg may spuriously fail.
- bool isWeak() const {
- return getSubclassDataFromInstruction() & 0x100;
- }
+ bool isWeak() const { return getSubclassData<WeakField>(); }
- void setWeak(bool IsWeak) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x100) |
- (IsWeak << 8));
- }
+ void setWeak(bool IsWeak) { setSubclassData<WeakField>(IsWeak); }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Returns the success ordering constraint of this cmpxchg instruction.
AtomicOrdering getSuccessOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ return getSubclassData<SuccessOrderingField>();
}
/// Sets the success ordering constraint of this cmpxchg instruction.
void setSuccessOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"CmpXchg instructions can only be atomic.");
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~0x1c) |
- ((unsigned)Ordering << 2));
+ setSubclassData<SuccessOrderingField>(Ordering);
}
/// Returns the failure ordering constraint of this cmpxchg instruction.
AtomicOrdering getFailureOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 5) & 7);
+ return getSubclassData<FailureOrderingField>();
}
/// Sets the failure ordering constraint of this cmpxchg instruction.
void setFailureOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"CmpXchg instructions can only be atomic.");
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~0xe0) |
- ((unsigned)Ordering << 5));
+ setSubclassData<FailureOrderingField>(Ordering);
}
/// Returns the synchronization scope ID of this cmpxchg instruction.
@@ -682,8 +672,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
/// The synchronization scope ID of this cmpxchg instruction. Not quite
@@ -719,7 +710,7 @@ public:
/// the descriptions, 'p' is the pointer to the instruction's memory location,
/// 'old' is the initial value of *p, and 'v' is the other value passed to the
/// instruction. These instructions always return 'old'.
- enum BinOp {
+ enum BinOp : unsigned {
/// *p = v
Xchg,
/// *p = old + v
@@ -754,10 +745,21 @@ public:
BAD_BINOP
};
- AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+private:
+ template <unsigned Offset>
+ using AtomicOrderingBitfieldElement =
+ typename Bitfield::Element<AtomicOrdering, Offset, 3,
+ AtomicOrdering::LAST>;
+
+ template <unsigned Offset>
+ using BinOpBitfieldElement =
+ typename Bitfield::Element<BinOp, Offset, 4, BinOp::LAST_BINOP>;
+
+public:
+ AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, Align Alignment,
AtomicOrdering Ordering, SyncScope::ID SSID,
Instruction *InsertBefore = nullptr);
- AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val,
+ AtomicRMWInst(BinOp Operation, Value *Ptr, Value *Val, Align Alignment,
AtomicOrdering Ordering, SyncScope::ID SSID,
BasicBlock *InsertAtEnd);
@@ -766,9 +768,16 @@ public:
return User::operator new(s, 2);
}
- BinOp getOperation() const {
- return static_cast<BinOp>(getSubclassDataFromInstruction() >> 5);
- }
+ using VolatileField = BoolBitfieldElementT<0>;
+ using AtomicOrderingField =
+ AtomicOrderingBitfieldElementT<VolatileField::NextBit>;
+ using OperationField = BinOpBitfieldElement<AtomicOrderingField::NextBit>;
+ using AlignmentField = AlignmentBitfieldElementT<OperationField::NextBit>;
+ static_assert(Bitfield::areContiguous<VolatileField, AtomicOrderingField,
+ OperationField, AlignmentField>(),
+ "Bitfields must be contiguous");
+
+ BinOp getOperation() const { return getSubclassData<OperationField>(); }
static StringRef getOperationName(BinOp Op);
@@ -783,38 +792,40 @@ public:
}
void setOperation(BinOp Operation) {
- unsigned short SubclassData = getSubclassDataFromInstruction();
- setInstructionSubclassData((SubclassData & 31) |
- (Operation << 5));
+ setSubclassData<OperationField>(Operation);
+ }
+
+ /// Return the alignment of the memory that is being allocated by the
+ /// instruction.
+ Align getAlign() const {
+ return Align(1ULL << getSubclassData<AlignmentField>());
+ }
+
+ void setAlignment(Align Align) {
+ setSubclassData<AlignmentField>(Log2(Align));
}
/// Return true if this is a RMW on a volatile memory location.
///
- bool isVolatile() const {
- return getSubclassDataFromInstruction() & 1;
- }
+ bool isVolatile() const { return getSubclassData<VolatileField>(); }
/// Specify whether this is a volatile RMW or not.
///
- void setVolatile(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- (unsigned)V);
- }
+ void setVolatile(bool V) { setSubclassData<VolatileField>(V); }
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Returns the ordering constraint of this rmw instruction.
AtomicOrdering getOrdering() const {
- return AtomicOrdering((getSubclassDataFromInstruction() >> 2) & 7);
+ return getSubclassData<AtomicOrderingField>();
}
/// Sets the ordering constraint of this rmw instruction.
void setOrdering(AtomicOrdering Ordering) {
assert(Ordering != AtomicOrdering::NotAtomic &&
"atomicrmw instructions can only be atomic.");
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~(7 << 2)) |
- ((unsigned)Ordering << 2));
+ setSubclassData<AtomicOrderingField>(Ordering);
}
/// Returns the synchronization scope ID of this rmw instruction.
@@ -852,13 +863,14 @@ public:
}
private:
- void Init(BinOp Operation, Value *Ptr, Value *Val,
+ void Init(BinOp Operation, Value *Ptr, Value *Val, Align Align,
AtomicOrdering Ordering, SyncScope::ID SSID);
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
/// The synchronization scope ID of this rmw instruction. Not quite enough
@@ -1004,16 +1016,23 @@ public:
return getPointerAddressSpace();
}
- /// Returns the type of the element that would be loaded with
- /// a load instruction with the specified parameters.
+ /// Returns the result type of a getelementptr with the given source
+ /// element type and indexes.
///
/// Null is returned if the indices are invalid for the specified
- /// pointer type.
- ///
+ /// source element type.
static Type *getIndexedType(Type *Ty, ArrayRef<Value *> IdxList);
static Type *getIndexedType(Type *Ty, ArrayRef<Constant *> IdxList);
static Type *getIndexedType(Type *Ty, ArrayRef<uint64_t> IdxList);
+ /// Return the type of the element at the given index of an indexable
+ /// type. This is equivalent to "getIndexedType(Agg, {Zero, Idx})".
+ ///
+ /// Returns null if the type can't be indexed, or the given index is not
+ /// legal for the given type.
+ static Type *getTypeAtIndex(Type *Ty, Value *Idx);
+ static Type *getTypeAtIndex(Type *Ty, uint64_t Idx);
+
inline op_iterator idx_begin() { return op_begin()+1; }
inline const_op_iterator idx_begin() const { return op_begin()+1; }
inline op_iterator idx_end() { return op_end(); }
@@ -1055,14 +1074,14 @@ public:
Type *PtrTy = PointerType::get(checkGEPType(getIndexedType(ElTy, IdxList)),
Ptr->getType()->getPointerAddressSpace());
// Vector GEP
- if (Ptr->getType()->isVectorTy()) {
- unsigned NumElem = Ptr->getType()->getVectorNumElements();
- return VectorType::get(PtrTy, NumElem);
+ if (auto *PtrVTy = dyn_cast<VectorType>(Ptr->getType())) {
+ ElementCount EltCount = PtrVTy->getElementCount();
+ return VectorType::get(PtrTy, EltCount);
}
for (Value *Index : IdxList)
- if (Index->getType()->isVectorTy()) {
- unsigned NumElem = Index->getType()->getVectorNumElements();
- return VectorType::get(PtrTy, NumElem);
+ if (auto *IndexVTy = dyn_cast<VectorType>(Index->getType())) {
+ ElementCount EltCount = IndexVTy->getElementCount();
+ return VectorType::get(PtrTy, EltCount);
}
// Scalar GEP
return PtrTy;
@@ -1532,58 +1551,6 @@ public:
NameStr, InsertAtEnd);
}
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, NameStr, InsertBefore);
- }
-
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
- const Twine &NameStr,
- Instruction *InsertBefore = nullptr) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, Args, NameStr, InsertBefore);
- }
-
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles = None,
- const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, Args, Bundles, NameStr, InsertBefore);
- }
-
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, const Twine &NameStr,
- BasicBlock *InsertAtEnd) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, NameStr, InsertAtEnd);
- }
-
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
- const Twine &NameStr, BasicBlock *InsertAtEnd) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, Args, NameStr, InsertAtEnd);
- }
-
- // Deprecated [opaque pointer types]
- static CallInst *Create(Value *Func, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles,
- const Twine &NameStr, BasicBlock *InsertAtEnd) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, Args, Bundles, NameStr, InsertAtEnd);
- }
-
/// Create a clone of \p CI with a different set of operand bundles and
/// insert it before \p InsertPt.
///
@@ -1632,37 +1599,38 @@ public:
BasicBlock *InsertAtEnd);
// Note that 'musttail' implies 'tail'.
- enum TailCallKind {
+ enum TailCallKind : unsigned {
TCK_None = 0,
TCK_Tail = 1,
TCK_MustTail = 2,
- TCK_NoTail = 3
+ TCK_NoTail = 3,
+ TCK_LAST = TCK_NoTail
};
+
+ using TailCallKindField = Bitfield::Element<TailCallKind, 0, 2, TCK_LAST>;
+ static_assert(
+ Bitfield::areContiguous<TailCallKindField, CallBase::CallingConvField>(),
+ "Bitfields must be contiguous");
+
TailCallKind getTailCallKind() const {
- return TailCallKind(getSubclassDataFromInstruction() & 3);
+ return getSubclassData<TailCallKindField>();
}
bool isTailCall() const {
- unsigned Kind = getSubclassDataFromInstruction() & 3;
+ TailCallKind Kind = getTailCallKind();
return Kind == TCK_Tail || Kind == TCK_MustTail;
}
- bool isMustTailCall() const {
- return (getSubclassDataFromInstruction() & 3) == TCK_MustTail;
- }
+ bool isMustTailCall() const { return getTailCallKind() == TCK_MustTail; }
- bool isNoTailCall() const {
- return (getSubclassDataFromInstruction() & 3) == TCK_NoTail;
- }
+ bool isNoTailCall() const { return getTailCallKind() == TCK_NoTail; }
- void setTailCall(bool isTC = true) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) |
- unsigned(isTC ? TCK_Tail : TCK_None));
+ void setTailCallKind(TailCallKind TCK) {
+ setSubclassData<TailCallKindField>(TCK);
}
- void setTailCallKind(TailCallKind TCK) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~3) |
- unsigned(TCK));
+ void setTailCall(bool IsTc = true) {
+ setTailCallKind(IsTc ? TCK_Tail : TCK_None);
}
/// Return true if the call can return twice
@@ -1685,8 +1653,9 @@ public:
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
};
@@ -1977,10 +1946,22 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertElementInst, Value)
// ShuffleVectorInst Class
//===----------------------------------------------------------------------===//
+constexpr int UndefMaskElem = -1;
+
/// This instruction constructs a fixed permutation of two
/// input vectors.
///
+/// For each element of the result vector, the shuffle mask selects an element
+/// from one of the input vectors to copy to the result. Non-negative elements
+/// in the mask represent an index into the concatenated pair of input vectors.
+/// UndefMaskElem (-1) specifies that the result element is undefined.
+///
+/// For scalable vectors, all the elements of the mask must be 0 or -1. This
+/// requirement may be relaxed in the future.
class ShuffleVectorInst : public Instruction {
+ SmallVector<int, 4> ShuffleMask;
+ Constant *ShuffleMaskForBitcode;
+
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
@@ -1993,13 +1974,15 @@ public:
Instruction *InsertBefor = nullptr);
ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
const Twine &NameStr, BasicBlock *InsertAtEnd);
+ ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
+ const Twine &NameStr = "",
+ Instruction *InsertBefor = nullptr);
+ ShuffleVectorInst(Value *V1, Value *V2, ArrayRef<int> Mask,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
- // allocate space for exactly three operands
- void *operator new(size_t s) {
- return User::operator new(s, 3);
- }
+ void *operator new(size_t s) { return User::operator new(s, 2); }
- /// Swap the first 2 operands and adjust the mask to preserve the semantics
+ /// Swap the operands and adjust the mask to preserve the semantics
/// of the instruction.
void commute();
@@ -2007,6 +1990,8 @@ public:
/// formed with the specified operands.
static bool isValidOperands(const Value *V1, const Value *V2,
const Value *Mask);
+ static bool isValidOperands(const Value *V1, const Value *V2,
+ ArrayRef<int> Mask);
/// Overload to return most specific vector type.
///
@@ -2017,44 +2002,42 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- Constant *getMask() const {
- return cast<Constant>(getOperand(2));
- }
-
- /// Return the shuffle mask value for the specified element of the mask.
- /// Return -1 if the element is undef.
- static int getMaskValue(const Constant *Mask, unsigned Elt);
-
/// Return the shuffle mask value of this instruction for the given element
- /// index. Return -1 if the element is undef.
- int getMaskValue(unsigned Elt) const {
- return getMaskValue(getMask(), Elt);
- }
+ /// index. Return UndefMaskElem if the element is undef.
+ int getMaskValue(unsigned Elt) const { return ShuffleMask[Elt]; }
/// Convert the input shuffle mask operand to a vector of integers. Undefined
- /// elements of the mask are returned as -1.
+ /// elements of the mask are returned as UndefMaskElem.
static void getShuffleMask(const Constant *Mask,
SmallVectorImpl<int> &Result);
/// Return the mask for this instruction as a vector of integers. Undefined
- /// elements of the mask are returned as -1.
+ /// elements of the mask are returned as UndefMaskElem.
void getShuffleMask(SmallVectorImpl<int> &Result) const {
- return getShuffleMask(getMask(), Result);
+ Result.assign(ShuffleMask.begin(), ShuffleMask.end());
}
- SmallVector<int, 16> getShuffleMask() const {
- SmallVector<int, 16> Mask;
- getShuffleMask(Mask);
- return Mask;
- }
+ /// Return the mask for this instruction, for use in bitcode.
+ ///
+ /// TODO: This is temporary until we decide a new bitcode encoding for
+ /// shufflevector.
+ Constant *getShuffleMaskForBitcode() const { return ShuffleMaskForBitcode; }
+
+ static Constant *convertShuffleMaskForBitcode(ArrayRef<int> Mask,
+ Type *ResultTy);
+
+ void setShuffleMask(ArrayRef<int> Mask);
+
+ ArrayRef<int> getShuffleMask() const { return ShuffleMask; }
/// Return true if this shuffle returns a vector with a different number of
/// elements than its source vectors.
/// Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3>
/// shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5>
bool changesLength() const {
- unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements();
- unsigned NumMaskElts = getMask()->getType()->getVectorNumElements();
+ unsigned NumSourceElts =
+ cast<VectorType>(Op<0>()->getType())->getElementCount().Min;
+ unsigned NumMaskElts = ShuffleMask.size();
return NumSourceElts != NumMaskElts;
}
@@ -2062,8 +2045,9 @@ public:
/// elements than its source vectors.
/// Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3>
bool increasesLength() const {
- unsigned NumSourceElts = Op<0>()->getType()->getVectorNumElements();
- unsigned NumMaskElts = getMask()->getType()->getVectorNumElements();
+ unsigned NumSourceElts =
+ cast<VectorType>(Op<0>()->getType())->getNumElements();
+ unsigned NumMaskElts = ShuffleMask.size();
return NumSourceElts < NumMaskElts;
}
@@ -2084,7 +2068,7 @@ public:
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
/// TODO: Optionally allow length-changing shuffles.
bool isSingleSource() const {
- return !changesLength() && isSingleSourceMask(getMask());
+ return !changesLength() && isSingleSourceMask(ShuffleMask);
}
/// Return true if this shuffle mask chooses elements from exactly one source
@@ -2105,7 +2089,7 @@ public:
/// from its input vectors.
/// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
bool isIdentity() const {
- return !changesLength() && isIdentityMask(getShuffleMask());
+ return !changesLength() && isIdentityMask(ShuffleMask);
}
/// Return true if this shuffle lengthens exactly one source vector with
@@ -2146,7 +2130,7 @@ public:
/// In that case, the shuffle is better classified as an identity shuffle.
/// TODO: Optionally allow length-changing shuffles.
bool isSelect() const {
- return !changesLength() && isSelectMask(getMask());
+ return !changesLength() && isSelectMask(ShuffleMask);
}
/// Return true if this shuffle mask swaps the order of elements from exactly
@@ -2166,7 +2150,7 @@ public:
/// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
/// TODO: Optionally allow length-changing shuffles.
bool isReverse() const {
- return !changesLength() && isReverseMask(getMask());
+ return !changesLength() && isReverseMask(ShuffleMask);
}
/// Return true if this shuffle mask chooses all elements with the same value
@@ -2188,7 +2172,7 @@ public:
/// TODO: Optionally allow length-changing shuffles.
/// TODO: Optionally allow splats from other elements.
bool isZeroEltSplat() const {
- return !changesLength() && isZeroEltSplatMask(getMask());
+ return !changesLength() && isZeroEltSplatMask(ShuffleMask);
}
/// Return true if this shuffle mask is a transpose mask.
@@ -2237,7 +2221,7 @@ public:
/// exact specification.
/// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
bool isTranspose() const {
- return !changesLength() && isTransposeMask(getMask());
+ return !changesLength() && isTransposeMask(ShuffleMask);
}
/// Return true if this shuffle mask is an extract subvector mask.
@@ -2255,8 +2239,8 @@ public:
/// Return true if this shuffle mask is an extract subvector mask.
bool isExtractSubvectorMask(int &Index) const {
- int NumSrcElts = Op<0>()->getType()->getVectorNumElements();
- return isExtractSubvectorMask(getMask(), NumSrcElts, Index);
+ int NumSrcElts = cast<VectorType>(Op<0>()->getType())->getNumElements();
+ return isExtractSubvectorMask(ShuffleMask, NumSrcElts, Index);
}
/// Change values in a shuffle permute mask assuming the two vector operands
@@ -2282,9 +2266,8 @@ public:
};
template <>
-struct OperandTraits<ShuffleVectorInst> :
- public FixedNumOperandTraits<ShuffleVectorInst, 3> {
-};
+struct OperandTraits<ShuffleVectorInst>
+ : public FixedNumOperandTraits<ShuffleVectorInst, 2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ShuffleVectorInst, Value)
@@ -2610,15 +2593,11 @@ public:
using const_block_iterator = BasicBlock * const *;
block_iterator block_begin() {
- Use::UserRef *ref =
- reinterpret_cast<Use::UserRef*>(op_begin() + ReservedSpace);
- return reinterpret_cast<block_iterator>(ref + 1);
+ return reinterpret_cast<block_iterator>(op_begin() + ReservedSpace);
}
const_block_iterator block_begin() const {
- const Use::UserRef *ref =
- reinterpret_cast<const Use::UserRef*>(op_begin() + ReservedSpace);
- return reinterpret_cast<const_block_iterator>(ref + 1);
+ return reinterpret_cast<const_block_iterator>(op_begin() + ReservedSpace);
}
block_iterator block_end() {
@@ -2795,6 +2774,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value)
/// cleanup.
///
class LandingPadInst : public Instruction {
+ using CleanupField = BoolBitfieldElementT<0>;
+
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -2839,13 +2820,10 @@ public:
/// Return 'true' if this landingpad instruction is a
/// cleanup. I.e., it should be run when unwinding even if its landing pad
/// doesn't catch the exception.
- bool isCleanup() const { return getSubclassDataFromInstruction() & 1; }
+ bool isCleanup() const { return getSubclassData<CleanupField>(); }
/// Indicate that this landingpad instruction is a cleanup.
- void setCleanup(bool V) {
- setInstructionSubclassData((getSubclassDataFromInstruction() & ~1) |
- (V ? 1 : 0));
- }
+ void setCleanup(bool V) { setSubclassData<CleanupField>(V); }
/// Add a catch or filter clause to the landing pad.
void addClause(Constant *ClauseVal);
@@ -3781,49 +3759,6 @@ public:
IfException, Args, Bundles, NameStr, InsertAtEnd);
}
- // Deprecated [opaque pointer types]
- static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- const Twine &NameStr,
- Instruction *InsertBefore = nullptr) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, IfNormal, IfException, Args, None, NameStr,
- InsertBefore);
- }
-
- // Deprecated [opaque pointer types]
- static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles = None,
- const Twine &NameStr = "",
- Instruction *InsertBefore = nullptr) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, IfNormal, IfException, Args, Bundles, NameStr,
- InsertBefore);
- }
-
- // Deprecated [opaque pointer types]
- static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- const Twine &NameStr, BasicBlock *InsertAtEnd) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, IfNormal, IfException, Args, NameStr, InsertAtEnd);
- }
-
- // Deprecated [opaque pointer types]
- static InvokeInst *Create(Value *Func, BasicBlock *IfNormal,
- BasicBlock *IfException, ArrayRef<Value *> Args,
- ArrayRef<OperandBundleDef> Bundles,
- const Twine &NameStr, BasicBlock *InsertAtEnd) {
- return Create(cast<FunctionType>(
- cast<PointerType>(Func->getType())->getElementType()),
- Func, IfNormal, IfException, Args, Bundles, NameStr,
- InsertAtEnd);
- }
-
/// Create a clone of \p II with a different set of operand bundles and
/// insert it before \p InsertPt.
///
@@ -3833,15 +3768,6 @@ public:
static InvokeInst *Create(InvokeInst *II, ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertPt = nullptr);
- /// Determine if the call should not perform indirect branch tracking.
- bool doesNoCfCheck() const { return hasFnAttr(Attribute::NoCfCheck); }
-
- /// Determine if the call cannot unwind.
- bool doesNotThrow() const { return hasFnAttr(Attribute::NoUnwind); }
- void setDoesNotThrow() {
- addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind);
- }
-
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const {
return cast<BasicBlock>(Op<NormalDestOpEndIdx>());
@@ -3884,11 +3810,11 @@ public:
}
private:
-
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
};
@@ -4124,11 +4050,11 @@ public:
}
private:
-
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
};
@@ -4219,6 +4145,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
// CatchSwitchInst Class
//===----------------------------------------------------------------------===//
class CatchSwitchInst : public Instruction {
+ using UnwindDestField = BoolBitfieldElementT<0>;
+
/// The number of operands actually allocated. NumOperands is
/// the number actually in use.
unsigned ReservedSpace;
@@ -4280,7 +4208,7 @@ public:
void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); }
// Accessor Methods for CatchSwitch stmt
- bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool hasUnwindDest() const { return getSubclassData<UnwindDestField>(); }
bool unwindsToCaller() const { return !hasUnwindDest(); }
BasicBlock *getUnwindDest() const {
if (hasUnwindDest())
@@ -4566,6 +4494,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
//===----------------------------------------------------------------------===//
class CleanupReturnInst : public Instruction {
+ using UnwindDestField = BoolBitfieldElementT<0>;
+
private:
CleanupReturnInst(const CleanupReturnInst &RI);
CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values,
@@ -4606,7 +4536,7 @@ public:
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
+ bool hasUnwindDest() const { return getSubclassData<UnwindDestField>(); }
bool unwindsToCaller() const { return !hasUnwindDest(); }
/// Convenience accessor.
@@ -4650,8 +4580,9 @@ private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
- void setInstructionSubclassData(unsigned short D) {
- Instruction::setInstructionSubclassData(D);
+ template <typename Bitfield>
+ void setSubclassData(typename Bitfield::Type Value) {
+ Instruction::setSubclassData<Bitfield>(Value);
}
};
@@ -5283,12 +5214,12 @@ inline Value *getPointerOperand(Value *V) {
}
/// A helper function that returns the alignment of load or store instruction.
-inline MaybeAlign getLoadStoreAlignment(Value *I) {
+inline Align getLoadStoreAlignment(Value *I) {
assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
"Expected Load or Store instruction");
if (auto *LI = dyn_cast<LoadInst>(I))
- return MaybeAlign(LI->getAlignment());
- return MaybeAlign(cast<StoreInst>(I)->getAlignment());
+ return LI->getAlign();
+ return cast<StoreInst>(I)->getAlign();
}
/// A helper function that returns the address space of the pointer operand of
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h
index 42a5564a4488..7a8898464e66 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicInst.h
@@ -38,829 +38,904 @@
namespace llvm {
- /// A wrapper class for inspecting calls to intrinsic functions.
- /// This allows the standard isa/dyncast/cast functionality to work with calls
- /// to intrinsic functions.
- class IntrinsicInst : public CallInst {
- public:
- IntrinsicInst() = delete;
- IntrinsicInst(const IntrinsicInst &) = delete;
- IntrinsicInst &operator=(const IntrinsicInst &) = delete;
-
- /// Return the intrinsic ID of this intrinsic.
- Intrinsic::ID getIntrinsicID() const {
- return getCalledFunction()->getIntrinsicID();
- }
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const CallInst *I) {
- if (const Function *CF = I->getCalledFunction())
- return CF->isIntrinsic();
+/// A wrapper class for inspecting calls to intrinsic functions.
+/// This allows the standard isa/dyncast/cast functionality to work with calls
+/// to intrinsic functions.
+class IntrinsicInst : public CallInst {
+public:
+ IntrinsicInst() = delete;
+ IntrinsicInst(const IntrinsicInst &) = delete;
+ IntrinsicInst &operator=(const IntrinsicInst &) = delete;
+
+ /// Return the intrinsic ID of this intrinsic.
+ Intrinsic::ID getIntrinsicID() const {
+ return getCalledFunction()->getIntrinsicID();
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const CallInst *I) {
+ if (const Function *CF = I->getCalledFunction())
+ return CF->isIntrinsic();
+ return false;
+ }
+ static bool classof(const Value *V) {
+ return isa<CallInst>(V) && classof(cast<CallInst>(V));
+ }
+};
+
+/// Check if \p ID corresponds to a debug info intrinsic.
+static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) {
+ switch (ID) {
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ case Intrinsic::dbg_addr:
+ case Intrinsic::dbg_label:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/// This is the common base class for debug info intrinsics.
+class DbgInfoIntrinsic : public IntrinsicInst {
+public:
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return isDbgInfoIntrinsic(I->getIntrinsicID());
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
+/// This is the common base class for debug info intrinsics for variables.
+class DbgVariableIntrinsic : public DbgInfoIntrinsic {
+public:
+ /// Get the location corresponding to the variable referenced by the debug
+ /// info intrinsic. Depending on the intrinsic, this could be the
+ /// variable's value or its address.
+ Value *getVariableLocation(bool AllowNullOp = true) const;
+
+ /// Does this describe the address of a local variable. True for dbg.addr
+ /// and dbg.declare, but not dbg.value, which describes its value.
+ bool isAddressOfVariable() const {
+ return getIntrinsicID() != Intrinsic::dbg_value;
+ }
+
+ DILocalVariable *getVariable() const {
+ return cast<DILocalVariable>(getRawVariable());
+ }
+
+ DIExpression *getExpression() const {
+ return cast<DIExpression>(getRawExpression());
+ }
+
+ Metadata *getRawVariable() const {
+ return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
+ }
+
+ Metadata *getRawExpression() const {
+ return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
+ }
+
+ /// Get the size (in bits) of the variable, or fragment of the variable that
+ /// is described.
+ Optional<uint64_t> getFragmentSizeInBits() const;
+
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::dbg_declare:
+ case Intrinsic::dbg_value:
+ case Intrinsic::dbg_addr:
+ return true;
+ default:
return false;
}
- static bool classof(const Value *V) {
- return isa<CallInst>(V) && classof(cast<CallInst>(V));
- }
- };
-
- /// This is the common base class for debug info intrinsics.
- class DbgInfoIntrinsic : public IntrinsicInst {
- public:
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_addr:
- case Intrinsic::dbg_label:
- return true;
- default: return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
-
- /// This is the common base class for debug info intrinsics for variables.
- class DbgVariableIntrinsic : public DbgInfoIntrinsic {
- public:
- /// Get the location corresponding to the variable referenced by the debug
- /// info intrinsic. Depending on the intrinsic, this could be the
- /// variable's value or its address.
- Value *getVariableLocation(bool AllowNullOp = true) const;
-
- /// Does this describe the address of a local variable. True for dbg.addr
- /// and dbg.declare, but not dbg.value, which describes its value.
- bool isAddressOfVariable() const {
- return getIntrinsicID() != Intrinsic::dbg_value;
- }
-
- DILocalVariable *getVariable() const {
- return cast<DILocalVariable>(getRawVariable());
- }
-
- DIExpression *getExpression() const {
- return cast<DIExpression>(getRawExpression());
- }
-
- Metadata *getRawVariable() const {
- return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
- }
-
- Metadata *getRawExpression() const {
- return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
- }
-
- /// Get the size (in bits) of the variable, or fragment of the variable that
- /// is described.
- Optional<uint64_t> getFragmentSizeInBits() const;
-
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::dbg_declare:
- case Intrinsic::dbg_value:
- case Intrinsic::dbg_addr:
- return true;
- default: return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
-
- /// This represents the llvm.dbg.declare instruction.
- class DbgDeclareInst : public DbgVariableIntrinsic {
- public:
- Value *getAddress() const { return getVariableLocation(); }
-
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_declare;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
-
- /// This represents the llvm.dbg.addr instruction.
- class DbgAddrIntrinsic : public DbgVariableIntrinsic {
- public:
- Value *getAddress() const { return getVariableLocation(); }
-
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_addr;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This represents the llvm.dbg.value instruction.
- class DbgValueInst : public DbgVariableIntrinsic {
- public:
- Value *getValue() const {
- return getVariableLocation(/* AllowNullOp = */ false);
- }
-
- /// \name Casting methods
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_value;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
-
- /// This represents the llvm.dbg.label instruction.
- class DbgLabelInst : public DbgInfoIntrinsic {
- public:
- DILabel *getLabel() const {
- return cast<DILabel>(getRawLabel());
- }
-
- Metadata *getRawLabel() const {
- return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
- }
-
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
- /// @{
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::dbg_label;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- /// @}
- };
-
- /// This is the common base class for constrained floating point intrinsics.
- class ConstrainedFPIntrinsic : public IntrinsicInst {
- public:
- bool isUnaryOp() const;
- bool isTernaryOp() const;
- Optional<fp::RoundingMode> getRoundingMode() const;
- Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I);
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// Constrained floating point compare intrinsics.
- class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
- public:
- FCmpInst::Predicate getPredicate() const;
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::experimental_constrained_fcmp:
- case Intrinsic::experimental_constrained_fcmps:
- return true;
- default: return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents an intrinsic that is based on a binary operation.
- /// This includes op.with.overflow and saturating add/sub intrinsics.
- class BinaryOpIntrinsic : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::usub_with_overflow:
- case Intrinsic::ssub_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow:
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::ssub_sat:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); }
- Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); }
-
- /// Returns the binary operation underlying the intrinsic.
- Instruction::BinaryOps getBinaryOp() const;
-
- /// Whether the intrinsic is signed or unsigned.
- bool isSigned() const;
-
- /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
- unsigned getNoWrapKind() const;
- };
-
- /// Represents an op.with.overflow intrinsic.
- class WithOverflowInst : public BinaryOpIntrinsic {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_with_overflow:
- case Intrinsic::sadd_with_overflow:
- case Intrinsic::usub_with_overflow:
- case Intrinsic::ssub_with_overflow:
- case Intrinsic::umul_with_overflow:
- case Intrinsic::smul_with_overflow:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// Represents a saturating add/sub intrinsic.
- class SaturatingInst : public BinaryOpIntrinsic {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::uadd_sat:
- case Intrinsic::sadd_sat:
- case Intrinsic::usub_sat:
- case Intrinsic::ssub_sat:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// Common base class for all memory intrinsics. Simply provides
- /// common methods.
- /// Written as CRTP to avoid a common base class amongst the
- /// three atomicity hierarchies.
- template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
- private:
- enum { ARG_DEST = 0, ARG_LENGTH = 2 };
-
- public:
- Value *getRawDest() const {
- return const_cast<Value *>(getArgOperand(ARG_DEST));
- }
- const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
- Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
-
- Value *getLength() const {
- return const_cast<Value *>(getArgOperand(ARG_LENGTH));
- }
- const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
- Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
-
- /// This is just like getRawDest, but it strips off any cast
- /// instructions (including addrspacecast) that feed it, giving the
- /// original input. The returned value is guaranteed to be a pointer.
- Value *getDest() const { return getRawDest()->stripPointerCasts(); }
-
- unsigned getDestAddressSpace() const {
- return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
+/// This represents the llvm.dbg.declare instruction.
+class DbgDeclareInst : public DbgVariableIntrinsic {
+public:
+ Value *getAddress() const { return getVariableLocation(); }
+
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_declare;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
+/// This represents the llvm.dbg.addr instruction.
+class DbgAddrIntrinsic : public DbgVariableIntrinsic {
+public:
+ Value *getAddress() const { return getVariableLocation(); }
+
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_addr;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This represents the llvm.dbg.value instruction.
+class DbgValueInst : public DbgVariableIntrinsic {
+public:
+ Value *getValue() const {
+ return getVariableLocation(/* AllowNullOp = */ false);
+ }
+
+ /// \name Casting methods
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_value;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
+/// This represents the llvm.dbg.label instruction.
+class DbgLabelInst : public DbgInfoIntrinsic {
+public:
+ DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); }
+
+ Metadata *getRawLabel() const {
+ return cast<MetadataAsValue>(getArgOperand(0))->getMetadata();
+ }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ /// @{
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_label;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ /// @}
+};
+
+/// This is the common base class for vector predication intrinsics.
+class VPIntrinsic : public IntrinsicInst {
+public:
+ static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID);
+ static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID);
+
+ /// The llvm.vp.* intrinsics for this instruction Opcode
+ static Intrinsic::ID GetForOpcode(unsigned OC);
+
+ // Whether \p ID is a VP intrinsic ID.
+ static bool IsVPIntrinsic(Intrinsic::ID);
+
+ /// \return the mask parameter or nullptr.
+ Value *getMaskParam() const;
+
+ /// \return the vector length parameter or nullptr.
+ Value *getVectorLengthParam() const;
+
+ /// \return whether the vector length param can be ignored.
+ bool canIgnoreVectorLengthParam() const;
+
+ /// \return the static element count (vector number of elements) the vector
+ /// length parameter applies to.
+ ElementCount getStaticVectorLength() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return IsVPIntrinsic(I->getIntrinsicID());
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ // Equivalent non-predicated opcode
+ unsigned getFunctionalOpcode() const {
+ return GetFunctionalOpcodeForVP(getIntrinsicID());
+ }
+
+ // Equivalent non-predicated opcode
+ static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID);
+};
+
+/// This is the common base class for constrained floating point intrinsics.
+class ConstrainedFPIntrinsic : public IntrinsicInst {
+public:
+ bool isUnaryOp() const;
+ bool isTernaryOp() const;
+ Optional<RoundingMode> getRoundingMode() const;
+ Optional<fp::ExceptionBehavior> getExceptionBehavior() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I);
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// Constrained floating point compare intrinsics.
+class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic {
+public:
+ FCmpInst::Predicate getPredicate() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::experimental_constrained_fcmp:
+ case Intrinsic::experimental_constrained_fcmps:
+ return true;
+ default:
+ return false;
}
-
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getDestAlign() instead.
- unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); }
- MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
-
- /// Set the specified arguments of the instruction.
- void setDest(Value *Ptr) {
- assert(getRawDest()->getType() == Ptr->getType() &&
- "setDest called with pointer of wrong type!");
- setArgOperand(ARG_DEST, Ptr);
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents an intrinsic that is based on a binary operation.
+/// This includes op.with.overflow and saturating add/sub intrinsics.
+class BinaryOpIntrinsic : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::usub_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::usub_sat:
+ case Intrinsic::ssub_sat:
+ return true;
+ default:
+ return false;
}
-
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- void setDestAlignment(unsigned Alignment) {
- setDestAlignment(MaybeAlign(Alignment));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); }
+ Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); }
+
+ /// Returns the binary operation underlying the intrinsic.
+ Instruction::BinaryOps getBinaryOp() const;
+
+ /// Whether the intrinsic is signed or unsigned.
+ bool isSigned() const;
+
+ /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
+ unsigned getNoWrapKind() const;
+};
+
+/// Represents an op.with.overflow intrinsic.
+class WithOverflowInst : public BinaryOpIntrinsic {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::uadd_with_overflow:
+ case Intrinsic::sadd_with_overflow:
+ case Intrinsic::usub_with_overflow:
+ case Intrinsic::ssub_with_overflow:
+ case Intrinsic::umul_with_overflow:
+ case Intrinsic::smul_with_overflow:
+ return true;
+ default:
+ return false;
}
- void setDestAlignment(MaybeAlign Alignment) {
- removeParamAttr(ARG_DEST, Attribute::Alignment);
- if (Alignment)
- addParamAttr(ARG_DEST,
- Attribute::getWithAlignment(getContext(), *Alignment));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// Represents a saturating add/sub intrinsic.
+class SaturatingInst : public BinaryOpIntrinsic {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::uadd_sat:
+ case Intrinsic::sadd_sat:
+ case Intrinsic::usub_sat:
+ case Intrinsic::ssub_sat:
+ return true;
+ default:
+ return false;
}
- void setDestAlignment(Align Alignment) {
- removeParamAttr(ARG_DEST, Attribute::Alignment);
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// Common base class for all memory intrinsics. Simply provides
+/// common methods.
+/// Written as CRTP to avoid a common base class amongst the
+/// three atomicity hierarchies.
+template <typename Derived> class MemIntrinsicBase : public IntrinsicInst {
+private:
+ enum { ARG_DEST = 0, ARG_LENGTH = 2 };
+
+public:
+ Value *getRawDest() const {
+ return const_cast<Value *>(getArgOperand(ARG_DEST));
+ }
+ const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); }
+ Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); }
+
+ Value *getLength() const {
+ return const_cast<Value *>(getArgOperand(ARG_LENGTH));
+ }
+ const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); }
+ Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); }
+
+ /// This is just like getRawDest, but it strips off any cast
+ /// instructions (including addrspacecast) that feed it, giving the
+ /// original input. The returned value is guaranteed to be a pointer.
+ Value *getDest() const { return getRawDest()->stripPointerCasts(); }
+
+ unsigned getDestAddressSpace() const {
+ return cast<PointerType>(getRawDest()->getType())->getAddressSpace();
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ /// Use getDestAlign() instead.
+ unsigned getDestAlignment() const {
+ if (auto MA = getParamAlign(ARG_DEST))
+ return MA->value();
+ return 0;
+ }
+ MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); }
+
+ /// Set the specified arguments of the instruction.
+ void setDest(Value *Ptr) {
+ assert(getRawDest()->getType() == Ptr->getType() &&
+ "setDest called with pointer of wrong type!");
+ setArgOperand(ARG_DEST, Ptr);
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ /// Use the version that takes MaybeAlign instead of this one.
+ void setDestAlignment(unsigned Alignment) {
+ setDestAlignment(MaybeAlign(Alignment));
+ }
+ void setDestAlignment(MaybeAlign Alignment) {
+ removeParamAttr(ARG_DEST, Attribute::Alignment);
+ if (Alignment)
addParamAttr(ARG_DEST,
- Attribute::getWithAlignment(getContext(), Alignment));
- }
-
- void setLength(Value *L) {
- assert(getLength()->getType() == L->getType() &&
- "setLength called with value of wrong type!");
- setArgOperand(ARG_LENGTH, L);
- }
- };
-
- /// Common base class for all memory transfer intrinsics. Simply provides
- /// common methods.
- template <class BaseCL> class MemTransferBase : public BaseCL {
- private:
- enum { ARG_SOURCE = 1 };
-
- public:
- /// Return the arguments to the instruction.
- Value *getRawSource() const {
- return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
- }
- const Use &getRawSourceUse() const {
- return BaseCL::getArgOperandUse(ARG_SOURCE);
- }
- Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
-
- /// This is just like getRawSource, but it strips off any cast
- /// instructions that feed it, giving the original input. The returned
- /// value is guaranteed to be a pointer.
- Value *getSource() const { return getRawSource()->stripPointerCasts(); }
-
- unsigned getSourceAddressSpace() const {
- return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
- }
-
- /// FIXME: Remove this function once transition to Align is over.
- /// Use getSourceAlign() instead.
- unsigned getSourceAlignment() const {
- return BaseCL::getParamAlignment(ARG_SOURCE);
- }
-
- MaybeAlign getSourceAlign() const {
- return BaseCL::getParamAlign(ARG_SOURCE);
- }
-
- void setSource(Value *Ptr) {
- assert(getRawSource()->getType() == Ptr->getType() &&
- "setSource called with pointer of wrong type!");
- BaseCL::setArgOperand(ARG_SOURCE, Ptr);
- }
-
- /// FIXME: Remove this function once transition to Align is over.
- /// Use the version that takes MaybeAlign instead of this one.
- void setSourceAlignment(unsigned Alignment) {
- setSourceAlignment(MaybeAlign(Alignment));
- }
- void setSourceAlignment(MaybeAlign Alignment) {
- BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
- if (Alignment)
- BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
- BaseCL::getContext(), *Alignment));
- }
- void setSourceAlignment(Align Alignment) {
- BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
+ Attribute::getWithAlignment(getContext(), *Alignment));
+ }
+ void setDestAlignment(Align Alignment) {
+ removeParamAttr(ARG_DEST, Attribute::Alignment);
+ addParamAttr(ARG_DEST,
+ Attribute::getWithAlignment(getContext(), Alignment));
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setArgOperand(ARG_LENGTH, L);
+ }
+};
+
+/// Common base class for all memory transfer intrinsics. Simply provides
+/// common methods.
+template <class BaseCL> class MemTransferBase : public BaseCL {
+private:
+ enum { ARG_SOURCE = 1 };
+
+public:
+ /// Return the arguments to the instruction.
+ Value *getRawSource() const {
+ return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE));
+ }
+ const Use &getRawSourceUse() const {
+ return BaseCL::getArgOperandUse(ARG_SOURCE);
+ }
+ Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); }
+
+ /// This is just like getRawSource, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getSource() const { return getRawSource()->stripPointerCasts(); }
+
+ unsigned getSourceAddressSpace() const {
+ return cast<PointerType>(getRawSource()->getType())->getAddressSpace();
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ /// Use getSourceAlign() instead.
+ unsigned getSourceAlignment() const {
+ if (auto MA = BaseCL::getParamAlign(ARG_SOURCE))
+ return MA->value();
+ return 0;
+ }
+
+ MaybeAlign getSourceAlign() const {
+ return BaseCL::getParamAlign(ARG_SOURCE);
+ }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ BaseCL::setArgOperand(ARG_SOURCE, Ptr);
+ }
+
+ /// FIXME: Remove this function once transition to Align is over.
+ /// Use the version that takes MaybeAlign instead of this one.
+ void setSourceAlignment(unsigned Alignment) {
+ setSourceAlignment(MaybeAlign(Alignment));
+ }
+ void setSourceAlignment(MaybeAlign Alignment) {
+ BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
+ if (Alignment)
BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
- BaseCL::getContext(), Alignment));
- }
- };
-
- /// Common base class for all memset intrinsics. Simply provides
- /// common methods.
- template <class BaseCL> class MemSetBase : public BaseCL {
- private:
- enum { ARG_VALUE = 1 };
-
- public:
- Value *getValue() const {
- return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
- }
- const Use &getValueUse() const {
- return BaseCL::getArgOperandUse(ARG_VALUE);
- }
- Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
-
- void setValue(Value *Val) {
- assert(getValue()->getType() == Val->getType() &&
- "setValue called with value of wrong type!");
- BaseCL::setArgOperand(ARG_VALUE, Val);
- }
- };
-
- // The common base class for the atomic memset/memmove/memcpy intrinsics
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
- class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
- private:
- enum { ARG_ELEMENTSIZE = 3 };
-
- public:
- Value *getRawElementSizeInBytes() const {
- return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
- }
-
- ConstantInt *getElementSizeInBytesCst() const {
- return cast<ConstantInt>(getRawElementSizeInBytes());
- }
-
- uint32_t getElementSizeInBytes() const {
- return getElementSizeInBytesCst()->getZExtValue();
- }
-
- void setElementSizeInBytes(Constant *V) {
- assert(V->getType() == Type::getInt8Ty(getContext()) &&
- "setElementSizeInBytes called with value of wrong type!");
- setArgOperand(ARG_ELEMENTSIZE, V);
- }
-
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents atomic memset intrinsic
- // i.e. llvm.element.unordered.atomic.memset
- class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- // This class wraps the atomic memcpy/memmove intrinsics
- // i.e. llvm.element.unordered.atomic.memcpy/memmove
- class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents the atomic memcpy intrinsic
- /// i.e. llvm.element.unordered.atomic.memcpy
- class AtomicMemCpyInst : public AtomicMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents the atomic memmove intrinsic
- /// i.e. llvm.element.unordered.atomic.memmove
- class AtomicMemMoveInst : public AtomicMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This is the common base class for memset/memcpy/memmove.
- class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
- private:
- enum { ARG_VOLATILE = 3 };
-
- public:
- ConstantInt *getVolatileCst() const {
- return cast<ConstantInt>(
- const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
- }
-
- bool isVolatile() const {
- return !getVolatileCst()->isZero();
- }
-
- void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
-
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memset:
- return true;
- default: return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class wraps the llvm.memset intrinsic.
- class MemSetInst : public MemSetBase<MemIntrinsic> {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memset;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class wraps the llvm.memcpy/memmove intrinsics.
- class MemTransferInst : public MemTransferBase<MemIntrinsic> {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy ||
- I->getIntrinsicID() == Intrinsic::memmove;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class wraps the llvm.memcpy intrinsic.
- class MemCpyInst : public MemTransferInst {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memcpy;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class wraps the llvm.memmove intrinsic.
- class MemMoveInst : public MemTransferInst {
- public:
- // Methods for support type inquiry through isa, cast, and dyn_cast:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::memmove;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- // The common base class for any memset/memmove/memcpy intrinsics;
- // whether they be atomic or non-atomic.
- // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
- // and llvm.memset/memcpy/memmove
- class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
- public:
- bool isVolatile() const {
- // Only the non-atomic intrinsics can be volatile
- if (auto *MI = dyn_cast<MemIntrinsic>(this))
- return MI->isVolatile();
+ BaseCL::getContext(), *Alignment));
+ }
+ void setSourceAlignment(Align Alignment) {
+ BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment);
+ BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment(
+ BaseCL::getContext(), Alignment));
+ }
+};
+
+/// Common base class for all memset intrinsics. Simply provides
+/// common methods.
+template <class BaseCL> class MemSetBase : public BaseCL {
+private:
+ enum { ARG_VALUE = 1 };
+
+public:
+ Value *getValue() const {
+ return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE));
+ }
+ const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); }
+ Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); }
+
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setValue called with value of wrong type!");
+ BaseCL::setArgOperand(ARG_VALUE, Val);
+ }
+};
+
+// The common base class for the atomic memset/memmove/memcpy intrinsics
+// i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
+class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> {
+private:
+ enum { ARG_ELEMENTSIZE = 3 };
+
+public:
+ Value *getRawElementSizeInBytes() const {
+ return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE));
+ }
+
+ ConstantInt *getElementSizeInBytesCst() const {
+ return cast<ConstantInt>(getRawElementSizeInBytes());
+ }
+
+ uint32_t getElementSizeInBytes() const {
+ return getElementSizeInBytesCst()->getZExtValue();
+ }
+
+ void setElementSizeInBytes(Constant *V) {
+ assert(V->getType() == Type::getInt8Ty(getContext()) &&
+ "setElementSizeInBytes called with value of wrong type!");
+ setArgOperand(ARG_ELEMENTSIZE, V);
+ }
+
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
return false;
}
-
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memset:
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents any memset intrinsic
- // i.e. llvm.element.unordered.atomic.memset
- // and llvm.memset
- class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memset:
- case Intrinsic::memset_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- // This class wraps any memcpy/memmove intrinsics
- // i.e. llvm.element.unordered.atomic.memcpy/memmove
- // and llvm.memcpy/memmove
- class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memmove:
- case Intrinsic::memcpy_element_unordered_atomic:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents any memcpy intrinsic
- /// i.e. llvm.element.unordered.atomic.memcpy
- /// and llvm.memcpy
- class AnyMemCpyInst : public AnyMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memcpy:
- case Intrinsic::memcpy_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This class represents any memmove intrinsic
- /// i.e. llvm.element.unordered.atomic.memmove
- /// and llvm.memmove
- class AnyMemMoveInst : public AnyMemTransferInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- switch (I->getIntrinsicID()) {
- case Intrinsic::memmove:
- case Intrinsic::memmove_element_unordered_atomic:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
- };
-
- /// This represents the llvm.va_start intrinsic.
- class VAStartInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vastart;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
- };
-
- /// This represents the llvm.va_end intrinsic.
- class VAEndInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vaend;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); }
- };
-
- /// This represents the llvm.va_copy intrinsic.
- class VACopyInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::vacopy;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); }
- Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); }
- };
-
- /// This represents the llvm.instrprof_increment intrinsic.
- class InstrProfIncrementInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_increment;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
- }
-
- GlobalVariable *getName() const {
- return cast<GlobalVariable>(
- const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
- }
-
- ConstantInt *getHash() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
- }
-
- ConstantInt *getNumCounters() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
- }
-
- ConstantInt *getIndex() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
- }
-
- Value *getStep() const;
- };
-
- class InstrProfIncrementInstStep : public InstrProfIncrementInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
- }
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents atomic memset intrinsic
+// i.e. llvm.element.unordered.atomic.memset
+class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+// This class wraps the atomic memcpy/memmove intrinsics
+// i.e. llvm.element.unordered.atomic.memcpy/memmove
+class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
- };
-
- /// This represents the llvm.instrprof_value_profile intrinsic.
- class InstrProfValueProfileInst : public IntrinsicInst {
- public:
- static bool classof(const IntrinsicInst *I) {
- return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents the atomic memcpy intrinsic
+/// i.e. llvm.element.unordered.atomic.memcpy
+class AtomicMemCpyInst : public AtomicMemTransferInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents the atomic memmove intrinsic
+/// i.e. llvm.element.unordered.atomic.memmove
+class AtomicMemMoveInst : public AtomicMemTransferInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This is the common base class for memset/memcpy/memmove.
+class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> {
+private:
+ enum { ARG_VOLATILE = 3 };
+
+public:
+ ConstantInt *getVolatileCst() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE)));
+ }
+
+ bool isVolatile() const { return !getVolatileCst()->isZero(); }
+
+ void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memset:
+ case Intrinsic::memcpy_inline:
+ return true;
+ default:
+ return false;
}
- static bool classof(const Value *V) {
- return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class wraps the llvm.memset intrinsic.
+class MemSetInst : public MemSetBase<MemIntrinsic> {
+public:
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memset;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class wraps the llvm.memcpy/memmove intrinsics.
+class MemTransferInst : public MemTransferBase<MemIntrinsic> {
+public:
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memmove:
+ case Intrinsic::memcpy_inline:
+ return true;
+ default:
+ return false;
}
-
- GlobalVariable *getName() const {
- return cast<GlobalVariable>(
- const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class wraps the llvm.memcpy intrinsic.
+class MemCpyInst : public MemTransferInst {
+public:
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memcpy;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class wraps the llvm.memmove intrinsic.
+class MemMoveInst : public MemTransferInst {
+public:
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memmove;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class wraps the llvm.memcpy.inline intrinsic.
+class MemCpyInlineInst : public MemTransferInst {
+public:
+ ConstantInt *getLength() const {
+ return cast<ConstantInt>(MemTransferInst::getLength());
+ }
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memcpy_inline;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+// The common base class for any memset/memmove/memcpy intrinsics;
+// whether they be atomic or non-atomic.
+// i.e. llvm.element.unordered.atomic.memset/memcpy/memmove
+// and llvm.memset/memcpy/memmove
+class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> {
+public:
+ bool isVolatile() const {
+ // Only the non-atomic intrinsics can be volatile
+ if (auto *MI = dyn_cast<MemIntrinsic>(this))
+ return MI->isVolatile();
+ return false;
+ }
+
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memcpy_inline:
+ case Intrinsic::memmove:
+ case Intrinsic::memset:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
-
- ConstantInt *getHash() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents any memset intrinsic
+// i.e. llvm.element.unordered.atomic.memset
+// and llvm.memset
+class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memset:
+ case Intrinsic::memset_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
-
- Value *getTargetValue() const {
- return cast<Value>(const_cast<Value *>(getArgOperand(2)));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+// This class wraps any memcpy/memmove intrinsics
+// i.e. llvm.element.unordered.atomic.memcpy/memmove
+// and llvm.memcpy/memmove
+class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memcpy_inline:
+ case Intrinsic::memmove:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
-
- ConstantInt *getValueKind() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents any memcpy intrinsic
+/// i.e. llvm.element.unordered.atomic.memcpy
+/// and llvm.memcpy
+class AnyMemCpyInst : public AnyMemTransferInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy:
+ case Intrinsic::memcpy_inline:
+ case Intrinsic::memcpy_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
-
- // Returns the value site index.
- ConstantInt *getIndex() const {
- return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This class represents any memmove intrinsic
+/// i.e. llvm.element.unordered.atomic.memmove
+/// and llvm.memmove
+class AnyMemMoveInst : public AnyMemTransferInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memmove:
+ case Intrinsic::memmove_element_unordered_atomic:
+ return true;
+ default:
+ return false;
}
- };
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This represents the llvm.va_start intrinsic.
+class VAStartInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vastart;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
+};
+
+/// This represents the llvm.va_end intrinsic.
+class VAEndInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vaend;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); }
+};
+
+/// This represents the llvm.va_copy intrinsic.
+class VACopyInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::vacopy;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); }
+ Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); }
+};
+
+/// This represents the llvm.instrprof_increment intrinsic.
+class InstrProfIncrementInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::instrprof_increment;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ GlobalVariable *getName() const {
+ return cast<GlobalVariable>(
+ const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
+ }
+
+ ConstantInt *getHash() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
+ }
+
+ ConstantInt *getNumCounters() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2)));
+ }
+
+ ConstantInt *getIndex() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
+ }
+
+ Value *getStep() const;
+};
+
+class InstrProfIncrementInstStep : public InstrProfIncrementInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::instrprof_increment_step;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+};
+
+/// This represents the llvm.instrprof_value_profile intrinsic.
+class InstrProfValueProfileInst : public IntrinsicInst {
+public:
+ static bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::instrprof_value_profile;
+ }
+ static bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ GlobalVariable *getName() const {
+ return cast<GlobalVariable>(
+ const_cast<Value *>(getArgOperand(0))->stripPointerCasts());
+ }
+
+ ConstantInt *getHash() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1)));
+ }
+
+ Value *getTargetValue() const {
+ return cast<Value>(const_cast<Value *>(getArgOperand(2)));
+ }
+
+ ConstantInt *getValueKind() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3)));
+ }
+
+ // Returns the value site index.
+ ConstantInt *getIndex() const {
+ return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4)));
+ }
+};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.h b/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.h
index 58e7725fc0df..a9e6525e2f3d 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/TypeSize.h"
#include <string>
namespace llvm {
@@ -99,21 +100,41 @@ namespace Intrinsic {
/// intrinsic. This is returned by getIntrinsicInfoTableEntries.
struct IITDescriptor {
enum IITDescriptorKind {
- Void, VarArg, MMX, Token, Metadata, Half, Float, Double, Quad,
- Integer, Vector, Pointer, Struct,
- Argument, ExtendArgument, TruncArgument, HalfVecArgument,
- SameVecWidthArgument, PtrToArgument, PtrToElt, VecOfAnyPtrsToElt,
- VecElementArgument, ScalableVecArgument, Subdivide2Argument,
- Subdivide4Argument, VecOfBitcastsToInt
+ Void,
+ VarArg,
+ MMX,
+ Token,
+ Metadata,
+ Half,
+ BFloat,
+ Float,
+ Double,
+ Quad,
+ Integer,
+ Vector,
+ Pointer,
+ Struct,
+ Argument,
+ ExtendArgument,
+ TruncArgument,
+ HalfVecArgument,
+ SameVecWidthArgument,
+ PtrToArgument,
+ PtrToElt,
+ VecOfAnyPtrsToElt,
+ VecElementArgument,
+ Subdivide2Argument,
+ Subdivide4Argument,
+ VecOfBitcastsToInt
} Kind;
union {
unsigned Integer_Width;
unsigned Float_Width;
- unsigned Vector_Width;
unsigned Pointer_AddressSpace;
unsigned Struct_NumElements;
unsigned Argument_Info;
+ ElementCount Vector_Width;
};
enum ArgKind {
@@ -165,6 +186,14 @@ namespace Intrinsic {
IITDescriptor Result = {K, {Field}};
return Result;
}
+
+ static IITDescriptor getVector(unsigned Width, bool IsScalable) {
+ IITDescriptor Result;
+ Result.Kind = Vector;
+ Result.Vector_Width.Min = Width;
+ Result.Vector_Width.Scalable = IsScalable;
+ return Result;
+ }
};
/// Return the IIT table descriptor for the specified intrinsic into an array
@@ -193,6 +222,13 @@ namespace Intrinsic {
/// This method returns true on error.
bool matchIntrinsicVarArg(bool isVarArg, ArrayRef<IITDescriptor> &Infos);
+ /// Gets the type arguments of an intrinsic call by matching type contraints
+ /// specified by the .td file. The overloaded types are pushed into the
+ /// AgTys vector.
+ ///
+ /// Returns false if the given function is not a valid intrinsic call.
+ bool getIntrinsicSignature(Function *F, SmallVectorImpl<Type *> &ArgTys);
+
// Checks if the intrinsic name matches with its signature and if not
// returns the declaration with the same signature and remangled name.
llvm::Optional<Function*> remangleIntrinsicFunction(Function *F);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.td b/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.td
index 865e4ccc9bc4..4918ea876df6 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Intrinsics.td
@@ -27,6 +27,10 @@ class IntrinsicProperty;
// effects. It may be CSE'd deleted if dead, etc.
def IntrNoMem : IntrinsicProperty;
+// IntrNoSync - Threads executing the intrinsic will not synchronize using
+// memory or other means.
+def IntrNoSync : IntrinsicProperty;
+
// IntrReadMem - This intrinsic only reads from memory. It does not write to
// memory and has no other side effects. Therefore, it cannot be moved across
// potentially aliasing stores. However, it can be reordered otherwise and can
@@ -58,48 +62,63 @@ def Commutative : IntrinsicProperty;
// Throws - This intrinsic can throw.
def Throws : IntrinsicProperty;
+// Attribute index needs to match `AttrIndex` defined `Attributes.h`.
+class AttrIndex<int idx> {
+ int Value = idx;
+}
+def FuncIndex : AttrIndex<-1>;
+def RetIndex : AttrIndex<0>;
+class ArgIndex<int argNo> : AttrIndex<!add(argNo, 1)>;
+
// NoCapture - The specified argument pointer is not captured by the intrinsic.
-class NoCapture<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class NoCapture<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
// NoAlias - The specified argument pointer is not aliasing other "noalias" pointer
// arguments of the intrinsic wrt. the intrinsic scope.
-class NoAlias<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class NoAlias<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
+}
+
+class Align<AttrIndex idx, int align> : IntrinsicProperty {
+ int ArgNo = idx.Value;
+ int Align = align;
}
// Returned - The specified argument is always the return value of the
// intrinsic.
-class Returned<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class Returned<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
// ImmArg - The specified argument must be an immediate.
-class ImmArg<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class ImmArg<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
// ReadOnly - The specified argument pointer is not written to through the
// pointer by the intrinsic.
-class ReadOnly<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class ReadOnly<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
// WriteOnly - The intrinsic does not read memory through the specified
// argument pointer.
-class WriteOnly<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class WriteOnly<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
// ReadNone - The specified argument pointer is not dereferenced by the
// intrinsic.
-class ReadNone<int argNo> : IntrinsicProperty {
- int ArgNo = argNo;
+class ReadNone<AttrIndex idx> : IntrinsicProperty {
+ int ArgNo = idx.Value;
}
def IntrNoReturn : IntrinsicProperty;
+def IntrNoFree : IntrinsicProperty;
+
def IntrWillReturn : IntrinsicProperty;
// IntrCold - Calls to this intrinsic are cold.
@@ -210,6 +229,7 @@ def llvm_i16_ty : LLVMType<i16>;
def llvm_i32_ty : LLVMType<i32>;
def llvm_i64_ty : LLVMType<i64>;
def llvm_half_ty : LLVMType<f16>;
+def llvm_bfloat_ty : LLVMType<bf16>;
def llvm_float_ty : LLVMType<f32>;
def llvm_double_ty : LLVMType<f64>;
def llvm_f80_ty : LLVMType<f80>;
@@ -232,6 +252,7 @@ def llvm_v8i1_ty : LLVMType<v8i1>; // 8 x i1
def llvm_v16i1_ty : LLVMType<v16i1>; // 16 x i1
def llvm_v32i1_ty : LLVMType<v32i1>; // 32 x i1
def llvm_v64i1_ty : LLVMType<v64i1>; // 64 x i1
+def llvm_v128i1_ty : LLVMType<v128i1>; // 128 x i1
def llvm_v512i1_ty : LLVMType<v512i1>; // 512 x i1
def llvm_v1024i1_ty : LLVMType<v1024i1>; //1024 x i1
@@ -274,6 +295,9 @@ def llvm_v1i128_ty : LLVMType<v1i128>; // 1 x i128
def llvm_v2f16_ty : LLVMType<v2f16>; // 2 x half (__fp16)
def llvm_v4f16_ty : LLVMType<v4f16>; // 4 x half (__fp16)
def llvm_v8f16_ty : LLVMType<v8f16>; // 8 x half (__fp16)
+def llvm_v2bf16_ty : LLVMType<v2bf16>; // 2 x bfloat (__bf16)
+def llvm_v4bf16_ty : LLVMType<v4bf16>; // 4 x bfloat (__bf16)
+def llvm_v8bf16_ty : LLVMType<v8bf16>; // 8 x bfloat (__bf16)
def llvm_v1f32_ty : LLVMType<v1f32>; // 1 x float
def llvm_v2f32_ty : LLVMType<v2f32>; // 2 x float
def llvm_v4f32_ty : LLVMType<v4f32>; // 4 x float
@@ -284,6 +308,7 @@ def llvm_v1f64_ty : LLVMType<v1f64>; // 1 x double
def llvm_v2f64_ty : LLVMType<v2f64>; // 2 x double
def llvm_v4f64_ty : LLVMType<v4f64>; // 4 x double
def llvm_v8f64_ty : LLVMType<v8f64>; // 8 x double
+def llvm_v16f64_ty : LLVMType<v16f64>; // 16 x double
def llvm_vararg_ty : LLVMType<isVoid>; // this means vararg here
@@ -346,7 +371,8 @@ def int_gcread : Intrinsic<[llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_gcwrite : Intrinsic<[],
[llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
- [IntrArgMemOnly, NoCapture<1>, NoCapture<2>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<1>>,
+ NoCapture<ArgIndex<2>>]>;
//===------------------- ObjC ARC runtime Intrinsics --------------------===//
//
@@ -422,14 +448,19 @@ def int_objc_arc_annotation_bottomup_bbend : Intrinsic<[],
//===--------------------- Code Generator Intrinsics ----------------------===//
//
-def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_addressofreturnaddress : Intrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
-def int_frameaddress : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+def int_frameaddress : Intrinsic<[llvm_anyptr_ty], [llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_sponentry : Intrinsic<[llvm_anyptr_ty], [], [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrReadMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
[], "llvm.write_register">;
+def int_read_volatile_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
+ [IntrHasSideEffects],
+ "llvm.read_volatile_register">;
// Gets the address of the local variable area. This is typically a copy of the
// stack, frame, or base pointer depending on the type of prologue.
@@ -442,7 +473,7 @@ def int_localescape : Intrinsic<[], [llvm_vararg_ty]>;
// to an escaped allocation indicated by the index.
def int_localrecover : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
// Given the frame pointer passed into an SEH filter function, returns a
// pointer to the local variable area suitable for use with llvm.localrecover.
@@ -468,8 +499,9 @@ def int_thread_pointer : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>,
// memory while not impeding optimization.
def int_prefetch
: Intrinsic<[], [ llvm_anyptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty ],
- [ IntrInaccessibleMemOrArgMemOnly, IntrWillReturn, ReadOnly<0>, NoCapture<0>,
- ImmArg<1>, ImmArg<2>]>;
+ [IntrInaccessibleMemOrArgMemOnly, IntrWillReturn,
+ ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
def int_pcmarker : Intrinsic<[], [llvm_i32_ty]>;
def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
@@ -503,24 +535,47 @@ def int_instrprof_value_profile : Intrinsic<[],
llvm_i32_ty],
[]>;
+def int_call_preallocated_setup : Intrinsic<[llvm_token_ty], [llvm_i32_ty]>;
+def int_call_preallocated_arg : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_i32_ty]>;
+def int_call_preallocated_teardown : Intrinsic<[], [llvm_token_ty]>;
+
//===------------------- Standard C Library Intrinsics --------------------===//
//
def int_memcpy : Intrinsic<[],
- [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
- llvm_i1_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<0>, NoCapture<1>,
- NoAlias<0>, NoAlias<1>, WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>;
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
+ llvm_i1_ty],
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
+ NoAlias<ArgIndex<0>>, NoAlias<ArgIndex<1>>,
+ WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
+ ImmArg<ArgIndex<3>>]>;
+
+// Memcpy semantic that is guaranteed to be inlined.
+// In particular this means that the generated code is not allowed to call any
+// external function.
+// The third argument (specifying the size) must be a constant.
+def int_memcpy_inline
+ : Intrinsic<[],
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i1_ty],
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
+ NoAlias<ArgIndex<0>>, NoAlias<ArgIndex<1>>,
+ WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
def int_memmove : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
llvm_i1_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<0>, NoCapture<1>,
- ReadOnly<1>, ImmArg<3>]>;
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>,
+ ReadOnly<ArgIndex<1>>, ImmArg<ArgIndex<3>>]>;
def int_memset : Intrinsic<[],
[llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty,
llvm_i1_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<0>, WriteOnly<0>,
- ImmArg<3>]>;
+ [IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>,
+ ImmArg<ArgIndex<3>>]>;
// FIXME: Add version of these floating point intrinsics which allow non-default
// rounding modes and FP exception handling.
@@ -556,6 +611,7 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
def int_rint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_nearbyint : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_round : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
+ def int_roundeven : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>]>;
def int_canonicalize : Intrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>],
[IntrNoMem]>;
@@ -586,9 +642,18 @@ def int_maximum : Intrinsic<[llvm_anyfloat_ty],
def int_objectsize : Intrinsic<[llvm_anyint_ty],
[llvm_anyptr_ty, llvm_i1_ty,
llvm_i1_ty, llvm_i1_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<1>, ImmArg<2>, ImmArg<3>]>,
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>,
+ ImmArg<ArgIndex<3>>]>,
GCCBuiltin<"__builtin_object_size">;
+//===--------------- Access to Floating Point Environment -----------------===//
+//
+
+let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
+ def int_flt_rounds : Intrinsic<[llvm_i32_ty], []>;
+}
+
//===--------------- Constrained Floating Point Intrinsics ----------------===//
//
@@ -626,6 +691,13 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
llvm_metadata_ty,
llvm_metadata_ty ]>;
+ def int_experimental_constrained_fmuladd : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ llvm_metadata_ty,
+ llvm_metadata_ty ]>;
+
def int_experimental_constrained_fptosi : Intrinsic<[ llvm_anyint_ty ],
[ llvm_anyfloat_ty,
llvm_metadata_ty ]>;
@@ -746,6 +818,9 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
def int_experimental_constrained_round : Intrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
+ def int_experimental_constrained_roundeven : Intrinsic<[ llvm_anyfloat_ty ],
+ [ LLVMMatchType<0>,
+ llvm_metadata_ty ]>;
def int_experimental_constrained_trunc : Intrinsic<[ llvm_anyfloat_ty ],
[ LLVMMatchType<0>,
llvm_metadata_ty ]>;
@@ -768,6 +843,10 @@ let IntrProperties = [IntrInaccessibleMemOnly, IntrWillReturn] in {
def int_expect : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrWillReturn]>;
+def int_expect_with_probability : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_double_ty],
+ [IntrNoMem, IntrWillReturn]>;
+
//===-------------------- Bit Manipulation Intrinsics ---------------------===//
//
@@ -782,7 +861,8 @@ let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn] in {
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>]>;
}
-let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<1>] in {
+let IntrProperties = [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<1>>] in {
def int_ctlz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
def int_cttz : Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, llvm_i1_ty]>;
}
@@ -872,12 +952,12 @@ def int_codeview_annotation : Intrinsic<[], [llvm_metadata_ty],
//
def int_init_trampoline : Intrinsic<[],
[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<0>]>,
- GCCBuiltin<"__builtin_init_trampoline">;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>,
+ GCCBuiltin<"__builtin_init_trampoline">;
def int_adjust_trampoline : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly]>,
- GCCBuiltin<"__builtin_adjust_trampoline">;
+ GCCBuiltin<"__builtin_adjust_trampoline">;
//===------------------------ Overflow Intrinsics -------------------------===//
//
@@ -924,44 +1004,64 @@ def int_usub_sat : Intrinsic<[llvm_anyint_ty],
//
def int_smul_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ Commutative, ImmArg<ArgIndex<2>>]>;
def int_umul_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ Commutative, ImmArg<ArgIndex<2>>]>;
def int_sdiv_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_udiv_fix : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
//===------------------- Fixed Point Saturation Arithmetic Intrinsics ----------------===//
//
def int_smul_fix_sat : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ Commutative, ImmArg<ArgIndex<2>>]>;
def int_umul_fix_sat : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, IntrWillReturn, Commutative, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ Commutative, ImmArg<ArgIndex<2>>]>;
+
+def int_sdiv_fix_sat : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_udiv_fix_sat : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
//===------------------------- Memory Use Markers -------------------------===//
//
def int_lifetime_start : Intrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<1>, ImmArg<0>]>;
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<1>>,
+ ImmArg<ArgIndex<0>>]>;
def int_lifetime_end : Intrinsic<[],
[llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<1>, ImmArg<0>]>;
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<1>>,
+ ImmArg<ArgIndex<0>>]>;
def int_invariant_start : Intrinsic<[llvm_descriptor_ty],
[llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<1>, ImmArg<0>]>;
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<1>>,
+ ImmArg<ArgIndex<0>>]>;
def int_invariant_end : Intrinsic<[],
[llvm_descriptor_ty, llvm_i64_ty,
llvm_anyptr_ty],
- [IntrArgMemOnly, IntrWillReturn, NoCapture<2>, ImmArg<1>]>;
+ [IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<2>>,
+ ImmArg<ArgIndex<1>>]>;
// launder.invariant.group can't be marked with 'readnone' (IntrNoMem),
// because it would cause CSE of two barriers with the same argument.
@@ -1008,13 +1108,17 @@ def int_experimental_gc_statepoint : Intrinsic<[llvm_token_ty],
[llvm_i64_ty, llvm_i32_ty,
llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty, llvm_vararg_ty],
- [Throws, ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>]>;
+ [Throws, ImmArg<ArgIndex<0>>,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<3>>,
+ ImmArg<ArgIndex<4>>]>;
def int_experimental_gc_result : Intrinsic<[llvm_any_ty], [llvm_token_ty],
[IntrReadMem]>;
def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty],
- [llvm_token_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<1>, ImmArg<2>]>;
+ [llvm_token_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrReadMem, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
//===------------------------ Coroutine Intrinsics ---------------===//
// These are documented in docs/Coroutines.rst
@@ -1024,7 +1128,8 @@ def int_experimental_gc_relocate : Intrinsic<[llvm_any_ty],
def int_coro_id : Intrinsic<[llvm_token_ty], [llvm_i32_ty, llvm_ptr_ty,
llvm_ptr_ty, llvm_ptr_ty],
[IntrArgMemOnly, IntrReadMem,
- ReadNone<1>, ReadOnly<2>, NoCapture<2>]>;
+ ReadNone<ArgIndex<1>>, ReadOnly<ArgIndex<2>>,
+ NoCapture<ArgIndex<2>>]>;
def int_coro_id_retcon : Intrinsic<[llvm_token_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty,
llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
@@ -1035,11 +1140,12 @@ def int_coro_id_retcon_once : Intrinsic<[llvm_token_ty],
[]>;
def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>;
def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
- [WriteOnly<1>]>;
+ [WriteOnly<ArgIndex<1>>]>;
def int_coro_free : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
- [IntrReadMem, IntrArgMemOnly, ReadOnly<1>,
- NoCapture<1>]>;
+ [IntrReadMem, IntrArgMemOnly,
+ ReadOnly<ArgIndex<1>>,
+ NoCapture<ArgIndex<1>>]>;
def int_coro_end : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_i1_ty], []>;
def int_coro_frame : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
@@ -1057,28 +1163,29 @@ def int_coro_alloca_get : Intrinsic<[llvm_ptr_ty], [llvm_token_ty], []>;
def int_coro_alloca_free : Intrinsic<[], [llvm_token_ty], []>;
def int_coro_param : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty, llvm_ptr_ty],
- [IntrNoMem, ReadNone<0>, ReadNone<1>]>;
+ [IntrNoMem, ReadNone<ArgIndex<0>>,
+ ReadNone<ArgIndex<1>>]>;
// Coroutine Manipulation Intrinsics.
def int_coro_resume : Intrinsic<[], [llvm_ptr_ty], [Throws]>;
def int_coro_destroy : Intrinsic<[], [llvm_ptr_ty], [Throws]>;
def int_coro_done : Intrinsic<[llvm_i1_ty], [llvm_ptr_ty],
- [IntrArgMemOnly, ReadOnly<0>, NoCapture<0>]>;
+ [IntrArgMemOnly, ReadOnly<ArgIndex<0>>,
+ NoCapture<ArgIndex<0>>]>;
def int_coro_promise : Intrinsic<[llvm_ptr_ty],
[llvm_ptr_ty, llvm_i32_ty, llvm_i1_ty],
- [IntrNoMem, NoCapture<0>]>;
+ [IntrNoMem, NoCapture<ArgIndex<0>>]>;
// Coroutine Lowering Intrinsics. Used internally by coroutine passes.
def int_coro_subfn_addr : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_i8_ty],
- [IntrReadMem, IntrArgMemOnly, ReadOnly<0>,
- NoCapture<0>]>;
+ [IntrReadMem, IntrArgMemOnly,
+ ReadOnly<ArgIndex<0>>,
+ NoCapture<ArgIndex<0>>]>;
///===-------------------------- Other Intrinsics --------------------------===//
//
-def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
- GCCBuiltin<"__builtin_flt_rounds">;
def int_trap : Intrinsic<[], [], [IntrNoReturn, IntrCold]>,
GCCBuiltin<"__builtin_trap">;
def int_debugtrap : Intrinsic<[]>,
@@ -1117,36 +1224,117 @@ def int_clear_cache : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
[], "llvm.clear_cache">;
// Intrinsic to detect whether its argument is a constant.
-def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem, IntrWillReturn], "llvm.is.constant">;
+def int_is_constant : Intrinsic<[llvm_i1_ty], [llvm_any_ty],
+ [IntrNoMem, IntrWillReturn, IntrConvergent],
+ "llvm.is.constant">;
// Intrinsic to mask out bits of a pointer.
-def int_ptrmask: Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty, llvm_anyint_ty],
+def int_ptrmask: Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_anyint_ty],
[IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
+//===---------------- Vector Predication Intrinsics --------------===//
+
+// Binary operators
+let IntrProperties = [IntrNoMem, IntrNoSync, IntrWillReturn] in {
+ def int_vp_add : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_sub : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_mul : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_sdiv : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_udiv : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_srem : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_urem : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_ashr : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_lshr : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_shl : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_or : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_and : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+ def int_vp_xor : Intrinsic<[ llvm_anyvector_ty ],
+ [ LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ llvm_i32_ty]>;
+
+}
+
+def int_get_active_lane_mask:
+ Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyint_ty, LLVMMatchType<1>],
+ [IntrNoMem, IntrNoSync, IntrWillReturn]>;
+
//===-------------------------- Masked Intrinsics -------------------------===//
//
def int_masked_store : Intrinsic<[], [llvm_anyvector_ty,
LLVMAnyPointerType<LLVMMatchType<0>>,
llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [IntrArgMemOnly, IntrWillReturn, ImmArg<2>]>;
+ [IntrArgMemOnly, IntrWillReturn, ImmArg<ArgIndex<2>>]>;
def int_masked_load : Intrinsic<[llvm_anyvector_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMMatchType<0>],
- [IntrReadMem, IntrArgMemOnly, IntrWillReturn, ImmArg<1>]>;
+ [IntrReadMem, IntrArgMemOnly, IntrWillReturn,
+ ImmArg<ArgIndex<1>>]>;
def int_masked_gather: Intrinsic<[llvm_anyvector_ty],
[LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>],
- [IntrReadMem, IntrWillReturn, ImmArg<1>]>;
+ [IntrReadMem, IntrWillReturn,
+ ImmArg<ArgIndex<1>>]>;
def int_masked_scatter: Intrinsic<[],
[llvm_anyvector_ty,
LLVMVectorOfAnyPointersToElt<0>, llvm_i32_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [IntrWillReturn, ImmArg<2>]>;
+ [IntrWillReturn, ImmArg<ArgIndex<2>>]>;
def int_masked_expandload: Intrinsic<[llvm_anyvector_ty],
[LLVMPointerToElt<0>,
@@ -1177,20 +1365,24 @@ def int_load_relative: Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty, llvm_anyint_ty],
[IntrReadMem, IntrArgMemOnly]>;
def int_hwasan_check_memaccess :
- Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly, ImmArg<2>]>;
+ Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrInaccessibleMemOnly, ImmArg<ArgIndex<2>>]>;
def int_hwasan_check_memaccess_shortgranules :
- Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty], [IntrInaccessibleMemOnly, ImmArg<2>]>;
+ Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrInaccessibleMemOnly, ImmArg<ArgIndex<2>>]>;
// Xray intrinsics
//===----------------------------------------------------------------------===//
// Custom event logging for x-ray.
// Takes a pointer to a string and the length of the string.
def int_xray_customevent : Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
- [NoCapture<0>, ReadOnly<0>, IntrWriteMem]>;
+ [IntrWriteMem, NoCapture<ArgIndex<0>>,
+ ReadOnly<ArgIndex<0>>]>;
// Typed event logging for x-ray.
// Takes a numeric type tag, a pointer to a string and the length of the string.
def int_xray_typedevent : Intrinsic<[], [llvm_i16_ty, llvm_ptr_ty, llvm_i32_ty],
- [NoCapture<1>, ReadOnly<1>, IntrWriteMem]>;
+ [IntrWriteMem, NoCapture<ArgIndex<1>>,
+ ReadOnly<ArgIndex<1>>]>;
//===----------------------------------------------------------------------===//
//===------ Memory intrinsics with element-wise atomicity guarantees ------===//
@@ -1199,29 +1391,25 @@ def int_xray_typedevent : Intrinsic<[], [llvm_i16_ty, llvm_ptr_ty, llvm_i32_ty],
// @llvm.memcpy.element.unordered.atomic.*(dest, src, length, elementsize)
def int_memcpy_element_unordered_atomic
: Intrinsic<[],
- [
- llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty
- ],
- [
- IntrArgMemOnly, IntrWillReturn, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
- ReadOnly<1>, ImmArg<3>
- ]>;
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty],
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>,
+ NoCapture<ArgIndex<1>>, WriteOnly<ArgIndex<0>>,
+ ReadOnly<ArgIndex<1>>, ImmArg<ArgIndex<3>>]>;
// @llvm.memmove.element.unordered.atomic.*(dest, src, length, elementsize)
def int_memmove_element_unordered_atomic
: Intrinsic<[],
- [
- llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty
- ],
- [
- IntrArgMemOnly, IntrWillReturn, NoCapture<0>, NoCapture<1>, WriteOnly<0>,
- ReadOnly<1>, ImmArg<3>
- ]>;
+ [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty, llvm_i32_ty],
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>,
+ NoCapture<ArgIndex<1>>, WriteOnly<ArgIndex<0>>,
+ ReadOnly<ArgIndex<1>>, ImmArg<ArgIndex<3>>]>;
// @llvm.memset.element.unordered.atomic.*(dest, value, length, elementsize)
def int_memset_element_unordered_atomic
- : Intrinsic<[], [ llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty ],
- [ IntrArgMemOnly, IntrWillReturn, NoCapture<0>, WriteOnly<0>, ImmArg<3> ]>;
+ : Intrinsic<[], [llvm_anyptr_ty, llvm_i8_ty, llvm_anyint_ty, llvm_i32_ty],
+ [IntrWriteMem, IntrArgMemOnly, IntrWillReturn,
+ NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>,
+ ImmArg<ArgIndex<3>>]>;
//===------------------------ Reduction Intrinsics ------------------------===//
//
@@ -1258,39 +1446,34 @@ let IntrProperties = [IntrNoMem, IntrWillReturn] in {
//===----- Matrix intrinsics ---------------------------------------------===//
-def int_matrix_transpose : Intrinsic<[llvm_anyvector_ty],
- [LLVMMatchType<0>,
- llvm_i32_ty,
- llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable,
- IntrWillReturn, ImmArg<1>, ImmArg<2>]>;
-
-def int_matrix_multiply : Intrinsic<[llvm_anyvector_ty],
- [llvm_anyvector_ty,
- llvm_anyvector_ty,
- llvm_i32_ty,
- llvm_i32_ty,
- llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable,
- IntrWillReturn, ImmArg<2>, ImmArg<3>,
- ImmArg<4>]>;
-
-def int_matrix_columnwise_load : Intrinsic<[llvm_anyvector_ty],
- [LLVMAnyPointerType<LLVMMatchType<0>>,
- llvm_i32_ty,
- llvm_i32_ty,
- llvm_i32_ty],
- [IntrReadMem, IntrWillReturn,
- ImmArg<2>, ImmArg<3>]>;
-
-def int_matrix_columnwise_store : Intrinsic<[],
- [llvm_anyvector_ty,
- LLVMAnyPointerType<LLVMMatchType<0>>,
- llvm_i32_ty,
- llvm_i32_ty,
- llvm_i32_ty],
- [WriteOnly<1>, IntrWillReturn,
- ImmArg<3>, ImmArg<4>]>;
+def int_matrix_transpose
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
+ [ IntrNoSync, IntrWillReturn, IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
+
+def int_matrix_multiply
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_anyvector_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoSync, IntrWillReturn, IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
+
+def int_matrix_column_major_load
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMPointerToElt<0>, llvm_i64_ty, llvm_i1_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrReadMem,
+ NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>,
+ ImmArg<ArgIndex<4>>]>;
+
+def int_matrix_column_major_store
+ : Intrinsic<[],
+ [llvm_anyvector_ty, LLVMPointerToElt<0>,
+ llvm_i64_ty, llvm_i1_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoSync, IntrWillReturn, IntrArgMemOnly, IntrWriteMem,
+ WriteOnly<ArgIndex<1>>, NoCapture<ArgIndex<1>>,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
//===---------- Intrinsics to control hardware supported loops ----------===//
@@ -1319,27 +1502,36 @@ def int_loop_decrement :
// may be optimised.
def int_loop_decrement_reg :
Intrinsic<[llvm_anyint_ty],
- [llvm_anyint_ty, llvm_anyint_ty], [IntrNoDuplicate]>;
+ [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoDuplicate]>;
//===----- Intrinsics that are used to provide predicate information -----===//
def int_ssa_copy : Intrinsic<[llvm_any_ty], [LLVMMatchType<0>],
- [IntrNoMem, Returned<0>]>;
+ [IntrNoMem, Returned<ArgIndex<0>>]>;
//===------- Intrinsics that are used to preserve debug information -------===//
def int_preserve_array_access_index : Intrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem,
+ ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
def int_preserve_union_access_index : Intrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem,
+ ImmArg<ArgIndex<1>>]>;
def int_preserve_struct_access_index : Intrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty, llvm_i32_ty,
llvm_i32_ty],
- [IntrNoMem, ImmArg<1>,
- ImmArg<2>]>;
+ [IntrNoMem,
+ ImmArg<ArgIndex<1>>,
+ ImmArg<ArgIndex<2>>]>;
+
+//===---------- Intrinsics to query properties of scalable vectors --------===//
+def int_vscale : Intrinsic<[llvm_anyint_ty], [], [IntrNoMem]>;
+
+//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Target-specific intrinsics
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAArch64.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAArch64.td
index 27a2550d1857..3f71f644f9a1 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -133,6 +133,10 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
: Intrinsic<[llvm_anyvector_ty],
[LLVMHalfElementsVectorType<0>, llvm_anyvector_ty],
[IntrNoMem]>;
+ class AdvSIMD_2VectorArg_Lane_Intrinsic
+ : Intrinsic<[llvm_anyint_ty],
+ [LLVMMatchType<0>, llvm_anyint_ty, llvm_i32_ty],
+ [IntrNoMem]>;
class AdvSIMD_3VectorArg_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -169,6 +173,17 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
[IntrNoMem]>;
+
+ class AdvSIMD_MatMul_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
+ [IntrNoMem]>;
+
+ class AdvSIMD_FML_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
+ [IntrNoMem]>;
+
}
// Arithmetic ops
@@ -207,9 +222,13 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
// Vector Saturating Doubling Multiply High
def int_aarch64_neon_sqdmulh : AdvSIMD_2IntArg_Intrinsic;
+ def int_aarch64_neon_sqdmulh_lane : AdvSIMD_2VectorArg_Lane_Intrinsic;
+ def int_aarch64_neon_sqdmulh_laneq : AdvSIMD_2VectorArg_Lane_Intrinsic;
// Vector Saturating Rounding Doubling Multiply High
def int_aarch64_neon_sqrdmulh : AdvSIMD_2IntArg_Intrinsic;
+ def int_aarch64_neon_sqrdmulh_lane : AdvSIMD_2VectorArg_Lane_Intrinsic;
+ def int_aarch64_neon_sqrdmulh_laneq : AdvSIMD_2VectorArg_Lane_Intrinsic;
// Vector Polynominal Multiply
def int_aarch64_neon_pmul : AdvSIMD_2VectorArg_Intrinsic;
@@ -441,6 +460,27 @@ let TargetPrefix = "aarch64", IntrProperties = [IntrNoMem] in {
def int_aarch64_neon_udot : AdvSIMD_Dot_Intrinsic;
def int_aarch64_neon_sdot : AdvSIMD_Dot_Intrinsic;
+// v8.6-A Matrix Multiply Intrinsics
+ def int_aarch64_neon_ummla : AdvSIMD_MatMul_Intrinsic;
+ def int_aarch64_neon_smmla : AdvSIMD_MatMul_Intrinsic;
+ def int_aarch64_neon_usmmla : AdvSIMD_MatMul_Intrinsic;
+ def int_aarch64_neon_usdot : AdvSIMD_Dot_Intrinsic;
+ def int_aarch64_neon_bfdot : AdvSIMD_Dot_Intrinsic;
+ def int_aarch64_neon_bfmmla : AdvSIMD_MatMul_Intrinsic;
+ def int_aarch64_neon_bfmlalb : AdvSIMD_FML_Intrinsic;
+ def int_aarch64_neon_bfmlalt : AdvSIMD_FML_Intrinsic;
+
+
+ // v8.6-A Bfloat Intrinsics
+ def int_aarch64_neon_bfcvt
+ : Intrinsic<[llvm_bfloat_ty], [llvm_float_ty], [IntrNoMem]>;
+ def int_aarch64_neon_bfcvtn
+ : Intrinsic<[llvm_v8bf16_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+ def int_aarch64_neon_bfcvtn2
+ : Intrinsic<[llvm_v8bf16_ty],
+ [llvm_v8bf16_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
// v8.2-A FP16 Fused Multiply-Add Long
def int_aarch64_neon_fmlal : AdvSIMD_FP16FML_Intrinsic;
def int_aarch64_neon_fmlsl : AdvSIMD_FP16FML_Intrinsic;
@@ -468,7 +508,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_1Vec_Store_Lane_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty, llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, NoCapture<2>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
class AdvSIMD_2Vec_Load_Intrinsic
: Intrinsic<[LLVMMatchType<0>, llvm_anyvector_ty],
@@ -482,11 +522,11 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_2Vec_Store_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMAnyPointerType<LLVMMatchType<0>>],
- [IntrArgMemOnly, NoCapture<2>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
class AdvSIMD_2Vec_Store_Lane_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, NoCapture<3>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
class AdvSIMD_3Vec_Load_Intrinsic
: Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
@@ -500,12 +540,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_3Vec_Store_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMAnyPointerType<LLVMMatchType<0>>],
- [IntrArgMemOnly, NoCapture<3>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
class AdvSIMD_3Vec_Store_Lane_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty,
LLVMMatchType<0>, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, NoCapture<4>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
class AdvSIMD_4Vec_Load_Intrinsic
: Intrinsic<[LLVMMatchType<0>, LLVMMatchType<0>,
@@ -523,12 +563,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
: Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMMatchType<0>,
LLVMAnyPointerType<LLVMMatchType<0>>],
- [IntrArgMemOnly, NoCapture<4>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
class AdvSIMD_4Vec_Store_Lane_Intrinsic
: Intrinsic<[], [llvm_anyvector_ty, LLVMMatchType<0>,
LLVMMatchType<0>, LLVMMatchType<0>,
llvm_i64_ty, llvm_anyptr_ty],
- [IntrArgMemOnly, NoCapture<5>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
}
// Memory ops
@@ -611,7 +651,7 @@ def int_aarch64_neon_tbx4 : AdvSIMD_Tbx4_Intrinsic;
let TargetPrefix = "aarch64" in {
class FPCR_Get_Intrinsic
- : Intrinsic<[llvm_i64_ty], [], [IntrNoMem]>;
+ : Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrHasSideEffects]>;
}
// FPCR
@@ -725,20 +765,20 @@ def int_aarch64_irg_sp : Intrinsic<[llvm_ptr_ty], [llvm_i64_ty],
// ADDG ptr1, baseptr, (ptr0 - baseptr), tag_offset
// It is intended that ptr0 is an alloca address, and baseptr is the direct output of llvm.aarch64.irg.sp.
def int_aarch64_tagp : Intrinsic<[llvm_anyptr_ty], [LLVMMatchType<0>, llvm_ptr_ty, llvm_i64_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
// Update allocation tags for the memory range to match the tag in the pointer argument.
def int_aarch64_settag : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
- [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
+ [IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
// Update allocation tags for the memory range to match the tag in the pointer argument,
// and set memory contents to zero.
def int_aarch64_settag_zero : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty],
- [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
+ [IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
// Update allocation tags for 16-aligned, 16-sized memory region, and store a pair 8-byte values.
def int_aarch64_stgp : Intrinsic<[], [llvm_ptr_ty, llvm_i64_ty, llvm_i64_ty],
- [IntrWriteMem, IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
+ [IntrWriteMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
}
// Transactional Memory Extension (TME) Intrinsics
@@ -749,7 +789,7 @@ def int_aarch64_tstart : GCCBuiltin<"__builtin_arm_tstart">,
def int_aarch64_tcommit : GCCBuiltin<"__builtin_arm_tcommit">, Intrinsic<[]>;
def int_aarch64_tcancel : GCCBuiltin<"__builtin_arm_tcancel">,
- Intrinsic<[], [llvm_i64_ty], [ImmArg<0>]>;
+ Intrinsic<[], [llvm_i64_ty], [ImmArg<ArgIndex<0>>]>;
def int_aarch64_ttest : GCCBuiltin<"__builtin_arm_ttest">,
Intrinsic<[llvm_i64_ty], [],
@@ -764,23 +804,78 @@ def llvm_nxv16i8_ty : LLVMType<nxv16i8>;
def llvm_nxv4i32_ty : LLVMType<nxv4i32>;
def llvm_nxv2i64_ty : LLVMType<nxv2i64>;
def llvm_nxv8f16_ty : LLVMType<nxv8f16>;
+def llvm_nxv8bf16_ty : LLVMType<nxv8bf16>;
def llvm_nxv4f32_ty : LLVMType<nxv4f32>;
def llvm_nxv2f64_ty : LLVMType<nxv2f64>;
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
+ class AdvSIMD_SVE_Create_2Vector_Tuple
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>],
+ [IntrReadMem]>;
+
+ class AdvSIMD_SVE_Create_3Vector_Tuple
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>],
+ [IntrReadMem]>;
+
+ class AdvSIMD_SVE_Create_4Vector_Tuple
+ : Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>,
+ LLVMMatchType<1>],
+ [IntrReadMem]>;
+
+ class AdvSIMD_SVE_Set_Vector_Tuple
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_i32_ty, llvm_anyvector_ty],
+ [IntrReadMem, ImmArg<ArgIndex<1>>]>;
+
+ class AdvSIMD_SVE_Get_Vector_Tuple
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly, ImmArg<ArgIndex<1>>]>;
+
+ class AdvSIMD_ManyVec_PredLoad_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty, LLVMPointerToElt<0>],
+ [IntrReadMem, IntrArgMemOnly]>;
+
class AdvSIMD_1Vec_PredLoad_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMPointerTo<0>],
+ LLVMPointerToElt<0>],
[IntrReadMem, IntrArgMemOnly]>;
class AdvSIMD_1Vec_PredStore_Intrinsic
: Intrinsic<[],
[llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
- LLVMPointerTo<0>],
- [IntrArgMemOnly, NoCapture<2>]>;
+ LLVMPointerToElt<0>],
+ [IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
+
+ class AdvSIMD_2Vec_PredStore_Intrinsic
+ : Intrinsic<[],
+ [llvm_anyvector_ty, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
+ [IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
+
+ class AdvSIMD_3Vec_PredStore_Intrinsic
+ : Intrinsic<[],
+ [llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
+ [IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
+
+ class AdvSIMD_4Vec_PredStore_Intrinsic
+ : Intrinsic<[],
+ [llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, LLVMPointerToElt<0>],
+ [IntrArgMemOnly, NoCapture<ArgIndex<5>>]>;
+
+ class AdvSIMD_SVE_Index_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMVectorElementType<0>,
+ LLVMVectorElementType<0>],
+ [IntrNoMem]>;
class AdvSIMD_Merged1VectorArg_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -794,7 +889,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_3VectorArgIndexed_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -802,7 +897,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_Pred1VectorArg_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -850,7 +945,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
[LLVMMatchType<0>,
llvm_i32_ty,
llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_Saturating_N_Intrinsic<LLVMType T>
: Intrinsic<[T],
@@ -860,7 +955,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_SVE_SaturatingWithPattern_N_Intrinsic<LLVMType T>
: Intrinsic<[T],
[T, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_CNT_Intrinsic
: Intrinsic<[LLVMVectorOfBitcastsToInt<0>],
@@ -869,12 +964,6 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
llvm_anyvector_ty],
[IntrNoMem]>;
- class AdvSIMD_SVE_FP_Reduce_Intrinsic
- : Intrinsic<[llvm_anyfloat_ty],
- [LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>,
- llvm_anyvector_ty],
- [IntrNoMem]>;
-
class AdvSIMD_SVE_ReduceWithInit_Intrinsic
: Intrinsic<[LLVMVectorElementType<0>],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -882,19 +971,12 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
llvm_anyvector_ty],
[IntrNoMem]>;
- class AdvSIMD_SVE_FP_ReduceWithInit_Intrinsic
- : Intrinsic<[llvm_anyfloat_ty],
- [LLVMScalarOrSameVectorWidth<1, llvm_i1_ty>,
- LLVMMatchType<0>,
- llvm_anyvector_ty],
- [IntrNoMem]>;
-
class AdvSIMD_SVE_ShiftByImm_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
LLVMMatchType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
class AdvSIMD_SVE_ShiftWide_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -914,7 +996,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_SVE_CMLA_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -923,7 +1005,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMMatchType<0>,
LLVMMatchType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
class AdvSIMD_SVE_CMLA_LANE_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
@@ -932,6 +1014,23 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMMatchType<0>,
llvm_i32_ty,
llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
+
+ class AdvSIMD_SVE_DUP_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMVectorElementType<0>],
+ [IntrNoMem]>;
+
+ class AdvSIMD_SVE_DUP_Unpred_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty], [LLVMVectorElementType<0>],
+ [IntrNoMem]>;
+
+ class AdvSIMD_SVE_DUPQ_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ llvm_i64_ty],
[IntrNoMem]>;
class AdvSIMD_SVE_EXPA_Intrinsic
@@ -962,7 +1061,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_SVE_PTRUE_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[llvm_i32_ty],
- [IntrNoMem, ImmArg<0>]>;
+ [IntrNoMem, ImmArg<ArgIndex<0>>]>;
class AdvSIMD_SVE_PUNPKHI_Intrinsic
: Intrinsic<[LLVMHalfElementsVectorType<0>],
@@ -992,7 +1091,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class AdvSIMD_SVE_CNTB_Intrinsic
: Intrinsic<[llvm_i64_ty],
[llvm_i32_ty],
- [IntrNoMem, ImmArg<0>]>;
+ [IntrNoMem, ImmArg<ArgIndex<0>>]>;
class AdvSIMD_SVE_CNTP_Intrinsic
: Intrinsic<[llvm_i64_ty],
@@ -1012,7 +1111,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMSubdivide4VectorType<0>,
LLVMSubdivide4VectorType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
class AdvSIMD_SVE_PTEST_Intrinsic
: Intrinsic<[llvm_i1_ty],
@@ -1026,6 +1125,45 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMVectorOfBitcastsToInt<0>],
[IntrNoMem]>;
+ class AdvSIMD_SVE2_TBX_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMMatchType<0>,
+ LLVMVectorOfBitcastsToInt<0>],
+ [IntrNoMem]>;
+
+ class SVE2_1VectorArg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>,
+ llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+ class SVE2_2VectorArg_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>,
+ LLVMSubdivide2VectorType<0>],
+ [IntrNoMem]>;
+
+ class SVE2_2VectorArgIndexed_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMSubdivide2VectorType<0>,
+ LLVMSubdivide2VectorType<0>,
+ llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+ class SVE2_2VectorArg_Wide_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMSubdivide2VectorType<0>],
+ [IntrNoMem]>;
+
+ class SVE2_2VectorArg_Pred_Long_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
+ LLVMMatchType<0>,
+ LLVMSubdivide2VectorType<0>],
+ [IntrNoMem]>;
+
class SVE2_3VectorArg_Long_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>,
@@ -1039,7 +1177,7 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
LLVMSubdivide2VectorType<0>,
LLVMSubdivide2VectorType<0>,
llvm_i32_ty],
- [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
class SVE2_1VectorArg_Narrowing_Intrinsic
: Intrinsic<[LLVMSubdivide2VectorType<0>],
@@ -1066,23 +1204,46 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
class SVE2_1VectorArg_Imm_Narrowing_Intrinsic
: Intrinsic<[LLVMSubdivide2VectorType<0>],
[llvm_anyvector_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
class SVE2_2VectorArg_Imm_Narrowing_Intrinsic
: Intrinsic<[LLVMSubdivide2VectorType<0>],
[LLVMSubdivide2VectorType<0>, llvm_anyvector_ty,
llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+ class SVE2_CONFLICT_DETECT_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMAnyPointerType<llvm_any_ty>,
+ LLVMMatchType<1>]>;
+
+ class SVE2_3VectorArg_Indexed_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMSubdivide2VectorType<0>,
+ LLVMSubdivide2VectorType<0>,
+ llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+ class AdvSIMD_SVE_CDOT_LANE_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>,
+ LLVMSubdivide4VectorType<0>,
+ LLVMSubdivide4VectorType<0>,
+ llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
// NOTE: There is no relationship between these intrinsics beyond an attempt
// to reuse currently identical class definitions.
class AdvSIMD_SVE_LOGB_Intrinsic : AdvSIMD_SVE_CNT_Intrinsic;
+ class AdvSIMD_SVE2_CADD_Intrinsic : AdvSIMD_2VectorArgIndexed_Intrinsic;
+ class AdvSIMD_SVE2_CMLA_Intrinsic : AdvSIMD_3VectorArgIndexed_Intrinsic;
// This class of intrinsics are not intended to be useful within LLVM IR but
// are instead here to support some of the more regid parts of the ACLE.
- class Builtin_SVCVT<string name, LLVMType OUT, LLVMType IN>
- : GCCBuiltin<"__builtin_sve_" # name>,
- Intrinsic<[OUT], [OUT, llvm_nxv16i1_ty, IN], [IntrNoMem]>;
+ class Builtin_SVCVT<string name, LLVMType OUT, LLVMType PRED, LLVMType IN>
+ : Intrinsic<[OUT], [OUT, PRED, IN], [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
@@ -1107,7 +1268,7 @@ class AdvSIMD_SVE_WHILE_Intrinsic
[llvm_anyint_ty, LLVMMatchType<1>],
[IntrNoMem]>;
-class AdvSIMD_GatherLoad_64bitOffset_Intrinsic
+class AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -1116,7 +1277,7 @@ class AdvSIMD_GatherLoad_64bitOffset_Intrinsic
],
[IntrReadMem, IntrArgMemOnly]>;
-class AdvSIMD_GatherLoad_32bitOffset_Intrinsic
+class AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -1125,7 +1286,7 @@ class AdvSIMD_GatherLoad_32bitOffset_Intrinsic
],
[IntrReadMem, IntrArgMemOnly]>;
-class AdvSIMD_GatherLoad_VecTorBase_Intrinsic
+class AdvSIMD_GatherLoad_VS_Intrinsic
: Intrinsic<[llvm_anyvector_ty],
[
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
@@ -1134,7 +1295,7 @@ class AdvSIMD_GatherLoad_VecTorBase_Intrinsic
],
[IntrReadMem, IntrArgMemOnly]>;
-class AdvSIMD_ScatterStore_64bitOffset_Intrinsic
+class AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic
: Intrinsic<[],
[
llvm_anyvector_ty,
@@ -1144,7 +1305,7 @@ class AdvSIMD_ScatterStore_64bitOffset_Intrinsic
],
[IntrWriteMem, IntrArgMemOnly]>;
-class AdvSIMD_ScatterStore_32bitOffset_Intrinsic
+class AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic
: Intrinsic<[],
[
llvm_anyvector_ty,
@@ -1154,28 +1315,148 @@ class AdvSIMD_ScatterStore_32bitOffset_Intrinsic
],
[IntrWriteMem, IntrArgMemOnly]>;
-class AdvSIMD_ScatterStore_VectorBase_Intrinsic
+class AdvSIMD_ScatterStore_VS_Intrinsic
: Intrinsic<[],
[
llvm_anyvector_ty,
LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
llvm_anyvector_ty, llvm_i64_ty
],
- [IntrWriteMem, IntrArgMemOnly, ImmArg<3>]>;
+ [IntrWriteMem, IntrArgMemOnly]>;
+
+
+class SVE_gather_prf_SV
+ : Intrinsic<[],
+ [
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, // Predicate
+ llvm_ptr_ty, // Base address
+ llvm_anyvector_ty, // Offsets
+ llvm_i32_ty // Prfop
+ ],
+ [IntrInaccessibleMemOrArgMemOnly, NoCapture<ArgIndex<1>>, ImmArg<ArgIndex<3>>]>;
+
+class SVE_gather_prf_VS
+ : Intrinsic<[],
+ [
+ LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>, // Predicate
+ llvm_anyvector_ty, // Base addresses
+ llvm_i64_ty, // Scalar offset
+ llvm_i32_ty // Prfop
+ ],
+ [IntrInaccessibleMemOrArgMemOnly, ImmArg<ArgIndex<3>>]>;
+
+class SVE_MatMul_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMSubdivide4VectorType<0>, LLVMSubdivide4VectorType<0>],
+ [IntrNoMem]>;
+
+class SVE_4Vec_BF16
+ : Intrinsic<[llvm_nxv4f32_ty],
+ [llvm_nxv4f32_ty, llvm_nxv8bf16_ty, llvm_nxv8bf16_ty],
+ [IntrNoMem]>;
+
+class SVE_4Vec_BF16_Indexed
+ : Intrinsic<[llvm_nxv4f32_ty],
+ [llvm_nxv4f32_ty, llvm_nxv8bf16_ty, llvm_nxv8bf16_ty, llvm_i64_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+//
+// Vector tuple creation intrinsics (ACLE)
+//
+
+def int_aarch64_sve_tuple_create2 : AdvSIMD_SVE_Create_2Vector_Tuple;
+def int_aarch64_sve_tuple_create3 : AdvSIMD_SVE_Create_3Vector_Tuple;
+def int_aarch64_sve_tuple_create4 : AdvSIMD_SVE_Create_4Vector_Tuple;
+
+//
+// Vector tuple insertion/extraction intrinsics (ACLE)
+//
+
+def int_aarch64_sve_tuple_get : AdvSIMD_SVE_Get_Vector_Tuple;
+def int_aarch64_sve_tuple_set : AdvSIMD_SVE_Set_Vector_Tuple;
//
// Loads
//
+def int_aarch64_sve_ld1 : AdvSIMD_1Vec_PredLoad_Intrinsic;
+
+def int_aarch64_sve_ld2 : AdvSIMD_ManyVec_PredLoad_Intrinsic;
+def int_aarch64_sve_ld3 : AdvSIMD_ManyVec_PredLoad_Intrinsic;
+def int_aarch64_sve_ld4 : AdvSIMD_ManyVec_PredLoad_Intrinsic;
+
def int_aarch64_sve_ldnt1 : AdvSIMD_1Vec_PredLoad_Intrinsic;
+def int_aarch64_sve_ldnf1 : AdvSIMD_1Vec_PredLoad_Intrinsic;
+def int_aarch64_sve_ldff1 : AdvSIMD_1Vec_PredLoad_Intrinsic;
+
+def int_aarch64_sve_ld1rq : AdvSIMD_1Vec_PredLoad_Intrinsic;
+def int_aarch64_sve_ld1ro : AdvSIMD_1Vec_PredLoad_Intrinsic;
//
// Stores
//
+def int_aarch64_sve_st1 : AdvSIMD_1Vec_PredStore_Intrinsic;
+def int_aarch64_sve_st2 : AdvSIMD_2Vec_PredStore_Intrinsic;
+def int_aarch64_sve_st3 : AdvSIMD_3Vec_PredStore_Intrinsic;
+def int_aarch64_sve_st4 : AdvSIMD_4Vec_PredStore_Intrinsic;
+
def int_aarch64_sve_stnt1 : AdvSIMD_1Vec_PredStore_Intrinsic;
//
+// Prefetches
+//
+
+def int_aarch64_sve_prf
+ : Intrinsic<[], [llvm_anyvector_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrArgMemOnly, ImmArg<ArgIndex<2>>]>;
+
+// Scalar + 32-bit scaled offset vector, zero extend, packed and
+// unpacked.
+def int_aarch64_sve_prfb_gather_uxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfh_gather_uxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfw_gather_uxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfd_gather_uxtw_index : SVE_gather_prf_SV;
+
+// Scalar + 32-bit scaled offset vector, sign extend, packed and
+// unpacked.
+def int_aarch64_sve_prfb_gather_sxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfw_gather_sxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfh_gather_sxtw_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfd_gather_sxtw_index : SVE_gather_prf_SV;
+
+// Scalar + 64-bit scaled offset vector.
+def int_aarch64_sve_prfb_gather_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfh_gather_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfw_gather_index : SVE_gather_prf_SV;
+def int_aarch64_sve_prfd_gather_index : SVE_gather_prf_SV;
+
+// Vector + scalar.
+def int_aarch64_sve_prfb_gather_scalar_offset : SVE_gather_prf_VS;
+def int_aarch64_sve_prfh_gather_scalar_offset : SVE_gather_prf_VS;
+def int_aarch64_sve_prfw_gather_scalar_offset : SVE_gather_prf_VS;
+def int_aarch64_sve_prfd_gather_scalar_offset : SVE_gather_prf_VS;
+
+//
+// Scalar to vector operations
+//
+
+def int_aarch64_sve_dup : AdvSIMD_SVE_DUP_Intrinsic;
+def int_aarch64_sve_dup_x : AdvSIMD_SVE_DUP_Unpred_Intrinsic;
+
+
+def int_aarch64_sve_index : AdvSIMD_SVE_Index_Intrinsic;
+
+//
+// Address calculation
+//
+
+def int_aarch64_sve_adrb : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_adrh : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_adrw : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_adrd : AdvSIMD_2VectorArg_Intrinsic;
+
+//
// Integer arithmetic
//
@@ -1183,7 +1464,10 @@ def int_aarch64_sve_add : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_sub : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_subr : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_pmul : AdvSIMD_2VectorArg_Intrinsic;
+
def int_aarch64_sve_mul : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_mul_lane : AdvSIMD_2VectorArgIndexed_Intrinsic;
def int_aarch64_sve_smulh : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_umulh : AdvSIMD_Pred2VectorArg_Intrinsic;
@@ -1202,7 +1486,9 @@ def int_aarch64_sve_uabd : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_mad : AdvSIMD_Pred3VectorArg_Intrinsic;
def int_aarch64_sve_msb : AdvSIMD_Pred3VectorArg_Intrinsic;
def int_aarch64_sve_mla : AdvSIMD_Pred3VectorArg_Intrinsic;
+def int_aarch64_sve_mla_lane : AdvSIMD_3VectorArgIndexed_Intrinsic;
def int_aarch64_sve_mls : AdvSIMD_Pred3VectorArg_Intrinsic;
+def int_aarch64_sve_mls_lane : AdvSIMD_3VectorArgIndexed_Intrinsic;
def int_aarch64_sve_saddv : AdvSIMD_SVE_SADDV_Reduce_Intrinsic;
def int_aarch64_sve_uaddv : AdvSIMD_SVE_SADDV_Reduce_Intrinsic;
@@ -1225,6 +1511,11 @@ def int_aarch64_sve_sdot_lane : AdvSIMD_SVE_DOT_Indexed_Intrinsic;
def int_aarch64_sve_udot : AdvSIMD_SVE_DOT_Intrinsic;
def int_aarch64_sve_udot_lane : AdvSIMD_SVE_DOT_Indexed_Intrinsic;
+def int_aarch64_sve_sqadd_x : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_sqsub_x : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_uqadd_x : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_uqsub_x : AdvSIMD_2VectorArg_Intrinsic;
+
// Shifts
def int_aarch64_sve_asr : AdvSIMD_Pred2VectorArg_Intrinsic;
@@ -1278,6 +1569,15 @@ def int_aarch64_sve_cntd : AdvSIMD_SVE_CNTB_Intrinsic;
def int_aarch64_sve_cntp : AdvSIMD_SVE_CNTP_Intrinsic;
//
+// FFR manipulation
+//
+
+def int_aarch64_sve_rdffr : GCCBuiltin<"__builtin_sve_svrdffr">, Intrinsic<[llvm_nxv16i1_ty], []>;
+def int_aarch64_sve_rdffr_z : GCCBuiltin<"__builtin_sve_svrdffr_z">, Intrinsic<[llvm_nxv16i1_ty], [llvm_nxv16i1_ty]>;
+def int_aarch64_sve_setffr : GCCBuiltin<"__builtin_sve_svsetffr">, Intrinsic<[], []>;
+def int_aarch64_sve_wrffr : GCCBuiltin<"__builtin_sve_svwrffr">, Intrinsic<[], [llvm_nxv16i1_ty]>;
+
+//
// Saturating scalar arithmetic
//
@@ -1363,7 +1663,9 @@ def int_aarch64_sve_clasta_n : AdvSIMD_SVE_ReduceWithInit_Intrinsic;
def int_aarch64_sve_clastb : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_clastb_n : AdvSIMD_SVE_ReduceWithInit_Intrinsic;
def int_aarch64_sve_compact : AdvSIMD_Pred1VectorArg_Intrinsic;
+def int_aarch64_sve_dupq_lane : AdvSIMD_SVE_DUPQ_Intrinsic;
def int_aarch64_sve_ext : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sel : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_lasta : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_lastb : AdvSIMD_SVE_Reduce_Intrinsic;
def int_aarch64_sve_rev : AdvSIMD_1VectorArg_Intrinsic;
@@ -1373,12 +1675,18 @@ def int_aarch64_sve_sunpklo : AdvSIMD_SVE_Unpack_Intrinsic;
def int_aarch64_sve_tbl : AdvSIMD_SVE_TBL_Intrinsic;
def int_aarch64_sve_trn1 : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_trn2 : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_trn1q : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_trn2q : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_uunpkhi : AdvSIMD_SVE_Unpack_Intrinsic;
def int_aarch64_sve_uunpklo : AdvSIMD_SVE_Unpack_Intrinsic;
def int_aarch64_sve_uzp1 : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_uzp2 : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_uzp1q : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_uzp2q : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_zip1 : AdvSIMD_2VectorArg_Intrinsic;
def int_aarch64_sve_zip2 : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_zip1q : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_zip2q : AdvSIMD_2VectorArg_Intrinsic;
//
// Logical operations
@@ -1470,12 +1778,12 @@ def int_aarch64_sve_ftssel_x : AdvSIMD_SVE_TSMUL_Intrinsic;
// Floating-point reductions
//
-def int_aarch64_sve_fadda : AdvSIMD_SVE_FP_ReduceWithInit_Intrinsic;
-def int_aarch64_sve_faddv : AdvSIMD_SVE_FP_Reduce_Intrinsic;
-def int_aarch64_sve_fmaxv : AdvSIMD_SVE_FP_Reduce_Intrinsic;
-def int_aarch64_sve_fmaxnmv : AdvSIMD_SVE_FP_Reduce_Intrinsic;
-def int_aarch64_sve_fminv : AdvSIMD_SVE_FP_Reduce_Intrinsic;
-def int_aarch64_sve_fminnmv : AdvSIMD_SVE_FP_Reduce_Intrinsic;
+def int_aarch64_sve_fadda : AdvSIMD_SVE_ReduceWithInit_Intrinsic;
+def int_aarch64_sve_faddv : AdvSIMD_SVE_Reduce_Intrinsic;
+def int_aarch64_sve_fmaxv : AdvSIMD_SVE_Reduce_Intrinsic;
+def int_aarch64_sve_fmaxnmv : AdvSIMD_SVE_Reduce_Intrinsic;
+def int_aarch64_sve_fminv : AdvSIMD_SVE_Reduce_Intrinsic;
+def int_aarch64_sve_fminnmv : AdvSIMD_SVE_Reduce_Intrinsic;
//
// Floating-point conversions
@@ -1500,41 +1808,44 @@ def int_aarch64_sve_fcmpgt : AdvSIMD_SVE_Compare_Intrinsic;
def int_aarch64_sve_fcmpne : AdvSIMD_SVE_Compare_Intrinsic;
def int_aarch64_sve_fcmpuo : AdvSIMD_SVE_Compare_Intrinsic;
-def int_aarch64_sve_fcvtzs_i32f16 : Builtin_SVCVT<"svcvt_s32_f16_m", llvm_nxv4i32_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvtzs_i32f64 : Builtin_SVCVT<"svcvt_s32_f64_m", llvm_nxv4i32_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvtzs_i64f16 : Builtin_SVCVT<"svcvt_s64_f16_m", llvm_nxv2i64_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvtzs_i64f32 : Builtin_SVCVT<"svcvt_s64_f32_m", llvm_nxv2i64_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvtzs_i32f16 : Builtin_SVCVT<"svcvt_s32_f16_m", llvm_nxv4i32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvtzs_i32f64 : Builtin_SVCVT<"svcvt_s32_f64_m", llvm_nxv4i32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvtzs_i64f16 : Builtin_SVCVT<"svcvt_s64_f16_m", llvm_nxv2i64_ty, llvm_nxv2i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvtzs_i64f32 : Builtin_SVCVT<"svcvt_s64_f32_m", llvm_nxv2i64_ty, llvm_nxv2i1_ty, llvm_nxv4f32_ty>;
+
+def int_aarch64_sve_fcvt_bf16f32 : Builtin_SVCVT<"svcvt_bf16_f32_m", llvm_nxv8bf16_ty, llvm_nxv8i1_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvtnt_bf16f32 : Builtin_SVCVT<"svcvtnt_bf16_f32_m", llvm_nxv8bf16_ty, llvm_nxv8i1_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvtzu_i32f16 : Builtin_SVCVT<"svcvt_u32_f16_m", llvm_nxv4i32_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvtzu_i32f64 : Builtin_SVCVT<"svcvt_u32_f64_m", llvm_nxv4i32_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvtzu_i64f16 : Builtin_SVCVT<"svcvt_u64_f16_m", llvm_nxv2i64_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvtzu_i64f32 : Builtin_SVCVT<"svcvt_u64_f32_m", llvm_nxv2i64_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvtzu_i32f16 : Builtin_SVCVT<"svcvt_u32_f16_m", llvm_nxv4i32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvtzu_i32f64 : Builtin_SVCVT<"svcvt_u32_f64_m", llvm_nxv4i32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvtzu_i64f16 : Builtin_SVCVT<"svcvt_u64_f16_m", llvm_nxv2i64_ty, llvm_nxv2i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvtzu_i64f32 : Builtin_SVCVT<"svcvt_u64_f32_m", llvm_nxv2i64_ty, llvm_nxv2i1_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvt_f16f32 : Builtin_SVCVT<"svcvt_f16_f32_m", llvm_nxv8f16_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvt_f16f64 : Builtin_SVCVT<"svcvt_f16_f64_m", llvm_nxv8f16_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvt_f32f64 : Builtin_SVCVT<"svcvt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvt_f16f32 : Builtin_SVCVT<"svcvt_f16_f32_m", llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvt_f16f64 : Builtin_SVCVT<"svcvt_f16_f64_m", llvm_nxv8f16_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvt_f32f64 : Builtin_SVCVT<"svcvt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvt_f32f16 : Builtin_SVCVT<"svcvt_f32_f16_m", llvm_nxv4f32_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvt_f64f16 : Builtin_SVCVT<"svcvt_f64_f16_m", llvm_nxv2f64_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvt_f64f32 : Builtin_SVCVT<"svcvt_f64_f32_m", llvm_nxv2f64_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvt_f32f16 : Builtin_SVCVT<"svcvt_f32_f16_m", llvm_nxv4f32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvt_f64f16 : Builtin_SVCVT<"svcvt_f64_f16_m", llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvt_f64f32 : Builtin_SVCVT<"svcvt_f64_f32_m", llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvtlt_f32f16 : Builtin_SVCVT<"svcvtlt_f32_f16_m", llvm_nxv4f32_ty, llvm_nxv8f16_ty>;
-def int_aarch64_sve_fcvtlt_f64f32 : Builtin_SVCVT<"svcvtlt_f64_f32_m", llvm_nxv2f64_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvtnt_f16f32 : Builtin_SVCVT<"svcvtnt_f16_f32_m", llvm_nxv8f16_ty, llvm_nxv4f32_ty>;
-def int_aarch64_sve_fcvtnt_f32f64 : Builtin_SVCVT<"svcvtnt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvtlt_f32f16 : Builtin_SVCVT<"svcvtlt_f32_f16_m", llvm_nxv4f32_ty, llvm_nxv4i1_ty, llvm_nxv8f16_ty>;
+def int_aarch64_sve_fcvtlt_f64f32 : Builtin_SVCVT<"svcvtlt_f64_f32_m", llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvtnt_f16f32 : Builtin_SVCVT<"svcvtnt_f16_f32_m", llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4f32_ty>;
+def int_aarch64_sve_fcvtnt_f32f64 : Builtin_SVCVT<"svcvtnt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvtx_f32f64 : Builtin_SVCVT<"svcvtx_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_fcvtxnt_f32f64 : Builtin_SVCVT<"svcvtxnt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvtx_f32f64 : Builtin_SVCVT<"svcvtx_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
+def int_aarch64_sve_fcvtxnt_f32f64 : Builtin_SVCVT<"svcvtxnt_f32_f64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2f64_ty>;
-def int_aarch64_sve_scvtf_f16i32 : Builtin_SVCVT<"svcvt_f16_s32_m", llvm_nxv8f16_ty, llvm_nxv4i32_ty>;
-def int_aarch64_sve_scvtf_f16i64 : Builtin_SVCVT<"svcvt_f16_s64_m", llvm_nxv8f16_ty, llvm_nxv2i64_ty>;
-def int_aarch64_sve_scvtf_f32i64 : Builtin_SVCVT<"svcvt_f32_s64_m", llvm_nxv4f32_ty, llvm_nxv2i64_ty>;
-def int_aarch64_sve_scvtf_f64i32 : Builtin_SVCVT<"svcvt_f64_s32_m", llvm_nxv2f64_ty, llvm_nxv4i32_ty>;
+def int_aarch64_sve_scvtf_f16i32 : Builtin_SVCVT<"svcvt_f16_s32_m", llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4i32_ty>;
+def int_aarch64_sve_scvtf_f16i64 : Builtin_SVCVT<"svcvt_f16_s64_m", llvm_nxv8f16_ty, llvm_nxv2i1_ty, llvm_nxv2i64_ty>;
+def int_aarch64_sve_scvtf_f32i64 : Builtin_SVCVT<"svcvt_f32_s64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2i64_ty>;
+def int_aarch64_sve_scvtf_f64i32 : Builtin_SVCVT<"svcvt_f64_s32_m", llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv4i32_ty>;
-def int_aarch64_sve_ucvtf_f16i32 : Builtin_SVCVT<"svcvt_f16_u32_m", llvm_nxv8f16_ty, llvm_nxv4i32_ty>;
-def int_aarch64_sve_ucvtf_f16i64 : Builtin_SVCVT<"svcvt_f16_u64_m", llvm_nxv8f16_ty, llvm_nxv2i64_ty>;
-def int_aarch64_sve_ucvtf_f32i64 : Builtin_SVCVT<"svcvt_f32_u64_m", llvm_nxv4f32_ty, llvm_nxv2i64_ty>;
-def int_aarch64_sve_ucvtf_f64i32 : Builtin_SVCVT<"svcvt_f64_u32_m", llvm_nxv2f64_ty, llvm_nxv4i32_ty>;
+def int_aarch64_sve_ucvtf_f16i32 : Builtin_SVCVT<"svcvt_f16_u32_m", llvm_nxv8f16_ty, llvm_nxv4i1_ty, llvm_nxv4i32_ty>;
+def int_aarch64_sve_ucvtf_f16i64 : Builtin_SVCVT<"svcvt_f16_u64_m", llvm_nxv8f16_ty, llvm_nxv2i1_ty, llvm_nxv2i64_ty>;
+def int_aarch64_sve_ucvtf_f32i64 : Builtin_SVCVT<"svcvt_f32_u64_m", llvm_nxv4f32_ty, llvm_nxv2i1_ty, llvm_nxv2i64_ty>;
+def int_aarch64_sve_ucvtf_f64i32 : Builtin_SVCVT<"svcvt_f64_u32_m", llvm_nxv2f64_ty, llvm_nxv2i1_ty, llvm_nxv4i32_ty>;
//
// Predicate creation
@@ -1548,6 +1859,13 @@ def int_aarch64_sve_ptrue : AdvSIMD_SVE_PTRUE_Intrinsic;
def int_aarch64_sve_and_z : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_bic_z : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_brka : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_brka_z : AdvSIMD_Pred1VectorArg_Intrinsic;
+def int_aarch64_sve_brkb : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_brkb_z : AdvSIMD_Pred1VectorArg_Intrinsic;
+def int_aarch64_sve_brkn_z : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_brkpa_z : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_brkpb_z : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_eor_z : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_nand_z : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_nor_z : AdvSIMD_Pred2VectorArg_Intrinsic;
@@ -1567,67 +1885,267 @@ def int_aarch64_sve_ptest_first : AdvSIMD_SVE_PTEST_Intrinsic;
def int_aarch64_sve_ptest_last : AdvSIMD_SVE_PTEST_Intrinsic;
//
-// Gather loads:
+// Reinterpreting data
+//
+
+def int_aarch64_sve_convert_from_svbool : Intrinsic<[llvm_anyvector_ty],
+ [llvm_nxv16i1_ty],
+ [IntrNoMem]>;
+
+def int_aarch64_sve_convert_to_svbool : Intrinsic<[llvm_nxv16i1_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem]>;
+
+//
+// Gather loads: scalar base + vector offsets
+//
+
+// 64 bit unscaled offsets
+def int_aarch64_sve_ld1_gather : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
+
+// 64 bit scaled offsets
+def int_aarch64_sve_ld1_gather_index : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
+
+// 32 bit unscaled offsets, sign (sxtw) or zero (zxtw) extended to 64 bits
+def int_aarch64_sve_ld1_gather_sxtw : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+def int_aarch64_sve_ld1_gather_uxtw : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+
+// 32 bit scaled offsets, sign (sxtw) or zero (zxtw) extended to 64 bits
+def int_aarch64_sve_ld1_gather_sxtw_index : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+def int_aarch64_sve_ld1_gather_uxtw_index : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+
+//
+// Gather loads: vector base + scalar offset
+//
+
+def int_aarch64_sve_ld1_gather_scalar_offset : AdvSIMD_GatherLoad_VS_Intrinsic;
+
+
+//
+// First-faulting gather loads: scalar base + vector offsets
+//
+
+// 64 bit unscaled offsets
+def int_aarch64_sve_ldff1_gather : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
+
+// 64 bit scaled offsets
+def int_aarch64_sve_ldff1_gather_index : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
+
+// 32 bit unscaled offsets, sign (sxtw) or zero (uxtw) extended to 64 bits
+def int_aarch64_sve_ldff1_gather_sxtw : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+def int_aarch64_sve_ldff1_gather_uxtw : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+
+// 32 bit scaled offsets, sign (sxtw) or zero (uxtw) extended to 64 bits
+def int_aarch64_sve_ldff1_gather_sxtw_index : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+def int_aarch64_sve_ldff1_gather_uxtw_index : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
+
+//
+// First-faulting gather loads: vector base + scalar offset
//
-// scalar + vector, 64 bit unscaled offsets
-def int_aarch64_sve_ld1_gather : AdvSIMD_GatherLoad_64bitOffset_Intrinsic;
+def int_aarch64_sve_ldff1_gather_scalar_offset : AdvSIMD_GatherLoad_VS_Intrinsic;
-// scalar + vector, 64 bit scaled offsets
-def int_aarch64_sve_ld1_gather_index : AdvSIMD_GatherLoad_64bitOffset_Intrinsic;
-// scalar + vector, 32 bit unscaled offsets, sign (sxtw) or zero (zxtw)
-// extended to 64 bits
-def int_aarch64_sve_ld1_gather_sxtw : AdvSIMD_GatherLoad_32bitOffset_Intrinsic;
-def int_aarch64_sve_ld1_gather_uxtw : AdvSIMD_GatherLoad_32bitOffset_Intrinsic;
+//
+// Non-temporal gather loads: scalar base + vector offsets
+//
+
+// 64 bit unscaled offsets
+def int_aarch64_sve_ldnt1_gather : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
-// scalar + vector, 32 bit scaled offsets, sign (sxtw) or zero (zxtw) extended
-// to 64 bits
-def int_aarch64_sve_ld1_gather_sxtw_index : AdvSIMD_GatherLoad_32bitOffset_Intrinsic;
-def int_aarch64_sve_ld1_gather_uxtw_index : AdvSIMD_GatherLoad_32bitOffset_Intrinsic;
+// 64 bit indices
+def int_aarch64_sve_ldnt1_gather_index : AdvSIMD_GatherLoad_SV_64b_Offsets_Intrinsic;
-// vector base + immediate index
-def int_aarch64_sve_ld1_gather_imm : AdvSIMD_GatherLoad_VecTorBase_Intrinsic;
+// 32 bit unscaled offsets, zero (zxtw) extended to 64 bits
+def int_aarch64_sve_ldnt1_gather_uxtw : AdvSIMD_GatherLoad_SV_32b_Offsets_Intrinsic;
//
-// Scatter stores:
+// Non-temporal gather loads: vector base + scalar offset
//
-// scalar + vector, 64 bit unscaled offsets
-def int_aarch64_sve_st1_scatter : AdvSIMD_ScatterStore_64bitOffset_Intrinsic;
+def int_aarch64_sve_ldnt1_gather_scalar_offset : AdvSIMD_GatherLoad_VS_Intrinsic;
-// scalar + vector, 64 bit scaled offsets
+//
+// Scatter stores: scalar base + vector offsets
+//
+
+// 64 bit unscaled offsets
+def int_aarch64_sve_st1_scatter : AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic;
+
+// 64 bit scaled offsets
def int_aarch64_sve_st1_scatter_index
- : AdvSIMD_ScatterStore_64bitOffset_Intrinsic;
+ : AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic;
-// scalar + vector, 32 bit unscaled offsets, sign (sxtw) or zero (zxtw)
-// extended to 64 bits
+// 32 bit unscaled offsets, sign (sxtw) or zero (zxtw) extended to 64 bits
def int_aarch64_sve_st1_scatter_sxtw
- : AdvSIMD_ScatterStore_32bitOffset_Intrinsic;
+ : AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic;
def int_aarch64_sve_st1_scatter_uxtw
- : AdvSIMD_ScatterStore_32bitOffset_Intrinsic;
+ : AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic;
-// scalar + vector, 32 bit scaled offsets, sign (sxtw) or zero (zxtw) extended
-// to 64 bits
+// 32 bit scaled offsets, sign (sxtw) or zero (zxtw) extended to 64 bits
def int_aarch64_sve_st1_scatter_sxtw_index
- : AdvSIMD_ScatterStore_32bitOffset_Intrinsic;
+ : AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic;
def int_aarch64_sve_st1_scatter_uxtw_index
- : AdvSIMD_ScatterStore_32bitOffset_Intrinsic;
+ : AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic;
+
+//
+// Scatter stores: vector base + scalar offset
+//
-// vector base + immediate index
-def int_aarch64_sve_st1_scatter_imm : AdvSIMD_ScatterStore_VectorBase_Intrinsic;
+def int_aarch64_sve_st1_scatter_scalar_offset : AdvSIMD_ScatterStore_VS_Intrinsic;
+
+//
+// Non-temporal scatter stores: scalar base + vector offsets
+//
+
+// 64 bit unscaled offsets
+def int_aarch64_sve_stnt1_scatter : AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic;
+
+// 64 bit indices
+def int_aarch64_sve_stnt1_scatter_index
+ : AdvSIMD_ScatterStore_SV_64b_Offsets_Intrinsic;
+
+// 32 bit unscaled offsets, zero (zxtw) extended to 64 bits
+def int_aarch64_sve_stnt1_scatter_uxtw : AdvSIMD_ScatterStore_SV_32b_Offsets_Intrinsic;
+
+//
+// Non-temporal scatter stores: vector base + scalar offset
+//
+
+def int_aarch64_sve_stnt1_scatter_scalar_offset : AdvSIMD_ScatterStore_VS_Intrinsic;
+
+//
+// SVE2 - Uniform DSP operations
+//
+
+def int_aarch64_sve_saba : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_shadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_shsub : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_shsubr : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sli : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sqabs : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_sqadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sqdmulh : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_sqdmulh_lane : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sqneg : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_sqrdmlah : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_sqrdmlah_lane : AdvSIMD_3VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sqrdmlsh : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_sqrdmlsh_lane : AdvSIMD_3VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sqrdmulh : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_sqrdmulh_lane : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_sqrshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sqshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sqshlu : AdvSIMD_SVE_ShiftByImm_Intrinsic;
+def int_aarch64_sve_sqsub : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sqsubr : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_srhadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sri : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_srshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_srshr : AdvSIMD_SVE_ShiftByImm_Intrinsic;
+def int_aarch64_sve_srsra : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_ssra : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_suqadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uaba : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_uhadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uhsub : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uhsubr : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uqadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uqrshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uqshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uqsub : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uqsubr : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_urecpe : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_urhadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_urshl : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_urshr : AdvSIMD_SVE_ShiftByImm_Intrinsic;
+def int_aarch64_sve_ursqrte : AdvSIMD_Merged1VectorArg_Intrinsic;
+def int_aarch64_sve_ursra : AdvSIMD_2VectorArgIndexed_Intrinsic;
+def int_aarch64_sve_usqadd : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_usra : AdvSIMD_2VectorArgIndexed_Intrinsic;
+
+//
+// SVE2 - Widening DSP operations
+//
+
+def int_aarch64_sve_sabalb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sabalt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sabdlb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sabdlt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_saddlb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_saddlt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_saddwb : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_saddwt : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_sshllb : SVE2_1VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sshllt : SVE2_1VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ssublb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ssublt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ssubwb : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_ssubwt : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_uabalb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uabalt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uabdlb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uabdlt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uaddlb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uaddlt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_uaddwb : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_uaddwt : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_ushllb : SVE2_1VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ushllt : SVE2_1VectorArg_Long_Intrinsic;
+def int_aarch64_sve_usublb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_usublt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_usubwb : SVE2_2VectorArg_Wide_Intrinsic;
+def int_aarch64_sve_usubwt : SVE2_2VectorArg_Wide_Intrinsic;
//
// SVE2 - Non-widening pairwise arithmetic
//
+def int_aarch64_sve_addp : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_faddp : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_fmaxp : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_fmaxnmp : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_fminp : AdvSIMD_Pred2VectorArg_Intrinsic;
def int_aarch64_sve_fminnmp : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_smaxp : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_sminp : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_umaxp : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_uminp : AdvSIMD_Pred2VectorArg_Intrinsic;
+
+//
+// SVE2 - Widening pairwise arithmetic
+//
+
+def int_aarch64_sve_sadalp : SVE2_2VectorArg_Pred_Long_Intrinsic;
+def int_aarch64_sve_uadalp : SVE2_2VectorArg_Pred_Long_Intrinsic;
+
+//
+// SVE2 - Uniform complex integer arithmetic
+//
+
+def int_aarch64_sve_cadd_x : AdvSIMD_SVE2_CADD_Intrinsic;
+def int_aarch64_sve_sqcadd_x : AdvSIMD_SVE2_CADD_Intrinsic;
+def int_aarch64_sve_cmla_x : AdvSIMD_SVE2_CMLA_Intrinsic;
+def int_aarch64_sve_cmla_lane_x : AdvSIMD_SVE_CMLA_LANE_Intrinsic;
+def int_aarch64_sve_sqrdcmlah_x : AdvSIMD_SVE2_CMLA_Intrinsic;
+def int_aarch64_sve_sqrdcmlah_lane_x : AdvSIMD_SVE_CMLA_LANE_Intrinsic;
+
+//
+// SVE2 - Widening complex integer arithmetic
+//
+
+def int_aarch64_sve_saddlbt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ssublbt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_ssubltb : SVE2_2VectorArg_Long_Intrinsic;
+
+//
+// SVE2 - Widening complex integer dot product
+//
+
+def int_aarch64_sve_cdot : AdvSIMD_SVE_DOT_Indexed_Intrinsic;
+def int_aarch64_sve_cdot_lane : AdvSIMD_SVE_CDOT_LANE_Intrinsic;
//
// SVE2 - Floating-point widening multiply-accumulate
@@ -1649,6 +2167,20 @@ def int_aarch64_sve_fmlslt_lane : SVE2_3VectorArgIndexed_Long_Intrinsic;
def int_aarch64_sve_flogb : AdvSIMD_SVE_LOGB_Intrinsic;
//
+// SVE2 - Vector histogram count
+//
+
+def int_aarch64_sve_histcnt : AdvSIMD_Pred2VectorArg_Intrinsic;
+def int_aarch64_sve_histseg : AdvSIMD_2VectorArg_Intrinsic;
+
+//
+// SVE2 - Character match
+//
+
+def int_aarch64_sve_match : AdvSIMD_SVE_Compare_Intrinsic;
+def int_aarch64_sve_nmatch : AdvSIMD_SVE_Compare_Intrinsic;
+
+//
// SVE2 - Unary narrowing operations
//
@@ -1701,4 +2233,163 @@ def int_aarch64_sve_sqshrunt : SVE2_2VectorArg_Imm_Narrowing_Intrinsic;
def int_aarch64_sve_sqrshrunb : SVE2_1VectorArg_Imm_Narrowing_Intrinsic;
def int_aarch64_sve_sqrshrunt : SVE2_2VectorArg_Imm_Narrowing_Intrinsic;
+
+// SVE2 MLA LANE.
+def int_aarch64_sve_smlalb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_smlalt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_umlalb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_umlalt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_smlslb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_smlslt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_umlslb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_umlslt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_smullb_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+def int_aarch64_sve_smullt_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+def int_aarch64_sve_umullb_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+def int_aarch64_sve_umullt_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+def int_aarch64_sve_sqdmlalb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_sqdmlalt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_sqdmlslb_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_sqdmlslt_lane : SVE2_3VectorArg_Indexed_Intrinsic;
+def int_aarch64_sve_sqdmullb_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+def int_aarch64_sve_sqdmullt_lane : SVE2_2VectorArgIndexed_Long_Intrinsic;
+
+// SVE2 MLA Unpredicated.
+def int_aarch64_sve_smlalb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_smlalt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umlalb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umlalt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_smlslb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_smlslt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umlslb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umlslt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_smullb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_smullt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umullb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_umullt : SVE2_2VectorArg_Long_Intrinsic;
+
+def int_aarch64_sve_sqdmlalb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmlalt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmlslb : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmlslt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmullb : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmullt : SVE2_2VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmlalbt : SVE2_3VectorArg_Long_Intrinsic;
+def int_aarch64_sve_sqdmlslbt : SVE2_3VectorArg_Long_Intrinsic;
+
+// SVE2 ADDSUB Long Unpredicated.
+def int_aarch64_sve_adclb : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_adclt : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_sbclb : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_sbclt : AdvSIMD_3VectorArg_Intrinsic;
+
+//
+// SVE2 - Polynomial arithmetic
+//
+def int_aarch64_sve_eorbt : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_eortb : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_pmullb_pair : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_pmullt_pair : AdvSIMD_2VectorArg_Intrinsic;
+
+//
+// SVE2 bitwise ternary operations.
+//
+def int_aarch64_sve_eor3 : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_bcax : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_bsl : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_bsl1n : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_bsl2n : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_nbsl : AdvSIMD_3VectorArg_Intrinsic;
+def int_aarch64_sve_xar : AdvSIMD_2VectorArgIndexed_Intrinsic;
+
+//
+// SVE2 - Optional AES, SHA-3 and SM4
+//
+
+def int_aarch64_sve_aesd : GCCBuiltin<"__builtin_sve_svaesd_u8">,
+ Intrinsic<[llvm_nxv16i8_ty],
+ [llvm_nxv16i8_ty, llvm_nxv16i8_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_aesimc : GCCBuiltin<"__builtin_sve_svaesimc_u8">,
+ Intrinsic<[llvm_nxv16i8_ty],
+ [llvm_nxv16i8_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_aese : GCCBuiltin<"__builtin_sve_svaese_u8">,
+ Intrinsic<[llvm_nxv16i8_ty],
+ [llvm_nxv16i8_ty, llvm_nxv16i8_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_aesmc : GCCBuiltin<"__builtin_sve_svaesmc_u8">,
+ Intrinsic<[llvm_nxv16i8_ty],
+ [llvm_nxv16i8_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_rax1 : GCCBuiltin<"__builtin_sve_svrax1_u64">,
+ Intrinsic<[llvm_nxv2i64_ty],
+ [llvm_nxv2i64_ty, llvm_nxv2i64_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_sm4e : GCCBuiltin<"__builtin_sve_svsm4e_u32">,
+ Intrinsic<[llvm_nxv4i32_ty],
+ [llvm_nxv4i32_ty, llvm_nxv4i32_ty],
+ [IntrNoMem]>;
+def int_aarch64_sve_sm4ekey : GCCBuiltin<"__builtin_sve_svsm4ekey_u32">,
+ Intrinsic<[llvm_nxv4i32_ty],
+ [llvm_nxv4i32_ty, llvm_nxv4i32_ty],
+ [IntrNoMem]>;
+//
+// SVE2 - Extended table lookup/permute
+//
+
+def int_aarch64_sve_tbl2 : AdvSIMD_SVE2_TBX_Intrinsic;
+def int_aarch64_sve_tbx : AdvSIMD_SVE2_TBX_Intrinsic;
+
+//
+// SVE2 - Optional bit permutation
+//
+
+def int_aarch64_sve_bdep_x : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_bext_x : AdvSIMD_2VectorArg_Intrinsic;
+def int_aarch64_sve_bgrp_x : AdvSIMD_2VectorArg_Intrinsic;
+
+
+//
+// SVE ACLE: 7.3. INT8 matrix multiply extensions
+//
+def int_aarch64_sve_ummla : SVE_MatMul_Intrinsic;
+def int_aarch64_sve_smmla : SVE_MatMul_Intrinsic;
+def int_aarch64_sve_usmmla : SVE_MatMul_Intrinsic;
+
+def int_aarch64_sve_usdot : AdvSIMD_SVE_DOT_Intrinsic;
+def int_aarch64_sve_usdot_lane : AdvSIMD_SVE_DOT_Indexed_Intrinsic;
+def int_aarch64_sve_sudot_lane : AdvSIMD_SVE_DOT_Indexed_Intrinsic;
+
+//
+// SVE ACLE: 7.4/5. FP64/FP32 matrix multiply extensions
+//
+def int_aarch64_sve_fmmla : AdvSIMD_3VectorArg_Intrinsic;
+
+//
+// SVE ACLE: 7.2. BFloat16 extensions
+//
+
+def int_aarch64_sve_bfdot : SVE_4Vec_BF16;
+def int_aarch64_sve_bfmlalb : SVE_4Vec_BF16;
+def int_aarch64_sve_bfmlalt : SVE_4Vec_BF16;
+
+def int_aarch64_sve_bfmmla : SVE_4Vec_BF16;
+
+def int_aarch64_sve_bfdot_lane : SVE_4Vec_BF16_Indexed;
+def int_aarch64_sve_bfmlalb_lane : SVE_4Vec_BF16_Indexed;
+def int_aarch64_sve_bfmlalt_lane : SVE_4Vec_BF16_Indexed;
}
+
+//
+// SVE2 - Contiguous conflict detection
+//
+
+def int_aarch64_sve_whilerw_b : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilerw_h : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilerw_s : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilerw_d : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilewr_b : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilewr_h : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilewr_s : SVE2_CONFLICT_DETECT_Intrinsic;
+def int_aarch64_sve_whilewr_d : SVE2_CONFLICT_DETECT_Intrinsic;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAMDGPU.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
index 07ca3a9229d6..01380afae006 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsAMDGPU.td
@@ -11,10 +11,10 @@
//===----------------------------------------------------------------------===//
class AMDGPUReadPreloadRegisterIntrinsic
- : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
class AMDGPUReadPreloadRegisterIntrinsicNamed<string name>
- : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>, GCCBuiltin<name>;
+ : Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>, GCCBuiltin<name>;
// Used to tag image and resource intrinsics with information used to generate
// mem operands.
@@ -48,35 +48,35 @@ defm int_r600_read_local_size : AMDGPUReadPreloadRegisterIntrinsic_xyz;
defm int_r600_read_tidig : AMDGPUReadPreloadRegisterIntrinsic_xyz;
def int_r600_group_barrier : GCCBuiltin<"__builtin_r600_group_barrier">,
- Intrinsic<[], [], [IntrConvergent]>;
+ Intrinsic<[], [], [IntrConvergent, IntrWillReturn]>;
// AS 7 is PARAM_I_ADDRESS, used for kernel arguments
def int_r600_implicitarg_ptr :
GCCBuiltin<"__builtin_r600_implicitarg_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 7>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_r600_rat_store_typed :
// 1st parameter: Data
// 2nd parameter: Index
// 3rd parameter: Constant RAT ID
- Intrinsic<[], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], []>,
+ Intrinsic<[], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty], [IntrWillReturn]>,
GCCBuiltin<"__builtin_r600_rat_store_typed">;
def int_r600_recipsqrt_ieee : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_r600_recipsqrt_clamped : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_r600_cube : Intrinsic<
- [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable]
+ [llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_r600_store_stream_output : Intrinsic<
- [], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []
+ [], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrWillReturn]
>;
class TextureIntrinsicFloatInput : Intrinsic<[llvm_v4f32_ty], [
@@ -90,7 +90,7 @@ class TextureIntrinsicFloatInput : Intrinsic<[llvm_v4f32_ty], [
llvm_i32_ty, // coord_type_y
llvm_i32_ty, // coord_type_z
llvm_i32_ty], // coord_type_w
- [IntrNoMem]
+ [IntrNoMem, IntrWillReturn]
>;
class TextureIntrinsicInt32Input : Intrinsic<[llvm_v4i32_ty], [
@@ -104,11 +104,11 @@ class TextureIntrinsicInt32Input : Intrinsic<[llvm_v4i32_ty], [
llvm_i32_ty, // coord_type_y
llvm_i32_ty, // coord_type_z
llvm_i32_ty], // coord_type_w
- [IntrNoMem]
+ [IntrNoMem, IntrWillReturn]
>;
def int_r600_store_swizzle :
- Intrinsic<[], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], []
+ Intrinsic<[], [llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty], [IntrWillReturn]
>;
def int_r600_tex : TextureIntrinsicFloatInput;
@@ -123,10 +123,10 @@ def int_r600_ddx : TextureIntrinsicFloatInput;
def int_r600_ddy : TextureIntrinsicFloatInput;
def int_r600_dot4 : Intrinsic<[llvm_float_ty],
- [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable]
+ [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
-def int_r600_kill : Intrinsic<[], [llvm_float_ty], []>;
+def int_r600_kill : Intrinsic<[], [llvm_float_ty], [IntrWillReturn]>;
} // End TargetPrefix = "r600"
@@ -141,44 +141,43 @@ defm int_amdgcn_workgroup_id : AMDGPUReadPreloadRegisterIntrinsic_xyz_named
<"__builtin_amdgcn_workgroup_id">;
def int_amdgcn_dispatch_ptr :
- GCCBuiltin<"__builtin_amdgcn_dispatch_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 4>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [Align<RetIndex, 4>, IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_queue_ptr :
GCCBuiltin<"__builtin_amdgcn_queue_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 4>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [Align<RetIndex, 4>, IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_kernarg_segment_ptr :
GCCBuiltin<"__builtin_amdgcn_kernarg_segment_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 4>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [Align<RetIndex, 4>, IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_implicitarg_ptr :
GCCBuiltin<"__builtin_amdgcn_implicitarg_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 4>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [Align<RetIndex, 4>, IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_groupstaticsize :
GCCBuiltin<"__builtin_amdgcn_groupstaticsize">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_dispatch_id :
GCCBuiltin<"__builtin_amdgcn_dispatch_id">,
- Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_implicit_buffer_ptr :
GCCBuiltin<"__builtin_amdgcn_implicit_buffer_ptr">,
Intrinsic<[LLVMQualPointerType<llvm_i8_ty, 4>], [],
- [IntrNoMem, IntrSpeculatable]>;
+ [Align<RetIndex, 4>, IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
// Set EXEC to the 64-bit value given.
// This is always moved to the beginning of the basic block.
// FIXME: Should be mangled for wave size.
def int_amdgcn_init_exec : Intrinsic<[],
[llvm_i64_ty], // 64-bit literal constant
- [IntrConvergent, ImmArg<0>]>;
+ [IntrConvergent, ImmArg<ArgIndex<0>>]>;
// Set EXEC according to a thread count packed in an SGPR input:
// thread_count = (input >> bitoffset) & 0x7f;
@@ -186,11 +185,11 @@ def int_amdgcn_init_exec : Intrinsic<[],
def int_amdgcn_init_exec_from_input : Intrinsic<[],
[llvm_i32_ty, // 32-bit SGPR input
llvm_i32_ty], // bit offset of the thread count
- [IntrConvergent, ImmArg<1>]>;
+ [IntrConvergent, ImmArg<ArgIndex<1>>]>;
def int_amdgcn_wavefrontsize :
GCCBuiltin<"__builtin_amdgcn_wavefrontsize">,
- Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_i32_ty], [], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
//===----------------------------------------------------------------------===//
@@ -201,180 +200,186 @@ def int_amdgcn_wavefrontsize :
// the second one is copied to m0
def int_amdgcn_s_sendmsg : GCCBuiltin<"__builtin_amdgcn_s_sendmsg">,
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
- [ImmArg<0>, IntrNoMem, IntrHasSideEffects]>;
+ [ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects]>;
def int_amdgcn_s_sendmsghalt : GCCBuiltin<"__builtin_amdgcn_s_sendmsghalt">,
Intrinsic <[], [llvm_i32_ty, llvm_i32_ty],
- [ImmArg<0>, IntrNoMem, IntrHasSideEffects]>;
+ [ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects]>;
def int_amdgcn_s_barrier : GCCBuiltin<"__builtin_amdgcn_s_barrier">,
- Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrConvergent]>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrConvergent, IntrWillReturn]>;
def int_amdgcn_wave_barrier : GCCBuiltin<"__builtin_amdgcn_wave_barrier">,
- Intrinsic<[], [], [IntrConvergent]>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrConvergent, IntrWillReturn]>;
def int_amdgcn_s_waitcnt : GCCBuiltin<"__builtin_amdgcn_s_waitcnt">,
- Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]>;
+ Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>, IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_div_scale : Intrinsic<
// 1st parameter: Numerator
// 2nd parameter: Denominator
- // 3rd parameter: Constant to select between first and
- // second. (0 = first, 1 = second).
+ // 3rd parameter: Select quotient. Must equal Numerator or Denominator.
+ // (0 = Denominator, 1 = Numerator).
[llvm_anyfloat_ty, llvm_i1_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<2>]
+ [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>, IntrWillReturn]
>;
def int_amdgcn_div_fmas : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>, llvm_i1_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_div_fixup : Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
+// Look Up 2.0 / pi src0 with segment select src1[4:0]
def int_amdgcn_trig_preop : Intrinsic<
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_sin : Intrinsic<
[llvm_anyfloat_ty], [LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cos : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_log_clamp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_fmul_legacy : GCCBuiltin<"__builtin_amdgcn_fmul_legacy">,
Intrinsic<[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_rcp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_rcp_legacy : GCCBuiltin<"__builtin_amdgcn_rcp_legacy">,
Intrinsic<[llvm_float_ty], [llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
+>;
+
+def int_amdgcn_sqrt : Intrinsic<
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_rsq : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_rsq_legacy : GCCBuiltin<"__builtin_amdgcn_rsq_legacy">,
Intrinsic<
- [llvm_float_ty], [llvm_float_ty], [IntrNoMem, IntrSpeculatable]
+ [llvm_float_ty], [llvm_float_ty], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
+// out = 1.0 / sqrt(a) result clamped to +/- max_float.
def int_amdgcn_rsq_clamp : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]>;
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]>;
def int_amdgcn_ldexp : Intrinsic<
[llvm_anyfloat_ty], [LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_frexp_mant : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_frexp_exp : Intrinsic<
- [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyint_ty], [llvm_anyfloat_ty], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// v_fract is buggy on SI/CI. It mishandles infinities, may return 1.0
// and always uses rtz, so is not suitable for implementing the OpenCL
// fract function. It should be ok on VI.
def int_amdgcn_fract : Intrinsic<
- [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pkrtz : GCCBuiltin<"__builtin_amdgcn_cvt_pkrtz">,
Intrinsic<[llvm_v2f16_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pknorm_i16 :
GCCBuiltin<"__builtin_amdgcn_cvt_pknorm_i16">,
Intrinsic<[llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pknorm_u16 :
GCCBuiltin<"__builtin_amdgcn_cvt_pknorm_u16">,
Intrinsic<[llvm_v2i16_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pk_i16 :
GCCBuiltin<"__builtin_amdgcn_cvt_pk_i16">,
Intrinsic<
[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pk_u16 : GCCBuiltin<"__builtin_amdgcn_cvt_pk_u16">,
Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_class : Intrinsic<
[llvm_i1_ty], [llvm_anyfloat_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_fmed3 : GCCBuiltin<"__builtin_amdgcn_fmed3">,
Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cubeid : GCCBuiltin<"__builtin_amdgcn_cubeid">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cubema : GCCBuiltin<"__builtin_amdgcn_cubema">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cubesc : GCCBuiltin<"__builtin_amdgcn_cubesc">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cubetc : GCCBuiltin<"__builtin_amdgcn_cubetc">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// v_ffbh_i32, as opposed to v_ffbh_u32. For v_ffbh_u32, llvm.ctlz
// should be used.
def int_amdgcn_sffbh :
Intrinsic<[llvm_anyint_ty], [LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// v_mad_f32|f16/v_mac_f32|f16, selected regardless of denorm support.
def int_amdgcn_fmad_ftz :
Intrinsic<[llvm_anyfloat_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// Fields should mirror atomicrmw
@@ -384,7 +389,8 @@ class AMDGPUAtomicIncIntrin : Intrinsic<[llvm_anyint_ty],
llvm_i32_ty, // ordering
llvm_i32_ty, // scope
llvm_i1_ty], // isVolatile
- [IntrArgMemOnly, NoCapture<0>, ImmArg<2>, ImmArg<3>, ImmArg<4>], "",
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>], "",
[SDNPMemOperand]
>;
@@ -399,7 +405,8 @@ class AMDGPULDSF32Intrin<string clang_builtin> :
llvm_i32_ty, // ordering
llvm_i32_ty, // scope
llvm_i1_ty], // isVolatile
- [IntrArgMemOnly, NoCapture<0>, ImmArg<2>, ImmArg<3>, ImmArg<4>]
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]
>;
// FIXME: The m0 argument should be moved after the normal arguments
@@ -416,9 +423,9 @@ class AMDGPUDSOrderedIntrinsic : Intrinsic<
// gfx10: bits 24-27 indicate the number of active threads/dwords
llvm_i1_ty, // wave release, usually set to 1
llvm_i1_ty], // wave done, set to 1 for the last ordered instruction
- [NoCapture<0>,
- ImmArg<2>, ImmArg<3>, ImmArg<4>,
- ImmArg<5>, ImmArg<6>, ImmArg<7>
+ [IntrWillReturn, NoCapture<ArgIndex<0>>,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>,
+ ImmArg<ArgIndex<5>>, ImmArg<ArgIndex<6>>, ImmArg<ArgIndex<7>>
]
>;
@@ -426,7 +433,8 @@ class AMDGPUDSAppendConsumedIntrinsic : Intrinsic<
[llvm_i32_ty],
[llvm_anyptr_ty, // LDS or GDS ptr
llvm_i1_ty], // isVolatile
- [IntrConvergent, IntrArgMemOnly, NoCapture<0>, ImmArg<1>],
+ [IntrConvergent, IntrWillReturn, IntrArgMemOnly,
+ NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>],
"",
[SDNPMemOperand]
>;
@@ -591,7 +599,7 @@ class AMDGPUDimProfile<string opmod,
AMDGPUDimProps Dim = dim;
string OpMod = opmod; // the corresponding instruction is named IMAGE_OpMod
- // These are entended to be overwritten by subclasses
+ // These are intended to be overwritten by subclasses
bit IsSample = 0;
bit IsAtomic = 0;
list<LLVMType> RetTypes = [];
@@ -697,11 +705,15 @@ class AMDGPUImageDimIntrinsic<AMDGPUDimProfile P_,
llvm_i1_ty], []), // unorm(imm)
[llvm_i32_ty, // texfailctrl(imm; bit 0 = tfe, bit 1 = lwe)
llvm_i32_ty]), // cachepolicy(imm; bit 0 = glc, bit 1 = slc, bit 2 = dlc)
+
!listconcat(props,
- !if(P_.IsAtomic, [], [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.DmaskArgIndex>]),
- !if(P_.IsSample, [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.UnormArgIndex>], []),
- [ImmArg<AMDGPUImageDimIntrinsicEval<P_>.TexFailCtrlArgIndex>,
- ImmArg<AMDGPUImageDimIntrinsicEval<P_>.CachePolicyArgIndex>]),
+ !if(P_.IsAtomic, [], [ImmArg<ArgIndex<AMDGPUImageDimIntrinsicEval<P_>.DmaskArgIndex>>]),
+ !if(P_.IsSample, [ImmArg<ArgIndex<AMDGPUImageDimIntrinsicEval<P_>.UnormArgIndex>>], []),
+ [IntrWillReturn],
+ [ImmArg<ArgIndex<AMDGPUImageDimIntrinsicEval<P_>.TexFailCtrlArgIndex>>,
+ ImmArg<ArgIndex<AMDGPUImageDimIntrinsicEval<P_>.CachePolicyArgIndex>>]),
+
+
"", sdnodeprops>,
AMDGPURsrcIntrinsic<!add(!size(P_.DataArgs), !size(P_.AddrTypes),
!if(P_.IsAtomic, 0, 1)), 1> {
@@ -755,15 +767,20 @@ defset list<AMDGPUImageDimIntrinsic> AMDGPUImageDimIntrinsics = {
AMDGPUImageDMaskIntrinsic;
defm int_amdgcn_image_load_mip
: AMDGPUImageDimIntrinsicsNoMsaa<"LOAD_MIP", [llvm_any_ty], [],
- [IntrReadMem], [SDNPMemOperand], 1>,
+ [IntrReadMem, IntrWillReturn], [SDNPMemOperand], 1>,
AMDGPUImageDMaskIntrinsic;
defm int_amdgcn_image_store : AMDGPUImageDimIntrinsicsAll<
"STORE", [], [AMDGPUArg<llvm_anyfloat_ty, "vdata">],
- [IntrWriteMem], [SDNPMemOperand]>;
+ [IntrWriteMem, IntrWillReturn], [SDNPMemOperand]>;
defm int_amdgcn_image_store_mip : AMDGPUImageDimIntrinsicsNoMsaa<
"STORE_MIP", [], [AMDGPUArg<llvm_anyfloat_ty, "vdata">],
- [IntrWriteMem], [SDNPMemOperand], 1>;
+ [IntrWriteMem, IntrWillReturn], [SDNPMemOperand], 1>;
+
+ defm int_amdgcn_image_msaa_load
+ : AMDGPUImageDimIntrinsicsAll<"MSAA_LOAD", [llvm_any_ty], [], [IntrReadMem],
+ [SDNPMemOperand]>,
+ AMDGPUImageDMaskIntrinsic;
//////////////////////////////////////////////////////////////////////////
// sample and getlod intrinsics
@@ -861,7 +878,8 @@ class AMDGPUBufferLoad<LLVMType data_ty = llvm_any_ty> : Intrinsic <
llvm_i32_ty, // offset(SGPR/VGPR/imm)
llvm_i1_ty, // glc(imm)
llvm_i1_ty], // slc(imm)
- [IntrReadMem, ImmArg<3>, ImmArg<4>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
def int_amdgcn_buffer_load_format : AMDGPUBufferLoad<llvm_anyfloat_ty>;
def int_amdgcn_buffer_load : AMDGPUBufferLoad;
@@ -871,7 +889,7 @@ def int_amdgcn_s_buffer_load : Intrinsic <
[llvm_v4i32_ty, // rsrc(SGPR)
llvm_i32_ty, // byte offset(SGPR/imm)
llvm_i32_ty], // cachepolicy(imm; bit 0 = glc, bit 2 = dlc)
- [IntrNoMem, ImmArg<2>]>,
+ [IntrNoMem, IntrWillReturn, ImmArg<ArgIndex<2>>]>,
AMDGPURsrcIntrinsic<0>;
class AMDGPUBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
@@ -882,7 +900,8 @@ class AMDGPUBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
llvm_i32_ty, // offset(SGPR/VGPR/imm)
llvm_i1_ty, // glc(imm)
llvm_i1_ty], // slc(imm)
- [IntrWriteMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
def int_amdgcn_buffer_store_format : AMDGPUBufferStore<llvm_anyfloat_ty>;
def int_amdgcn_buffer_store : AMDGPUBufferStore;
@@ -903,7 +922,7 @@ class AMDGPURawBufferLoad<LLVMType data_ty = llvm_any_ty> : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrReadMem, ImmArg<3>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn, ImmArg<ArgIndex<3>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
def int_amdgcn_raw_buffer_load_format : AMDGPURawBufferLoad<llvm_anyfloat_ty>;
def int_amdgcn_raw_buffer_load : AMDGPURawBufferLoad;
@@ -918,9 +937,9 @@ class AMDGPUStructBufferLoad<LLVMType data_ty = llvm_any_ty> : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrReadMem, ImmArg<4>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn, ImmArg<ArgIndex<4>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
-def int_amdgcn_struct_buffer_load_format : AMDGPUStructBufferLoad<llvm_anyfloat_ty>;
+def int_amdgcn_struct_buffer_load_format : AMDGPUStructBufferLoad;
def int_amdgcn_struct_buffer_load : AMDGPUStructBufferLoad;
class AMDGPURawBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
@@ -933,7 +952,7 @@ class AMDGPURawBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrWriteMem, ImmArg<4>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn, ImmArg<ArgIndex<4>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
def int_amdgcn_raw_buffer_store_format : AMDGPURawBufferStore<llvm_anyfloat_ty>;
def int_amdgcn_raw_buffer_store : AMDGPURawBufferStore;
@@ -949,9 +968,9 @@ class AMDGPUStructBufferStore<LLVMType data_ty = llvm_any_ty> : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrWriteMem, ImmArg<5>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn, ImmArg<ArgIndex<5>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
-def int_amdgcn_struct_buffer_store_format : AMDGPUStructBufferStore<llvm_anyfloat_ty>;
+def int_amdgcn_struct_buffer_store_format : AMDGPUStructBufferStore;
def int_amdgcn_struct_buffer_store : AMDGPUStructBufferStore;
class AMDGPURawBufferAtomic<LLVMType data_ty = llvm_any_ty> : Intrinsic <
@@ -961,7 +980,7 @@ class AMDGPURawBufferAtomic<LLVMType data_ty = llvm_any_ty> : Intrinsic <
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling)
llvm_i32_ty], // cachepolicy(imm; bit 1 = slc)
- [ImmArg<4>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<4>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1, 0>;
def int_amdgcn_raw_buffer_atomic_swap : AMDGPURawBufferAtomic;
def int_amdgcn_raw_buffer_atomic_add : AMDGPURawBufferAtomic;
@@ -983,7 +1002,7 @@ def int_amdgcn_raw_buffer_atomic_cmpswap : Intrinsic<
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling)
llvm_i32_ty], // cachepolicy(imm; bit 1 = slc)
- [ImmArg<5>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<5>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<2, 0>;
class AMDGPUStructBufferAtomic<LLVMType data_ty = llvm_any_ty> : Intrinsic <
@@ -994,7 +1013,7 @@ class AMDGPUStructBufferAtomic<LLVMType data_ty = llvm_any_ty> : Intrinsic <
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling)
llvm_i32_ty], // cachepolicy(imm; bit 1 = slc)
- [ImmArg<5>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<5>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1, 0>;
def int_amdgcn_struct_buffer_atomic_swap : AMDGPUStructBufferAtomic;
def int_amdgcn_struct_buffer_atomic_add : AMDGPUStructBufferAtomic;
@@ -1017,7 +1036,7 @@ def int_amdgcn_struct_buffer_atomic_cmpswap : Intrinsic<
llvm_i32_ty, // offset(VGPR/imm, included in bounds checking and swizzling)
llvm_i32_ty, // soffset(SGPR/imm, excluded from bounds checking and swizzling)
llvm_i32_ty], // cachepolicy(imm; bit 1 = slc)
- [ImmArg<6>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<6>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<2, 0>;
// Obsolescent tbuffer intrinsics.
@@ -1032,8 +1051,9 @@ def int_amdgcn_tbuffer_load : Intrinsic <
llvm_i32_ty, // nfmt(imm)
llvm_i1_ty, // glc(imm)
llvm_i1_ty], // slc(imm)
- [IntrReadMem, ImmArg<4>, ImmArg<5>, ImmArg<6>,
- ImmArg<7>, ImmArg<8>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>, ImmArg<ArgIndex<6>>,
+ ImmArg<ArgIndex<7>>, ImmArg<ArgIndex<8>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
def int_amdgcn_tbuffer_store : Intrinsic <
@@ -1048,8 +1068,9 @@ def int_amdgcn_tbuffer_store : Intrinsic <
llvm_i32_ty, // nfmt(imm)
llvm_i1_ty, // glc(imm)
llvm_i1_ty], // slc(imm)
- [IntrWriteMem, ImmArg<5>, ImmArg<6>, ImmArg<7>,
- ImmArg<8>, ImmArg<9>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn, ImmArg<ArgIndex<5>>,
+ ImmArg<ArgIndex<6>>, ImmArg<ArgIndex<7>>,
+ ImmArg<ArgIndex<8>>, ImmArg<ArgIndex<9>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
// New tbuffer intrinsics, with:
@@ -1066,7 +1087,8 @@ def int_amdgcn_raw_tbuffer_load : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrReadMem, ImmArg<3>, ImmArg<4>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
def int_amdgcn_raw_tbuffer_store : Intrinsic <
@@ -1080,7 +1102,8 @@ def int_amdgcn_raw_tbuffer_store : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrWriteMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
def int_amdgcn_struct_tbuffer_load : Intrinsic <
@@ -1094,7 +1117,8 @@ def int_amdgcn_struct_tbuffer_load : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrReadMem, ImmArg<4>, ImmArg<5>], "", [SDNPMemOperand]>,
+ [IntrReadMem, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<0>;
def int_amdgcn_struct_tbuffer_store : Intrinsic <
@@ -1109,7 +1133,8 @@ def int_amdgcn_struct_tbuffer_store : Intrinsic <
// bit 1 = slc,
// bit 2 = dlc on gfx10+),
// swizzled buffer (bit 3 = swz))
- [IntrWriteMem, ImmArg<5>, ImmArg<6>], "", [SDNPMemOperand]>,
+ [IntrWriteMem, IntrWillReturn,
+ ImmArg<ArgIndex<5>>, ImmArg<ArgIndex<6>>], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1>;
class AMDGPUBufferAtomic : Intrinsic <
@@ -1119,7 +1144,7 @@ class AMDGPUBufferAtomic : Intrinsic <
llvm_i32_ty, // vindex(VGPR)
llvm_i32_ty, // offset(SGPR/VGPR/imm)
llvm_i1_ty], // slc(imm)
- [ImmArg<4>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<4>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1, 0>;
def int_amdgcn_buffer_atomic_swap : AMDGPUBufferAtomic;
def int_amdgcn_buffer_atomic_add : AMDGPUBufferAtomic;
@@ -1139,9 +1164,10 @@ def int_amdgcn_buffer_atomic_cmpswap : Intrinsic<
llvm_i32_ty, // vindex(VGPR)
llvm_i32_ty, // offset(SGPR/VGPR/imm)
llvm_i1_ty], // slc(imm)
- [ImmArg<5>], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<5>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<2, 0>;
+def int_amdgcn_buffer_atomic_csub : AMDGPUBufferAtomic;
} // defset AMDGPUBufferIntrinsics
// Uses that do not set the done bit should set IntrWriteMem on the
@@ -1156,7 +1182,9 @@ def int_amdgcn_exp : Intrinsic <[], [
llvm_i1_ty, // done
llvm_i1_ty // vm
],
- [ImmArg<0>, ImmArg<1>, ImmArg<6>, ImmArg<7>, IntrInaccessibleMemOnly]
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<6>>,
+ ImmArg<ArgIndex<7>>, IntrWriteMem, IntrInaccessibleMemOnly,
+ IntrWillReturn]
>;
// exp with compr bit set.
@@ -1167,44 +1195,60 @@ def int_amdgcn_exp_compr : Intrinsic <[], [
LLVMMatchType<0>, // src1
llvm_i1_ty, // done
llvm_i1_ty], // vm
- [ImmArg<0>, ImmArg<1>, ImmArg<4>, ImmArg<5>, IntrInaccessibleMemOnly]
+ [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>,
+ ImmArg<ArgIndex<5>>, IntrWriteMem, IntrInaccessibleMemOnly,
+ IntrWillReturn]
>;
def int_amdgcn_buffer_wbinvl1_sc :
GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1_sc">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_buffer_wbinvl1 :
GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_s_dcache_inv :
GCCBuiltin<"__builtin_amdgcn_s_dcache_inv">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_s_memtime :
GCCBuiltin<"__builtin_amdgcn_s_memtime">,
- Intrinsic<[llvm_i64_ty], []>;
+ Intrinsic<[llvm_i64_ty], [], [IntrWillReturn]>;
def int_amdgcn_s_sleep :
GCCBuiltin<"__builtin_amdgcn_s_sleep">,
- Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> {
+ Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>, IntrNoMem,
+ IntrHasSideEffects, IntrWillReturn]> {
}
def int_amdgcn_s_incperflevel :
GCCBuiltin<"__builtin_amdgcn_s_incperflevel">,
- Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> {
+ Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>, IntrNoMem,
+ IntrHasSideEffects, IntrWillReturn]> {
}
def int_amdgcn_s_decperflevel :
GCCBuiltin<"__builtin_amdgcn_s_decperflevel">,
- Intrinsic<[], [llvm_i32_ty], [ImmArg<0>]> {
+ Intrinsic<[], [llvm_i32_ty], [ImmArg<ArgIndex<0>>, IntrNoMem,
+ IntrHasSideEffects, IntrWillReturn]> {
}
def int_amdgcn_s_getreg :
GCCBuiltin<"__builtin_amdgcn_s_getreg">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
- [IntrInaccessibleMemOnly, IntrReadMem, IntrSpeculatable, ImmArg<0>]
+ [IntrInaccessibleMemOnly, IntrReadMem, IntrSpeculatable,
+ IntrWillReturn, ImmArg<ArgIndex<0>>]
+>;
+
+// Note this can be used to set FP environment properties that are
+// unsafe to change in non-strictfp functions. The register properties
+// available (and value required to access them) may differ per
+// subtarget. llvm.amdgcn.s.setreg(hwmode, value)
+def int_amdgcn_s_setreg :
+ GCCBuiltin<"__builtin_amdgcn_s_setreg">,
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrHasSideEffects, ImmArg<ArgIndex<0>>]
>;
// int_amdgcn_s_getpc is provided to allow a specific style of position
@@ -1215,7 +1259,8 @@ def int_amdgcn_s_getreg :
// especially as we explicitly use IntrNoMem to allow optimizations.
def int_amdgcn_s_getpc :
GCCBuiltin<"__builtin_amdgcn_s_getpc">,
- Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable]>;
+ Intrinsic<[llvm_i64_ty], [], [IntrNoMem, IntrSpeculatable,
+ IntrWillReturn]>;
// __builtin_amdgcn_interp_mov <param>, <attr_chan>, <attr>, <m0>
// param values: 0 = P10, 1 = P20, 2 = P0
@@ -1223,7 +1268,8 @@ def int_amdgcn_interp_mov :
GCCBuiltin<"__builtin_amdgcn_interp_mov">,
Intrinsic<[llvm_float_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
// __builtin_amdgcn_interp_p1 <i>, <attr_chan>, <attr>, <m0>
// This intrinsic reads from lds, but the memory values are constant,
@@ -1232,14 +1278,16 @@ def int_amdgcn_interp_p1 :
GCCBuiltin<"__builtin_amdgcn_interp_p1">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
// __builtin_amdgcn_interp_p2 <p1>, <j>, <attr_chan>, <attr>, <m0>
def int_amdgcn_interp_p2 :
GCCBuiltin<"__builtin_amdgcn_interp_p2">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
// See int_amdgcn_v_interp_p1 for why this is IntrNoMem.
// __builtin_amdgcn_interp_p1_f16 <i>, <attr_chan>, <attr>, <high>, <m0>
@@ -1247,117 +1295,130 @@ def int_amdgcn_interp_p1_f16 :
GCCBuiltin<"__builtin_amdgcn_interp_p1_f16">,
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<1>, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
// __builtin_amdgcn_interp_p2_f16 <p1>, <j>, <attr_chan>, <attr>, <high>, <m0>
def int_amdgcn_interp_p2_f16 :
GCCBuiltin<"__builtin_amdgcn_interp_p2_f16">,
Intrinsic<[llvm_half_ty],
[llvm_float_ty, llvm_float_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable, ImmArg<2>, ImmArg<3>, ImmArg<4>]>;
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
// Pixel shaders only: whether the current pixel is live (i.e. not a helper
// invocation for derivative computation).
def int_amdgcn_ps_live : Intrinsic <
[llvm_i1_ty],
[],
- [IntrNoMem]>;
+ [IntrNoMem, IntrWillReturn]>;
def int_amdgcn_mbcnt_lo :
GCCBuiltin<"__builtin_amdgcn_mbcnt_lo">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrWillReturn]>;
def int_amdgcn_mbcnt_hi :
GCCBuiltin<"__builtin_amdgcn_mbcnt_hi">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrWillReturn]>;
// llvm.amdgcn.ds.swizzle src offset
def int_amdgcn_ds_swizzle :
GCCBuiltin<"__builtin_amdgcn_ds_swizzle">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrConvergent, ImmArg<1>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<1>>]>;
def int_amdgcn_ubfe : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_sbfe : Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_lerp :
GCCBuiltin<"__builtin_amdgcn_lerp">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_sad_u8 :
GCCBuiltin<"__builtin_amdgcn_sad_u8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_msad_u8 :
GCCBuiltin<"__builtin_amdgcn_msad_u8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_sad_hi_u8 :
GCCBuiltin<"__builtin_amdgcn_sad_hi_u8">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_sad_u16 :
GCCBuiltin<"__builtin_amdgcn_sad_u16">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_qsad_pk_u16_u8 :
GCCBuiltin<"__builtin_amdgcn_qsad_pk_u16_u8">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_mqsad_pk_u16_u8 :
GCCBuiltin<"__builtin_amdgcn_mqsad_pk_u16_u8">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i64_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_mqsad_u32_u8 :
GCCBuiltin<"__builtin_amdgcn_mqsad_u32_u8">,
Intrinsic<[llvm_v4i32_ty], [llvm_i64_ty, llvm_i32_ty, llvm_v4i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_cvt_pk_u8_f32 :
GCCBuiltin<"__builtin_amdgcn_cvt_pk_u8_f32">,
Intrinsic<[llvm_i32_ty], [llvm_float_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_icmp :
Intrinsic<[llvm_anyint_ty], [llvm_anyint_ty, LLVMMatchType<1>, llvm_i32_ty],
- [IntrNoMem, IntrConvergent, ImmArg<2>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<2>>]>;
def int_amdgcn_fcmp :
Intrinsic<[llvm_anyint_ty], [llvm_anyfloat_ty, LLVMMatchType<1>, llvm_i32_ty],
- [IntrNoMem, IntrConvergent, ImmArg<2>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<2>>]>;
+
+def int_amdgcn_ballot :
+ Intrinsic<[llvm_anyint_ty], [llvm_i1_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
def int_amdgcn_readfirstlane :
GCCBuiltin<"__builtin_amdgcn_readfirstlane">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
// The lane argument must be uniform across the currently active threads of the
// current wave. Otherwise, the result is undefined.
def int_amdgcn_readlane :
GCCBuiltin<"__builtin_amdgcn_readlane">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
// The value to write and lane select arguments must be uniform across the
// currently active threads of the current wave. Otherwise, the result is
@@ -1369,28 +1430,28 @@ def int_amdgcn_writelane :
llvm_i32_ty, // uniform lane select
llvm_i32_ty // returned by all lanes other than the selected one
],
- [IntrNoMem, IntrConvergent]
+ [IntrNoMem, IntrConvergent, IntrWillReturn]
>;
-def int_amdgcn_alignbit :
- GCCBuiltin<"__builtin_amdgcn_alignbit">, Intrinsic<[llvm_i32_ty],
+// FIXME: Deprecated. This is equivalent to llvm.fshr
+def int_amdgcn_alignbit : Intrinsic<[llvm_i32_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_alignbyte : GCCBuiltin<"__builtin_amdgcn_alignbyte">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_mul_i24 : Intrinsic<[llvm_i32_ty],
[llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
def int_amdgcn_mul_u24 : Intrinsic<[llvm_i32_ty],
[llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// llvm.amdgcn.ds.gws.init(i32 bar_val, i32 resource_id)
@@ -1401,7 +1462,8 @@ def int_amdgcn_ds_gws_init :
GCCBuiltin<"__builtin_amdgcn_ds_gws_init">,
Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrWriteMem, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrWriteMem,
+ IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1412,7 +1474,7 @@ def int_amdgcn_ds_gws_barrier :
GCCBuiltin<"__builtin_amdgcn_ds_gws_barrier">,
Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1421,7 +1483,7 @@ def int_amdgcn_ds_gws_sema_v :
GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_v">,
Intrinsic<[],
[llvm_i32_ty],
- [IntrConvergent, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1430,7 +1492,7 @@ def int_amdgcn_ds_gws_sema_br :
GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_br">,
Intrinsic<[],
[llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1439,7 +1501,7 @@ def int_amdgcn_ds_gws_sema_p :
GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_p">,
Intrinsic<[],
[llvm_i32_ty],
- [IntrConvergent, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1448,7 +1510,7 @@ def int_amdgcn_ds_gws_sema_release_all :
GCCBuiltin<"__builtin_amdgcn_ds_gws_sema_release_all">,
Intrinsic<[],
[llvm_i32_ty],
- [IntrConvergent, IntrInaccessibleMemOnly], "",
+ [IntrConvergent, IntrInaccessibleMemOnly, IntrWillReturn], "",
[SDNPMemOperand]
>;
@@ -1456,23 +1518,24 @@ def int_amdgcn_ds_gws_sema_release_all :
// Copies the source value to the destination value, with the guarantee that
// the source value is computed as if the entire program were executed in WQM.
def int_amdgcn_wqm : Intrinsic<[llvm_any_ty],
- [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// Copies the source value to the destination value, such that the source
// is computed as if the entire program were executed in WQM if any other
// program code executes in WQM.
def int_amdgcn_softwqm : Intrinsic<[llvm_any_ty],
- [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable]
+ [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
// Return true if at least one thread within the pixel quad passes true into
// the function.
def int_amdgcn_wqm_vote : Intrinsic<[llvm_i1_ty],
- [llvm_i1_ty], [IntrNoMem, IntrConvergent]
+ [llvm_i1_ty], [IntrNoMem, IntrConvergent, IntrWillReturn]
>;
// If false, set EXEC=0 for the current thread until the end of program.
+// FIXME: Should this be IntrNoMem, IntrHasSideEffects, or IntrWillReturn?
def int_amdgcn_kill : Intrinsic<[], [llvm_i1_ty], []>;
// Copies the active channels of the source value to the destination value,
@@ -1481,7 +1544,8 @@ def int_amdgcn_kill : Intrinsic<[], [llvm_i1_ty], []>;
// enabled, with a few exceptions: - Phi nodes with require WWM return an
// undefined value.
def int_amdgcn_wwm : Intrinsic<[llvm_any_ty],
- [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable, IntrConvergent]
+ [LLVMMatchType<0>], [IntrNoMem, IntrSpeculatable,
+ IntrConvergent, IntrWillReturn]
>;
// Given a value, copies it while setting all the inactive lanes to a given
@@ -1492,18 +1556,18 @@ def int_amdgcn_set_inactive :
Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, // value to be copied
LLVMMatchType<0>], // value for the inactive lanes to take
- [IntrNoMem, IntrConvergent]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
// Return if the given flat pointer points to a local memory address.
def int_amdgcn_is_shared : GCCBuiltin<"__builtin_amdgcn_is_shared">,
Intrinsic<[llvm_i1_ty], [llvm_ptr_ty],
- [IntrNoMem, IntrSpeculatable, NoCapture<0>]
+ [IntrNoMem, IntrSpeculatable, NoCapture<ArgIndex<0>>, IntrWillReturn]
>;
// Return if the given flat pointer points to a prvate memory address.
def int_amdgcn_is_private : GCCBuiltin<"__builtin_amdgcn_is_private">,
Intrinsic<[llvm_i1_ty], [llvm_ptr_ty],
- [IntrNoMem, IntrSpeculatable, NoCapture<0>]
+ [IntrNoMem, IntrSpeculatable, NoCapture<ArgIndex<0>>, IntrWillReturn]
>;
//===----------------------------------------------------------------------===//
@@ -1512,11 +1576,11 @@ def int_amdgcn_is_private : GCCBuiltin<"__builtin_amdgcn_is_private">,
def int_amdgcn_s_dcache_inv_vol :
GCCBuiltin<"__builtin_amdgcn_s_dcache_inv_vol">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_buffer_wbinvl1_vol :
GCCBuiltin<"__builtin_amdgcn_buffer_wbinvl1_vol">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
//===----------------------------------------------------------------------===//
// VI Intrinsics
@@ -1526,8 +1590,10 @@ def int_amdgcn_buffer_wbinvl1_vol :
def int_amdgcn_mov_dpp :
Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i1_ty], [IntrNoMem, IntrConvergent, ImmArg<1>,
- ImmArg<2>, ImmArg<3>, ImmArg<4>]>;
+ llvm_i1_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
// llvm.amdgcn.update.dpp.i32 <old> <src> <dpp_ctrl> <row_mask> <bank_mask> <bound_ctrl>
// Should be equivalent to:
@@ -1537,30 +1603,33 @@ def int_amdgcn_update_dpp :
Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_i1_ty],
- [IntrNoMem, IntrConvergent,
- ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_amdgcn_s_dcache_wb :
GCCBuiltin<"__builtin_amdgcn_s_dcache_wb">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_s_dcache_wb_vol :
GCCBuiltin<"__builtin_amdgcn_s_dcache_wb_vol">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects, IntrWillReturn]>;
def int_amdgcn_s_memrealtime :
GCCBuiltin<"__builtin_amdgcn_s_memrealtime">,
- Intrinsic<[llvm_i64_ty]>;
+ Intrinsic<[llvm_i64_ty], [], [IntrWillReturn]>;
// llvm.amdgcn.ds.permute <index> <src>
def int_amdgcn_ds_permute :
GCCBuiltin<"__builtin_amdgcn_ds_permute">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
// llvm.amdgcn.ds.bpermute <index> <src>
def int_amdgcn_ds_bpermute :
GCCBuiltin<"__builtin_amdgcn_ds_bpermute">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrNoMem, IntrConvergent]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]>;
//===----------------------------------------------------------------------===//
// GFX10 Intrinsics
@@ -1570,13 +1639,15 @@ def int_amdgcn_ds_bpermute :
def int_amdgcn_permlane16 : GCCBuiltin<"__builtin_amdgcn_permlane16">,
Intrinsic<[llvm_i32_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i1_ty],
- [IntrNoMem, IntrConvergent, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
// llvm.amdgcn.permlanex16 <old> <src0> <src1> <src2> <fi> <bound_control>
def int_amdgcn_permlanex16 : GCCBuiltin<"__builtin_amdgcn_permlanex16">,
Intrinsic<[llvm_i32_ty],
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i1_ty, llvm_i1_ty],
- [IntrNoMem, IntrConvergent, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
// llvm.amdgcn.mov.dpp8.i32 <src> <sel>
// <sel> is a 32-bit constant whose high 8 bits must be zero which selects
@@ -1584,11 +1655,21 @@ def int_amdgcn_permlanex16 : GCCBuiltin<"__builtin_amdgcn_permlanex16">,
def int_amdgcn_mov_dpp8 :
Intrinsic<[llvm_anyint_ty],
[LLVMMatchType<0>, llvm_i32_ty],
- [IntrNoMem, IntrConvergent, ImmArg<1>]>;
+ [IntrNoMem, IntrConvergent, IntrWillReturn,
+ ImmArg<ArgIndex<1>>]>;
def int_amdgcn_s_get_waveid_in_workgroup :
GCCBuiltin<"__builtin_amdgcn_s_get_waveid_in_workgroup">,
- Intrinsic<[llvm_i32_ty], [], [IntrReadMem, IntrInaccessibleMemOnly]>;
+ Intrinsic<[llvm_i32_ty], [],
+ [IntrReadMem, IntrInaccessibleMemOnly, IntrWillReturn]>;
+
+class AMDGPUGlobalAtomicRtn<LLVMType vt> : Intrinsic <
+ [vt],
+ [llvm_anyptr_ty, // vaddr
+ vt], // vdata(VGPR)
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>], "", [SDNPMemOperand]>;
+
+def int_amdgcn_global_atomic_csub : AMDGPUGlobalAtomicRtn<llvm_i32_ty>;
//===----------------------------------------------------------------------===//
// Deep learning intrinsics.
@@ -1606,7 +1687,7 @@ def int_amdgcn_fdot2 :
llvm_float_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// i32 %r = llvm.amdgcn.sdot2(v2i16 %a, v2i16 %b, i32 %c, i1 %clamp)
@@ -1621,7 +1702,7 @@ def int_amdgcn_sdot2 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// u32 %r = llvm.amdgcn.udot2(v2u16 %a, v2u16 %b, u32 %c, i1 %clamp)
@@ -1636,7 +1717,7 @@ def int_amdgcn_udot2 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// i32 %r = llvm.amdgcn.sdot4(v4i8 (as i32) %a, v4i8 (as i32) %b, i32 %c, i1 %clamp)
@@ -1651,7 +1732,7 @@ def int_amdgcn_sdot4 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// u32 %r = llvm.amdgcn.udot4(v4u8 (as u32) %a, v4u8 (as u32) %b, u32 %c, i1 %clamp)
@@ -1666,7 +1747,7 @@ def int_amdgcn_udot4 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// i32 %r = llvm.amdgcn.sdot8(v8i4 (as i32) %a, v8i4 (as i32) %b, i32 %c, i1 %clamp)
@@ -1682,7 +1763,7 @@ def int_amdgcn_sdot8 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
// u32 %r = llvm.amdgcn.udot8(v8u4 (as u32) %a, v8u4 (as u32) %b, u32 %c, i1 %clamp)
@@ -1698,7 +1779,7 @@ def int_amdgcn_udot8 :
llvm_i32_ty, // %c
llvm_i1_ty // %clamp
],
- [IntrNoMem, IntrSpeculatable, ImmArg<3>]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn, ImmArg<ArgIndex<3>>]
>;
//===----------------------------------------------------------------------===//
@@ -1712,140 +1793,183 @@ class AMDGPUBufferAtomicNoRtn : Intrinsic <
llvm_i32_ty, // vindex(VGPR)
llvm_i32_ty, // offset(SGPR/VGPR/imm)
llvm_i1_ty], // slc(imm)
- [], "", [SDNPMemOperand]>,
+ [ImmArg<ArgIndex<4>>, IntrWillReturn], "", [SDNPMemOperand]>,
AMDGPURsrcIntrinsic<1, 0>;
class AMDGPUGlobalAtomicNoRtn : Intrinsic <
[],
[llvm_anyptr_ty, // vaddr
llvm_anyfloat_ty], // vdata(VGPR)
- [IntrArgMemOnly, NoCapture<0>], "", [SDNPMemOperand]>;
+ [IntrArgMemOnly, IntrWillReturn, NoCapture<ArgIndex<0>>], "",
+ [SDNPMemOperand]>;
def int_amdgcn_buffer_atomic_fadd : AMDGPUBufferAtomicNoRtn;
def int_amdgcn_global_atomic_fadd : AMDGPUGlobalAtomicNoRtn;
// llvm.amdgcn.mfma.f32.* vdst, srcA, srcB, srcC, cbsz, abid, blgp
-def int_amdgcn_mfma_f32_32x32x1f32 : Intrinsic<[llvm_v32f32_ty],
- [llvm_float_ty, llvm_float_ty, llvm_v32f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x1f32 : Intrinsic<[llvm_v16f32_ty],
- [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_4x4x1f32 : Intrinsic<[llvm_v4f32_ty],
- [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_32x32x2f32 : Intrinsic<[llvm_v16f32_ty],
- [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x4f32 : Intrinsic<[llvm_v4f32_ty],
- [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_32x32x4f16 : Intrinsic<[llvm_v32f32_ty],
- [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v32f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x4f16 : Intrinsic<[llvm_v16f32_ty],
- [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_4x4x4f16 : Intrinsic<[llvm_v4f32_ty],
- [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_32x32x8f16 : Intrinsic<[llvm_v16f32_ty],
- [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x16f16 : Intrinsic<[llvm_v4f32_ty],
- [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_i32_32x32x4i8 : Intrinsic<[llvm_v32i32_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_v32i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_i32_16x16x4i8 : Intrinsic<[llvm_v16i32_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_i32_4x4x4i8 : Intrinsic<[llvm_v4i32_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_i32_32x32x8i8 : Intrinsic<[llvm_v16i32_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_i32_16x16x16i8 : Intrinsic<[llvm_v4i32_ty],
- [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_32x32x2bf16 : Intrinsic<[llvm_v32f32_ty],
- [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v32f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x2bf16 : Intrinsic<[llvm_v16f32_ty],
- [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_4x4x2bf16 : Intrinsic<[llvm_v4f32_ty],
- [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_32x32x4bf16 : Intrinsic<[llvm_v16f32_ty],
- [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
-
-def int_amdgcn_mfma_f32_16x16x8bf16 : Intrinsic<[llvm_v4f32_ty],
- [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrConvergent, IntrNoMem, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+def int_amdgcn_mfma_f32_32x32x1f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x1f32">,
+ Intrinsic<[llvm_v32f32_ty],
+ [llvm_float_ty, llvm_float_ty, llvm_v32f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x1f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x1f32">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_4x4x1f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_4x4x1f32">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_32x32x2f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x2f32">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_float_ty, llvm_float_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x4f32 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x4f32">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_float_ty, llvm_float_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_32x32x4f16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x4f16">,
+ Intrinsic<[llvm_v32f32_ty],
+ [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v32f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x4f16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x4f16">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_4x4x4f16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_4x4x4f16">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_32x32x8f16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x8f16">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x16f16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x16f16">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f16_ty, llvm_v4f16_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_i32_32x32x4i8 : GCCBuiltin<"__builtin_amdgcn_mfma_i32_32x32x4i8">,
+ Intrinsic<[llvm_v32i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_v32i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_i32_16x16x4i8 : GCCBuiltin<"__builtin_amdgcn_mfma_i32_16x16x4i8">,
+ Intrinsic<[llvm_v16i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_i32_4x4x4i8 : GCCBuiltin<"__builtin_amdgcn_mfma_i32_4x4x4i8">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_i32_32x32x8i8 : GCCBuiltin<"__builtin_amdgcn_mfma_i32_32x32x8i8">,
+ Intrinsic<[llvm_v16i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_v16i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_i32_16x16x16i8 : GCCBuiltin<"__builtin_amdgcn_mfma_i32_16x16x16i8">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_32x32x2bf16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x2bf16">,
+ Intrinsic<[llvm_v32f32_ty],
+ [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v32f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x2bf16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x2bf16">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_4x4x2bf16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_4x4x2bf16">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_32x32x4bf16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_32x32x4bf16">,
+ Intrinsic<[llvm_v16f32_ty],
+ [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v16f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
+
+def int_amdgcn_mfma_f32_16x16x8bf16 : GCCBuiltin<"__builtin_amdgcn_mfma_f32_16x16x8bf16">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v2i16_ty, llvm_v2i16_ty, llvm_v4f32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrConvergent, IntrNoMem, IntrWillReturn,
+ ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
//===----------------------------------------------------------------------===//
// Special Intrinsics for backend internal use only. No frontend
// should emit calls to these.
// ===----------------------------------------------------------------------===//
def int_amdgcn_if : Intrinsic<[llvm_i1_ty, llvm_anyint_ty],
- [llvm_i1_ty], [IntrConvergent]
+ [llvm_i1_ty], [IntrConvergent, IntrWillReturn]
>;
def int_amdgcn_else : Intrinsic<[llvm_i1_ty, llvm_anyint_ty],
- [llvm_anyint_ty], [IntrConvergent]
+ [llvm_anyint_ty], [IntrConvergent, IntrWillReturn]
>;
def int_amdgcn_if_break : Intrinsic<[llvm_anyint_ty],
- [llvm_i1_ty, llvm_anyint_ty], [IntrNoMem, IntrConvergent]
+ [llvm_i1_ty, LLVMMatchType<0>],
+ [IntrNoMem, IntrConvergent, IntrWillReturn]
>;
def int_amdgcn_loop : Intrinsic<[llvm_i1_ty],
- [llvm_anyint_ty], [IntrConvergent]
+ [llvm_anyint_ty], [IntrConvergent, IntrWillReturn]
>;
-def int_amdgcn_end_cf : Intrinsic<[], [llvm_anyint_ty], [IntrConvergent]>;
+def int_amdgcn_end_cf : Intrinsic<[], [llvm_anyint_ty],
+ [IntrConvergent, IntrWillReturn]>;
// Represent unreachable in a divergent region.
def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>;
@@ -1854,6 +1978,12 @@ def int_amdgcn_unreachable : Intrinsic<[], [], [IntrConvergent]>;
// pass based on !fpmath metadata.
def int_amdgcn_fdiv_fast : Intrinsic<
[llvm_float_ty], [llvm_float_ty, llvm_float_ty],
- [IntrNoMem, IntrSpeculatable]
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
+>;
+
+// Represent a relocation constant.
+def int_amdgcn_reloc_constant : Intrinsic<
+ [llvm_i32_ty], [llvm_metadata_ty],
+ [IntrNoMem, IntrSpeculatable, IntrWillReturn]
>;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsARM.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsARM.td
index 518ad7079225..df74e446b965 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsARM.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsARM.td
@@ -19,7 +19,7 @@ let TargetPrefix = "arm" in { // All intrinsics start with "llvm.arm.".
// A space-consuming intrinsic primarily for testing ARMConstantIslands. The
// first argument is the number of bytes this "instruction" takes up, the second
// and return value are essentially chains, used to force ordering during ISel.
-def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>]>;
+def int_arm_space : Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
// 16-bit multiplications
def int_arm_smulbb : GCCBuiltin<"__builtin_arm_smulbb">,
@@ -262,59 +262,59 @@ def int_arm_vcvtru : Intrinsic<[llvm_float_ty], [llvm_anyfloat_ty],
// Coprocessor
def int_arm_ldc : GCCBuiltin<"__builtin_arm_ldc">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_ldcl : GCCBuiltin<"__builtin_arm_ldcl">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_ldc2 : GCCBuiltin<"__builtin_arm_ldc2">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_ldc2l : GCCBuiltin<"__builtin_arm_ldc2l">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_stc : GCCBuiltin<"__builtin_arm_stc">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_stcl : GCCBuiltin<"__builtin_arm_stcl">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_stc2 : GCCBuiltin<"__builtin_arm_stc2">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_arm_stc2l : GCCBuiltin<"__builtin_arm_stc2l">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<0>, ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
// Move to coprocessor
def int_arm_mcr : GCCBuiltin<"__builtin_arm_mcr">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_arm_mcr2 : GCCBuiltin<"__builtin_arm_mcr2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
// Move from coprocessor
def int_arm_mrc : GCCBuiltin<"__builtin_arm_mrc">,
MSBuiltin<"_MoveFromCoprocessor">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_arm_mrc2 : GCCBuiltin<"__builtin_arm_mrc2">,
MSBuiltin<"_MoveFromCoprocessor2">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
// Coprocessor data processing
def int_arm_cdp : GCCBuiltin<"__builtin_arm_cdp">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_arm_cdp2 : GCCBuiltin<"__builtin_arm_cdp2">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>, ImmArg<3>, ImmArg<4>, ImmArg<5>]>;
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
// Move from two registers to coprocessor
def int_arm_mcrr : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_arm_mcrr2 : Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_arm_mrrc : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
def int_arm_mrrc2 : Intrinsic<[llvm_i32_ty, llvm_i32_ty], [llvm_i32_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<0>, ImmArg<1>, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
//===----------------------------------------------------------------------===//
// CRC32
@@ -695,16 +695,16 @@ def int_arm_neon_vst4 : Intrinsic<[],
def int_arm_neon_vst1x2 : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyvector_ty,
LLVMMatchType<1>],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_arm_neon_vst1x3 : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyvector_ty,
LLVMMatchType<1>, LLVMMatchType<1>],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_arm_neon_vst1x4 : Intrinsic<[],
[llvm_anyptr_ty, llvm_anyvector_ty,
LLVMMatchType<1>, LLVMMatchType<1>,
LLVMMatchType<1>],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
// Vector store N-element structure from one lane.
// Source operands are: the address, the N vectors, the lane number, and
@@ -773,6 +773,33 @@ class Neon_Dot_Intrinsic
def int_arm_neon_udot : Neon_Dot_Intrinsic;
def int_arm_neon_sdot : Neon_Dot_Intrinsic;
+// v8.6-A Matrix Multiply Intrinsics
+class Neon_MatMul_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty,
+ LLVMMatchType<1>],
+ [IntrNoMem]>;
+def int_arm_neon_ummla : Neon_MatMul_Intrinsic;
+def int_arm_neon_smmla : Neon_MatMul_Intrinsic;
+def int_arm_neon_usmmla : Neon_MatMul_Intrinsic;
+def int_arm_neon_usdot : Neon_Dot_Intrinsic;
+
+// v8.6-A Bfloat Intrinsics
+def int_arm_neon_vcvtfp2bf
+ : Intrinsic<[llvm_anyvector_ty], [llvm_v4f32_ty], [IntrNoMem]>;
+def int_arm_neon_vcvtbfp2bf
+ : Intrinsic<[llvm_bfloat_ty], [llvm_float_ty], [IntrNoMem]>;
+
+def int_arm_neon_bfdot : Neon_Dot_Intrinsic;
+def int_arm_neon_bfmmla : Neon_MatMul_Intrinsic;
+
+class Neon_FML_Intrinsic
+ : Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<1>],
+ [IntrNoMem]>;
+def int_arm_neon_bfmlalb : Neon_FML_Intrinsic;
+def int_arm_neon_bfmlalt : Neon_FML_Intrinsic;
+
def int_arm_cls: Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_arm_cls64: Intrinsic<[llvm_i32_ty], [llvm_i64_ty], [IntrNoMem]>;
@@ -795,14 +822,8 @@ def int_arm_mve_pred_i2v : Intrinsic<
[llvm_anyvector_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_arm_mve_pred_v2i : Intrinsic<
[llvm_i32_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-
-multiclass IntrinsicSignSuffix<list<LLVMType> rets, list<LLVMType> params = [],
- list<IntrinsicProperty> props = [],
- string name = "",
- list<SDNodeProperty> sdprops = []> {
- def _s: Intrinsic<rets, params, props, name, sdprops>;
- def _u: Intrinsic<rets, params, props, name, sdprops>;
-}
+def int_arm_mve_vreinterpretq : Intrinsic<
+ [llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
def int_arm_mve_min_predicated: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty /* unsigned */,
@@ -876,11 +897,18 @@ def int_arm_mve_qsub_predicated: Intrinsic<[llvm_anyvector_ty],
def int_arm_mve_hsub_predicated: Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty /* unsigned */,
llvm_anyvector_ty, LLVMMatchType<0>], [IntrNoMem]>;
-
-defm int_arm_mve_minv: IntrinsicSignSuffix<[llvm_i32_ty],
- [llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>;
-defm int_arm_mve_maxv: IntrinsicSignSuffix<[llvm_i32_ty],
- [llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>;
+def int_arm_mve_vmina_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_arm_mve_vmaxa_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_arm_mve_vminnma_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
+def int_arm_mve_vmaxnma_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_anyvector_ty],
+ [IntrNoMem]>;
multiclass MVEPredicated<list<LLVMType> rets, list<LLVMType> params,
LLVMType pred = llvm_anyvector_ty,
@@ -897,8 +925,40 @@ multiclass MVEPredicatedM<list<LLVMType> rets, list<LLVMType> params,
LLVMMatchType<0>, rets[0])], props>;
}
+multiclass MVE_minmaxv {
+ defm v: MVEPredicated<[llvm_i32_ty],
+ [llvm_i32_ty, llvm_anyvector_ty, llvm_i32_ty /* unsigned */]>;
+ defm av: MVEPredicated<[llvm_i32_ty],
+ [llvm_i32_ty, llvm_anyvector_ty]>;
+ defm nmv: MVEPredicated<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty]>;
+ defm nmav: MVEPredicated<[llvm_anyfloat_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty]>;
+}
+defm int_arm_mve_min: MVE_minmaxv;
+defm int_arm_mve_max: MVE_minmaxv;
+
+defm int_arm_mve_addv: MVEPredicated<[llvm_i32_ty],
+ [llvm_anyvector_ty, llvm_i32_ty /* unsigned */]>;
+defm int_arm_mve_addlv: MVEPredicated<[llvm_i64_ty],
+ [llvm_anyvector_ty, llvm_i32_ty /* unsigned */]>;
+
+// Intrinsic with a predicated and a non-predicated case. The predicated case
+// has two additional parameters: inactive (the value for inactive lanes, can
+// be undef) and predicate.
+multiclass MVEMXPredicated<list<LLVMType> rets, list<LLVMType> flags,
+ list<LLVMType> params, LLVMType inactive,
+ LLVMType predicate,
+ list<IntrinsicProperty> props = [IntrNoMem]> {
+ def "": Intrinsic<rets, flags # params, props>;
+ def _predicated: Intrinsic<rets, flags # [inactive] # params # [predicate],
+ props>;
+}
+
defm int_arm_mve_vcvt_narrow: MVEPredicated<[llvm_v8f16_ty],
[llvm_v8f16_ty, llvm_v4f32_ty, llvm_i32_ty], llvm_v4i1_ty>;
+defm int_arm_mve_vcvt_widen: MVEMXPredicated<[llvm_v4f32_ty], [],
+ [llvm_v8f16_ty, llvm_i32_ty], llvm_v4f32_ty, llvm_v4i1_ty>;
defm int_arm_mve_vldr_gather_base: MVEPredicated<
[llvm_anyvector_ty], [llvm_anyvector_ty, llvm_i32_ty],
@@ -992,10 +1052,25 @@ def int_arm_mve_vabd: Intrinsic<
def int_arm_mve_vadc: Intrinsic<
[llvm_anyvector_ty, llvm_i32_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]>;
+def int_arm_mve_vsbc: Intrinsic<
+ [llvm_anyvector_ty, llvm_i32_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty], [IntrNoMem]>;
def int_arm_mve_vadc_predicated: Intrinsic<
[llvm_anyvector_ty, llvm_i32_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>,
llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>;
+def int_arm_mve_vsbc_predicated: Intrinsic<
+ [llvm_anyvector_ty, llvm_i32_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i32_ty, llvm_anyvector_ty], [IntrNoMem]>;
+def int_arm_mve_vshlc: Intrinsic<
+ [llvm_i32_ty /* bits shifted out */, llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_i32_ty /* bits shifted in */,
+ llvm_i32_ty /* shift count */], [IntrNoMem]>;
+def int_arm_mve_vshlc_predicated: Intrinsic<
+ [llvm_i32_ty /* bits shifted out */, llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_i32_ty /* bits shifted in */,
+ llvm_i32_ty /* shift count */, llvm_anyvector_ty], [IntrNoMem]>;
def int_arm_mve_vmulh: Intrinsic<
[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, llvm_i32_ty /* unsigned */],
@@ -1030,21 +1105,9 @@ def int_arm_mve_vmull_poly: Intrinsic<
[llvm_anyvector_ty],
[llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty], [IntrNoMem]>;
-// Intrinsic with a predicated and a non-predicated case. The predicated case
-// has two additional parameters: inactive (the value for inactive lanes, can
-// be undef) and predicate.
-multiclass MVEMXPredicated<list<LLVMType> rets, list<LLVMType> flags,
- list<LLVMType> params, LLVMType inactive,
- LLVMType predicate,
- list<IntrinsicProperty> props = [IntrNoMem]> {
- def "": Intrinsic<rets, flags # params, props>;
- def _predicated: Intrinsic<rets, flags # [inactive] # params # [predicate],
- props>;
-}
-
// The first two parameters are compile-time constants:
// * Halving: 0 means halving (vhcaddq), 1 means non-halving (vcaddq)
-// instruction. Note: the flag is inverted to match the corresonding
+// instruction. Note: the flag is inverted to match the corresponding
// bit in the instruction encoding
// * Rotation angle: 0 mean 90 deg, 1 means 180 deg
defm int_arm_mve_vcaddq : MVEMXPredicated<
@@ -1068,12 +1131,11 @@ defm int_arm_mve_vcmlaq : MVEPredicated<
[llvm_i32_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
llvm_anyvector_ty>;
-def int_arm_mve_vld2q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem]>;
-def int_arm_mve_vld4q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem]>;
+def int_arm_mve_vld2q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem, IntrArgMemOnly]>;
+def int_arm_mve_vld4q: Intrinsic<[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [llvm_anyptr_ty], [IntrReadMem, IntrArgMemOnly]>;
-def int_arm_mve_vst2q: Intrinsic<[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty], [IntrWriteMem]>;
-def int_arm_mve_vst4q: Intrinsic<[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>, LLVMMatchType<1>, llvm_i32_ty], [IntrWriteMem]
->;
+def int_arm_mve_vst2q: Intrinsic<[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty], [IntrWriteMem, IntrArgMemOnly]>;
+def int_arm_mve_vst4q: Intrinsic<[], [llvm_anyptr_ty, llvm_anyvector_ty, LLVMMatchType<1>, LLVMMatchType<1>, LLVMMatchType<1>, llvm_i32_ty], [IntrWriteMem, IntrArgMemOnly]>;
// MVE vector absolute difference and accumulate across vector
// The first operand is an 'unsigned' flag. The remaining operands are:
@@ -1121,4 +1183,197 @@ defm int_arm_mve_vrmlldavha: MVEPredicated<
[llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty, llvm_anyvector_ty, LLVMMatchType<0>],
llvm_anyvector_ty>;
+
+defm int_arm_mve_vidup: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */, llvm_i32_ty /* written-back base */], [],
+ [llvm_i32_ty /* base */, llvm_i32_ty /* step */],
+ LLVMMatchType<0>, llvm_anyvector_ty>;
+defm int_arm_mve_vddup: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */, llvm_i32_ty /* written-back base */], [],
+ [llvm_i32_ty /* base */, llvm_i32_ty /* step */],
+ LLVMMatchType<0>, llvm_anyvector_ty>;
+defm int_arm_mve_viwdup: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */, llvm_i32_ty /* written-back base */], [],
+ [llvm_i32_ty /* base */, llvm_i32_ty /* limit */, llvm_i32_ty /* step */],
+ LLVMMatchType<0>, llvm_anyvector_ty>;
+defm int_arm_mve_vdwdup: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */, llvm_i32_ty /* written-back base */], [],
+ [llvm_i32_ty /* base */, llvm_i32_ty /* limit */, llvm_i32_ty /* step */],
+ LLVMMatchType<0>, llvm_anyvector_ty>;
+
+// Flags:
+// * unsigned
+defm int_arm_mve_vcvt_fix: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */], [llvm_i32_ty],
+ [llvm_anyvector_ty /* input vector */, llvm_i32_ty /* scale */],
+ LLVMMatchType<0>, llvm_anyvector_ty>;
+
+def int_arm_mve_vcvt_fp_int_predicated: Intrinsic<
+ [llvm_anyvector_ty], [llvm_anyvector_ty, llvm_i32_ty /* unsigned */,
+ llvm_anyvector_ty /* predicate */, LLVMMatchType<0> /* inactive */],
+ [IntrNoMem]>;
+
+foreach suffix = ["a","n","p","m"] in {
+ defm "int_arm_mve_vcvt"#suffix: MVEMXPredicated<
+ [llvm_anyvector_ty /* output */], [llvm_i32_ty /* unsigned */],
+ [llvm_anyvector_ty /* input */], LLVMMatchType<0>, llvm_anyvector_ty>;
+}
+
+def int_arm_mve_vrintn: Intrinsic<
+ [llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+def int_arm_mve_vcls: Intrinsic<
+ [llvm_anyvector_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+
+defm int_arm_mve_vbrsr: MVEMXPredicated<
+ [llvm_anyvector_ty], [],
+ [LLVMMatchType<0>, llvm_i32_ty], LLVMMatchType<0>, llvm_anyvector_ty>;
+
+def int_arm_mve_vqdmull: Intrinsic<
+ [llvm_anyvector_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty],
+ [IntrNoMem]>;
+def int_arm_mve_vqdmull_predicated: Intrinsic<
+ [llvm_anyvector_ty],
+ [llvm_anyvector_ty, LLVMMatchType<1>, llvm_i32_ty, llvm_anyvector_ty,
+ LLVMMatchType<0>],
+ [IntrNoMem]>;
+
+class MVESimpleUnaryPredicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_arm_mve_mvn_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_abs_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_neg_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_qabs_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_qneg_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_clz_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_cls_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrintz_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrintm_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrintp_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrinta_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrintx_predicated: MVESimpleUnaryPredicated;
+def int_arm_mve_vrintn_predicated: MVESimpleUnaryPredicated;
+
+def int_arm_mve_vrev_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_i32_ty /* size to reverse */,
+ llvm_anyvector_ty, LLVMMatchType<0>], [IntrNoMem]>;
+
+def int_arm_mve_vmovl_predicated: Intrinsic<[llvm_anyvector_ty],
+ [llvm_anyvector_ty, llvm_i32_ty /* unsigned */, llvm_i32_ty /* top half */,
+ llvm_anyvector_ty /* predicate */, LLVMMatchType<0>], [IntrNoMem]>;
+def int_arm_mve_vmovn_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty, llvm_i32_ty /* top half */,
+ llvm_anyvector_ty /* predicate */], [IntrNoMem]>;
+
+def int_arm_mve_vqmovn: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty,
+ llvm_i32_ty /* unsigned output */, llvm_i32_ty /* unsigned input */,
+ llvm_i32_ty /* top half */], [IntrNoMem]>;
+def int_arm_mve_vqmovn_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, llvm_anyvector_ty,
+ llvm_i32_ty /* unsigned output */, llvm_i32_ty /* unsigned input */,
+ llvm_i32_ty /* top half */, llvm_anyvector_ty /* pred */], [IntrNoMem]>;
+
+def int_arm_mve_fma_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* mult op #2 */,
+ LLVMMatchType<0> /* addend */, llvm_anyvector_ty /* pred */], [IntrNoMem]>;
+def int_arm_mve_vmla_n_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* addend */,
+ llvm_i32_ty /* mult op #2 (scalar) */, llvm_anyvector_ty /* pred */],
+ [IntrNoMem]>;
+def int_arm_mve_vmlas_n_predicated: Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* mult op #2 */,
+ llvm_i32_ty /* addend (scalar) */, llvm_anyvector_ty /* pred */],
+ [IntrNoMem]>;
+
+defm int_arm_mve_vqdmlah: MVEPredicated<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* addend */,
+ llvm_i32_ty /* mult op #2 (scalar) */]>;
+defm int_arm_mve_vqrdmlah: MVEPredicated<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* addend */,
+ llvm_i32_ty /* mult op #2 (scalar) */]>;
+defm int_arm_mve_vqdmlash: MVEPredicated<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* mult op #2 */,
+ llvm_i32_ty /* addend (scalar) */]>;
+defm int_arm_mve_vqrdmlash: MVEPredicated<[llvm_anyvector_ty],
+ [LLVMMatchType<0> /* mult op #1 */, LLVMMatchType<0> /* mult op #2 */,
+ llvm_i32_ty /* addend (scalar) */]>;
+
+defm int_arm_mve_vqdmlad: MVEPredicated<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>,
+ llvm_i32_ty /* exchange */, llvm_i32_ty /* round */,
+ llvm_i32_ty /* subtract */]>;
+
+// CDE (Custom Datapath Extension)
+
+multiclass CDEGPRIntrinsics<list<LLVMType> args> {
+ def "" : Intrinsic<
+ [llvm_i32_ty],
+ !listconcat([llvm_i32_ty /* coproc */], args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 1)>>]>;
+ def a : Intrinsic<
+ [llvm_i32_ty],
+ !listconcat([llvm_i32_ty /* coproc */, llvm_i32_ty /* acc */], args,
+ [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 2)>>]>;
+
+ def d: Intrinsic<
+ [llvm_i32_ty /* lo */, llvm_i32_ty /* hi */],
+ !listconcat([llvm_i32_ty /* coproc */], args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 1)>>]>;
+ def da: Intrinsic<
+ [llvm_i32_ty /* lo */, llvm_i32_ty /* hi */],
+ !listconcat([llvm_i32_ty /* coproc */, llvm_i32_ty /* acc_lo */,
+ llvm_i32_ty /* acc_hi */], args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 3)>>]>;
+}
+
+defm int_arm_cde_cx1: CDEGPRIntrinsics<[]>;
+defm int_arm_cde_cx2: CDEGPRIntrinsics<[llvm_i32_ty]>;
+defm int_arm_cde_cx3: CDEGPRIntrinsics<[llvm_i32_ty, llvm_i32_ty]>;
+
+multiclass CDEVCXIntrinsics<list<LLVMType> args> {
+ def "" : Intrinsic<
+ [llvm_anyfloat_ty],
+ !listconcat([llvm_i32_ty /* coproc */], args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 1)>>]>;
+ def a : Intrinsic<
+ [llvm_anyfloat_ty],
+ !listconcat([llvm_i32_ty /* coproc */, LLVMMatchType<0> /* acc */],
+ args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 2)>>]>;
+}
+
+defm int_arm_cde_vcx1 : CDEVCXIntrinsics<[]>;
+defm int_arm_cde_vcx2 : CDEVCXIntrinsics<[LLVMMatchType<0>]>;
+defm int_arm_cde_vcx3 : CDEVCXIntrinsics<[LLVMMatchType<0>, LLVMMatchType<0>]>;
+
+multiclass CDEVCXVecIntrinsics<list<LLVMType> args> {
+ def "" : Intrinsic<
+ [llvm_v16i8_ty],
+ !listconcat([llvm_i32_ty /* coproc */], args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 1)>>]>;
+ def a : Intrinsic<
+ [llvm_v16i8_ty],
+ !listconcat([llvm_i32_ty /* coproc */, llvm_v16i8_ty /* acc */],
+ args, [llvm_i32_ty /* imm */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 2)>>]>;
+
+ def _predicated : Intrinsic<
+ [llvm_anyvector_ty],
+ !listconcat([llvm_i32_ty /* coproc */, LLVMMatchType<0> /* inactive */],
+ args, [llvm_i32_ty /* imm */, llvm_anyvector_ty /* mask */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 2)>>]>;
+ def a_predicated : Intrinsic<
+ [llvm_anyvector_ty],
+ !listconcat([llvm_i32_ty /* coproc */, LLVMMatchType<0> /* acc */],
+ args, [llvm_i32_ty /* imm */, llvm_anyvector_ty /* mask */]),
+ [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<!add(!size(args), 2)>>]>;
+}
+
+defm int_arm_cde_vcx1q : CDEVCXVecIntrinsics<[]>;
+defm int_arm_cde_vcx2q : CDEVCXVecIntrinsics<[llvm_v16i8_ty]>;
+defm int_arm_cde_vcx3q : CDEVCXVecIntrinsics<[llvm_v16i8_ty, llvm_v16i8_ty]>;
+
} // end TargetPrefix
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsBPF.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsBPF.td
index 3618cc6a4128..c4d35b2a0a88 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsBPF.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsBPF.td
@@ -22,5 +22,8 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf."
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty]>;
def int_bpf_preserve_field_info : GCCBuiltin<"__builtin_bpf_preserve_field_info">,
Intrinsic<[llvm_i32_ty], [llvm_anyptr_ty, llvm_i64_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_bpf_btf_type_id : GCCBuiltin<"__builtin_bpf_btf_type_id">,
+ Intrinsic<[llvm_i32_ty], [llvm_any_ty, llvm_any_ty, llvm_i64_ty],
+ [IntrNoMem]>;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagon.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagon.td
index 2abc1dc07ebd..fe16a361ba3d 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagon.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagon.td
@@ -51,19 +51,19 @@ class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
llvm_i32_ty, llvm_i32_ty],
- [IntrArgMemOnly, ImmArg<3>]>;
+ [IntrArgMemOnly, ImmArg<ArgIndex<3>>]>;
class Hexagon_mem_memsisisi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty,
llvm_i32_ty, llvm_i32_ty],
- [IntrWriteMem, ImmArg<3>]>;
+ [IntrWriteMem, ImmArg<ArgIndex<3>>]>;
class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty,
llvm_i32_ty, llvm_i32_ty],
- [IntrWriteMem, ImmArg<3>]>;
+ [IntrWriteMem, ImmArg<ArgIndex<3>>]>;
//
// BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4)
@@ -122,24 +122,8 @@ Hexagon_mem_memsisisi_Intrinsic<"circ_sthhi">;
def int_hexagon_circ_stb :
Hexagon_mem_memsisisi_Intrinsic<"circ_stb">;
-//
-// BUILTIN_INFO(HEXAGON.dcfetch_A,v_ftype_DI*,1)
-//
def int_hexagon_prefetch :
Hexagon_Intrinsic<"HEXAGON_prefetch", [], [llvm_ptr_ty], []>;
-def int_hexagon_Y2_dccleana :
-Hexagon_Intrinsic<"HEXAGON_Y2_dccleana", [], [llvm_ptr_ty], []>;
-def int_hexagon_Y2_dccleaninva :
-Hexagon_Intrinsic<"HEXAGON_Y2_dccleaninva", [], [llvm_ptr_ty], []>;
-def int_hexagon_Y2_dcinva :
-Hexagon_Intrinsic<"HEXAGON_Y2_dcinva", [], [llvm_ptr_ty], []>;
-def int_hexagon_Y2_dczeroa :
-Hexagon_Intrinsic<"HEXAGON_Y2_dczeroa", [], [llvm_ptr_ty],
- [IntrWriteMem, IntrArgMemOnly, IntrHasSideEffects]>;
-def int_hexagon_Y4_l2fetch :
-Hexagon_Intrinsic<"HEXAGON_Y4_l2fetch", [], [llvm_ptr_ty, llvm_i32_ty], []>;
-def int_hexagon_Y5_l2fetch :
-Hexagon_Intrinsic<"HEXAGON_Y5_l2fetch", [], [llvm_ptr_ty, llvm_i64_ty], []>;
def llvm_ptr32_ty : LLVMPointerType<llvm_i32_ty>;
def llvm_ptr64_ty : LLVMPointerType<llvm_i64_ty>;
@@ -147,34 +131,34 @@ def llvm_ptr64_ty : LLVMPointerType<llvm_i64_ty>;
// Mark locked loads as read/write to prevent any accidental reordering.
def int_hexagon_L2_loadw_locked :
Hexagon_Intrinsic<"HEXAGON_L2_loadw_locked", [llvm_i32_ty], [llvm_ptr32_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_hexagon_L4_loadd_locked :
Hexagon_Intrinsic<"HEXAGON_L4_loadd_locked", [llvm_i64_ty], [llvm_ptr64_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_hexagon_S2_storew_locked :
Hexagon_Intrinsic<"HEXAGON_S2_storew_locked", [llvm_i32_ty],
- [llvm_ptr32_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture<0>]>;
+ [llvm_ptr32_ty, llvm_i32_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_hexagon_S4_stored_locked :
Hexagon_Intrinsic<"HEXAGON_S4_stored_locked", [llvm_i32_ty],
- [llvm_ptr64_ty, llvm_i64_ty], [IntrArgMemOnly, NoCapture<0>]>;
+ [llvm_ptr64_ty, llvm_i64_ty], [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_hexagon_vmemcpy : Hexagon_Intrinsic<"hexagon_vmemcpy",
[], [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>, NoCapture<1>, WriteOnly<0>, ReadOnly<1>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>, WriteOnly<ArgIndex<0>>, ReadOnly<ArgIndex<1>>]>;
def int_hexagon_vmemset : Hexagon_Intrinsic<"hexagon_vmemset",
[], [llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>, WriteOnly<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, WriteOnly<ArgIndex<0>>]>;
multiclass Hexagon_custom_circ_ld_Intrinsic<LLVMType ElTy> {
def NAME#_pci : Hexagon_NonGCC_Intrinsic<
[ElTy, llvm_ptr_ty],
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<3>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
def NAME#_pcr : Hexagon_NonGCC_Intrinsic<
[ElTy, llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<2>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<2>>]>;
}
defm int_hexagon_L2_loadrub : Hexagon_custom_circ_ld_Intrinsic<llvm_i32_ty>;
@@ -188,10 +172,10 @@ multiclass Hexagon_custom_circ_st_Intrinsic<LLVMType ElTy> {
def NAME#_pci : Hexagon_NonGCC_Intrinsic<
[llvm_ptr_ty],
[llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty, ElTy, llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<4>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<4>>]>;
def NAME#_pcr : Hexagon_NonGCC_Intrinsic<
[llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty, ElTy, llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<3>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<3>>]>;
}
defm int_hexagon_S2_storerb : Hexagon_custom_circ_st_Intrinsic<llvm_i32_ty>;
@@ -221,6157 +205,83 @@ def int_hexagon_S2_storerf_pbr : Hexagon_mem_memsisi_Intrinsic<"brev_sthhi">;
def int_hexagon_S2_storeri_pbr : Hexagon_mem_memsisi_Intrinsic<"brev_stw">;
def int_hexagon_S2_storerd_pbr : Hexagon_mem_memdisi_Intrinsic<"brev_std">;
-//
-// Masked vector stores
-//
-
-//
-// Hexagon_vv64ivmemv512_Intrinsic<string GCCIntSuffix>
-// tag: V6_vS32b_qpred_ai
-class Hexagon_vv64ivmemv512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v512i1_ty,llvm_ptr_ty,llvm_v16i32_ty],
- [IntrArgMemOnly]>;
-
-//
-// Hexagon_vv128ivmemv1024_Intrinsic<string GCCIntSuffix>
-// tag: V6_vS32b_qpred_ai_128B
-class Hexagon_vv128ivmemv1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v1024i1_ty,llvm_ptr_ty,llvm_v32i32_ty],
- [IntrArgMemOnly]>;
-
-def int_hexagon_V6_vS32b_qpred_ai :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vS32b_qpred_ai">;
-
-def int_hexagon_V6_vS32b_nqpred_ai :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vS32b_nqpred_ai">;
-
-def int_hexagon_V6_vS32b_nt_qpred_ai :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vS32b_nt_qpred_ai">;
-
-def int_hexagon_V6_vS32b_nt_nqpred_ai :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vS32b_nt_nqpred_ai">;
-
-def int_hexagon_V6_vS32b_qpred_ai_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vS32b_qpred_ai_128B">;
-
-def int_hexagon_V6_vS32b_nqpred_ai_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vS32b_nqpred_ai_128B">;
-
-def int_hexagon_V6_vS32b_nt_qpred_ai_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vS32b_nt_qpred_ai_128B">;
-
-def int_hexagon_V6_vS32b_nt_nqpred_ai_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vS32b_nt_nqpred_ai_128B">;
-
-def int_hexagon_V6_vmaskedstoreq :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vmaskedstoreq">;
-
-def int_hexagon_V6_vmaskedstorenq :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vmaskedstorenq">;
-
-def int_hexagon_V6_vmaskedstorentq :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vmaskedstorentq">;
-
-def int_hexagon_V6_vmaskedstorentnq :
-Hexagon_vv64ivmemv512_Intrinsic<"HEXAGON_V6_vmaskedstorentnq">;
-
-def int_hexagon_V6_vmaskedstoreq_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vmaskedstoreq_128B">;
-
-def int_hexagon_V6_vmaskedstorenq_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vmaskedstorenq_128B">;
-
-def int_hexagon_V6_vmaskedstorentq_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vmaskedstorentq_128B">;
-
-def int_hexagon_V6_vmaskedstorentnq_128B :
-Hexagon_vv128ivmemv1024_Intrinsic<"HEXAGON_V6_vmaskedstorentnq_128B">;
-
-class Hexagon_V65_vvmemiiv512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,
- llvm_v16i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemiiv1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,
- llvm_v32i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemiiv2048_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,
- llvm_v64i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemv64iiiv512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_v512i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v16i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemv128iiiv1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_v1024i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v32i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemv64iiiv1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_v512i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v32i32_ty],
- [IntrArgMemOnly]>;
-
-class Hexagon_V65_vvmemv128iiiv2048_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_ptr_ty,llvm_v1024i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v64i32_ty],
- [IntrArgMemOnly]>;
-
-def int_hexagon_V6_vgathermw :
-Hexagon_V65_vvmemiiv512_Intrinsic<"HEXAGON_V6_vgathermw">;
-
-def int_hexagon_V6_vgathermw_128B :
-Hexagon_V65_vvmemiiv1024_Intrinsic<"HEXAGON_V6_vgathermw_128B">;
-
-def int_hexagon_V6_vgathermh :
-Hexagon_V65_vvmemiiv512_Intrinsic<"HEXAGON_V6_vgathermh">;
-
-def int_hexagon_V6_vgathermh_128B :
-Hexagon_V65_vvmemiiv1024_Intrinsic<"HEXAGON_V6_vgathermh_128B">;
-
-def int_hexagon_V6_vgathermhw :
-Hexagon_V65_vvmemiiv1024_Intrinsic<"HEXAGON_V6_vgathermhw">;
-
-def int_hexagon_V6_vgathermhw_128B :
-Hexagon_V65_vvmemiiv2048_Intrinsic<"HEXAGON_V6_vgathermhw_128B">;
-
-def int_hexagon_V6_vgathermwq :
-Hexagon_V65_vvmemv64iiiv512_Intrinsic<"HEXAGON_V6_vgathermwq">;
-
-def int_hexagon_V6_vgathermwq_128B :
-Hexagon_V65_vvmemv128iiiv1024_Intrinsic<"HEXAGON_V6_vgathermwq_128B">;
-
-def int_hexagon_V6_vgathermhq :
-Hexagon_V65_vvmemv64iiiv512_Intrinsic<"HEXAGON_V6_vgathermhq">;
-
-def int_hexagon_V6_vgathermhq_128B :
-Hexagon_V65_vvmemv128iiiv1024_Intrinsic<"HEXAGON_V6_vgathermhq_128B">;
-
-def int_hexagon_V6_vgathermhwq :
-Hexagon_V65_vvmemv64iiiv1024_Intrinsic<"HEXAGON_V6_vgathermhwq">;
-
-def int_hexagon_V6_vgathermhwq_128B :
-Hexagon_V65_vvmemv128iiiv2048_Intrinsic<"HEXAGON_V6_vgathermhwq_128B">;
-
-class Hexagon_V65_viiv512v512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_i32_ty,llvm_i32_ty,
- llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_viiv1024v1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_i32_ty,llvm_i32_ty,
- llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_vv64iiiv512v512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v512i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v16i32_ty,
- llvm_v16i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_vv128iiiv1024v1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v1024i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v32i32_ty,
- llvm_v32i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_viiv1024v512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_i32_ty,llvm_i32_ty,
- llvm_v32i32_ty,llvm_v16i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_viiv2048v1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_i32_ty,llvm_i32_ty,
- llvm_v64i32_ty,llvm_v32i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_vv64iiiv1024v512_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v512i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v32i32_ty,
- llvm_v16i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_vv128iiiv2048v1024_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [], [llvm_v1024i1_ty,llvm_i32_ty,
- llvm_i32_ty,llvm_v64i32_ty,
- llvm_v32i32_ty],
- [IntrWriteMem]>;
-
-class Hexagon_V65_v2048_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [],
- [IntrNoMem]>;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermw,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermw
-def int_hexagon_V6_vscattermw :
-Hexagon_V65_viiv512v512_Intrinsic<"HEXAGON_V6_vscattermw">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermw_128B,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermw_128B
-def int_hexagon_V6_vscattermw_128B :
-Hexagon_V65_viiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermw_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermh,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermh
-def int_hexagon_V6_vscattermh :
-Hexagon_V65_viiv512v512_Intrinsic<"HEXAGON_V6_vscattermh">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermh_128B,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermh_128B
-def int_hexagon_V6_vscattermh_128B :
-Hexagon_V65_viiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermh_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermw_add,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermw_add
-def int_hexagon_V6_vscattermw_add :
-Hexagon_V65_viiv512v512_Intrinsic<"HEXAGON_V6_vscattermw_add">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermw_add_128B,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermw_add_128B
-def int_hexagon_V6_vscattermw_add_128B :
-Hexagon_V65_viiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermw_add_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermh_add,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermh_add
-def int_hexagon_V6_vscattermh_add :
-Hexagon_V65_viiv512v512_Intrinsic<"HEXAGON_V6_vscattermh_add">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermh_add_128B,v_ftype_SISIVIVI,4)
-// tag : V6_vscattermh_add_128B
-def int_hexagon_V6_vscattermh_add_128B :
-Hexagon_V65_viiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermh_add_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermwq,v_ftype_QVSISIVIVI,5)
-// tag : V6_vscattermwq
-def int_hexagon_V6_vscattermwq :
-Hexagon_V65_vv64iiiv512v512_Intrinsic<"HEXAGON_V6_vscattermwq">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermwq_128B,v_ftype_QVSISIVIVI,5)
-// tag : V6_vscattermwq_128B
-def int_hexagon_V6_vscattermwq_128B :
-Hexagon_V65_vv128iiiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermwq_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhq,v_ftype_QVSISIVIVI,5)
-// tag : V6_vscattermhq
-def int_hexagon_V6_vscattermhq :
-Hexagon_V65_vv64iiiv512v512_Intrinsic<"HEXAGON_V6_vscattermhq">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhq_128B,v_ftype_QVSISIVIVI,5)
-// tag : V6_vscattermhq_128B
-def int_hexagon_V6_vscattermhq_128B :
-Hexagon_V65_vv128iiiv1024v1024_Intrinsic<"HEXAGON_V6_vscattermhq_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhw,v_ftype_SISIVDVI,4)
-// tag : V6_vscattermhw
-def int_hexagon_V6_vscattermhw :
-Hexagon_V65_viiv1024v512_Intrinsic<"HEXAGON_V6_vscattermhw">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhw_128B,v_ftype_SISIVDVI,4)
-// tag : V6_vscattermhw_128B
-def int_hexagon_V6_vscattermhw_128B :
-Hexagon_V65_viiv2048v1024_Intrinsic<"HEXAGON_V6_vscattermhw_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhwq,v_ftype_QVSISIVDVI,5)
-// tag : V6_vscattermhwq
-def int_hexagon_V6_vscattermhwq :
-Hexagon_V65_vv64iiiv1024v512_Intrinsic<"HEXAGON_V6_vscattermhwq">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhwq_128B,v_ftype_QVSISIVDVI,5)
-// tag : V6_vscattermhwq_128B
-def int_hexagon_V6_vscattermhwq_128B :
-Hexagon_V65_vv128iiiv2048v1024_Intrinsic<"HEXAGON_V6_vscattermhwq_128B">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhw_add,v_ftype_SISIVDVI,4)
-// tag : V6_vscattermhw_add
-def int_hexagon_V6_vscattermhw_add :
-Hexagon_V65_viiv1024v512_Intrinsic<"HEXAGON_V6_vscattermhw_add">;
-
-//
-// BUILTIN_INFO(HEXAGON.V6_vscattermhw_add_128B,v_ftype_SISIVDVI,4)
-// tag : V6_vscattermhw_add_128B
-def int_hexagon_V6_vscattermhw_add_128B :
-Hexagon_V65_viiv2048v1024_Intrinsic<"HEXAGON_V6_vscattermhw_add_128B">;
-
-// Auto-generated intrinsics
-
-// tag : S2_vsatwh
-class Hexagon_i32_i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrmpybusv
-class Hexagon_v16i32_v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrmpybusv
-class Hexagon_v32i32_v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vaslw_acc
-class Hexagon_v16i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vaslw_acc
-class Hexagon_v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vmux
-class Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmux
-class Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : S2_tableidxd_goodsyntax
-class Hexagon_i32_i32i32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
-
-// tag : V6_vandnqrt_acc
-class Hexagon_v16i32_v16i32v512i1i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v512i1_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandnqrt_acc
-class Hexagon_v32i32_v32i32v1024i1i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v1024i1_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrmpybusi
-class Hexagon_v32i32_v32i32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vrmpybusi
-class Hexagon_v64i32_v64i32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vsubb_dv
-class Hexagon_v64i32_v64i32v64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : M2_mpysu_up
-class Hexagon_i32_i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : M2_mpyud_acc_ll_s0
-class Hexagon_i64_i64i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : S2_lsr_i_r_nac
-class Hexagon_i32_i32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : M2_cmpysc_s0
-class Hexagon_i64_i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_lo
-class Hexagon_v16i32_v32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v32i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_lo
-class Hexagon_v32i32_v64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v64i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : S2_shuffoh
-class Hexagon_i64_i64i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : F2_sfmax
-class Hexagon_float_floatfloat_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_float_ty,llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : A2_vabswsat
-class Hexagon_i64_i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag :
-class Hexagon_v32i32_v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_ldnp0
-class Hexagon_v16i32_i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_ldnp0
-class Hexagon_v32i32_i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhb
-class Hexagon_v16i32_v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhb
-class Hexagon_v32i32_v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : A4_vcmphgti
-class Hexagon_i32_i64i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i64_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag :
-class Hexagon_v32i32_v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : S6_rol_i_p_or
-class Hexagon_i64_i64i64i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vgtuh_and
-class Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vgtuh_and
-class Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : A2_abssat
-class Hexagon_i32_i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : A2_vcmpwgtu
-class Hexagon_i32_i64i64_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vtmpybus_acc
-class Hexagon_v64i32_v64i32v64i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_conv_df2uw_chop
-class Hexagon_i32_double_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_double_ty],
- [IntrNoMem]>;
-
-// tag : V6_pred_or
-class Hexagon_v512i1_v512i1v512i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v512i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_pred_or
-class Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v1024i1_ty],
- [IntrNoMem]>;
-
-// tag : S2_asr_i_p_rnd_goodsyntax
-class Hexagon_i64_i64i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : F2_conv_w2df
-class Hexagon_double_i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_double_ty], [llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vunpackuh
-class Hexagon_v32i32_v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vunpackuh
-class Hexagon_v64i32_v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vadduhw_acc
-class Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vadduhw_acc
-class Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : M2_vdmacs_s0
-class Hexagon_i64_i64i64i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrmpybub_rtt_acc
-class Hexagon_v32i32_v32i32v16i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrmpybub_rtt_acc
-class Hexagon_v64i32_v64i32v32i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_ldu0
-class Hexagon_v16i32_i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_ldu0
-class Hexagon_v32i32_i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : S4_extract_rp
-class Hexagon_i32_i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhsuisat
-class Hexagon_v16i32_v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhsuisat
-class Hexagon_v32i32_v64i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v64i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : A2_addsp
-class Hexagon_i64_i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_extractw
-class Hexagon_i32_v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_extractw
-class Hexagon_i32_v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vlutvwhi
-class Hexagon_v32i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vlutvwhi
-class Hexagon_v64i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vgtuh
-class Hexagon_v512i1_v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vgtuh
-class Hexagon_v1024i1_v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_sffma_lib
-class Hexagon_float_floatfloatfloat_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_float_ty,llvm_float_ty,llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : F2_conv_ud2df
-class Hexagon_double_i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_double_ty], [llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : S2_vzxthw
-class Hexagon_i64_i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vtmpyhb
-class Hexagon_v64i32_v64i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vshufoeh
-class Hexagon_v32i32_v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vshufoeh
-class Hexagon_v64i32_v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vlut4
-class Hexagon_v16i32_v16i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vlut4
-class Hexagon_v32i32_v32i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag :
-class Hexagon_v16i32_v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_conv_uw2sf
-class Hexagon_float_i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vswap
-class Hexagon_v32i32_v512i1v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vswap
-class Hexagon_v64i32_v1024i1v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandnqrt
-class Hexagon_v16i32_v512i1i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandnqrt
-class Hexagon_v32i32_v1024i1i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmpyub
-class Hexagon_v64i32_v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : A5_ACS
-class Hexagon_i64i32_i64i64i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty,llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vunpackob
-class Hexagon_v32i32_v32i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vunpackob
-class Hexagon_v64i32_v64i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmpyhsat_acc
-class Hexagon_v32i32_v32i32v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmpyhsat_acc
-class Hexagon_v64i32_v64i32v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vaddcarrysat
-class Hexagon_v16i32_v16i32v16i32v512i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v512i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_vaddcarrysat
-class Hexagon_v32i32_v32i32v32i32v1024i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v1024i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_vlutvvb_oracc
-class Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vlutvvb_oracc
-class Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix, list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
// tag : V6_vrmpybub_rtt
-class Hexagon_v32i32_v16i32i64_Intrinsic<string GCCIntSuffix>
+class Hexagon_v32i32_v16i32i64_rtt_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_v32i32_ty], [llvm_v16i32_ty,llvm_i64_ty],
[IntrNoMem]>;
-// tag : V6_vrmpybub_rtt
-class Hexagon_v64i32_v32i32i64_Intrinsic<string GCCIntSuffix>
+// tag : V6_vrmpybub_rtt_128B
+class Hexagon_v64i32_v32i32i64_rtt_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_v64i32_ty], [llvm_v32i32_ty,llvm_i64_ty],
[IntrNoMem]>;
-// tag : A4_addp_c
-class Hexagon_i64i32_i64i64i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty,llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vrsadubi_acc
-class Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vrsadubi_acc
-class Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : F2_conv_df2sf
-class Hexagon_float_double_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_double_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandvqv
-class Hexagon_v16i32_v512i1v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v512i1_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandvqv
-class Hexagon_v32i32_v1024i1v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v1024i1_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : C2_vmux
-class Hexagon_i64_i32i64i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i32_ty,llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : F2_sfcmpeq
-class Hexagon_i32_floatfloat_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_float_ty,llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : V6_vmpahhsat
-class Hexagon_v16i32_v16i32v16i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmpahhsat
-class Hexagon_v32i32_v32i32v32i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandvrt
-class Hexagon_v512i1_v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandvrt
-class Hexagon_v1024i1_v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vsubcarry
-class Hexagon_custom_v16i32v512i1_v16i32v16i32v512i1_Intrinsic
- : Hexagon_NonGCC_Intrinsic<
- [llvm_v16i32_ty,llvm_v512i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v512i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_vsubcarry
-class Hexagon_custom_v32i32v1024i1_v32i32v32i32v1024i1_Intrinsic_128B
- : Hexagon_NonGCC_Intrinsic<
- [llvm_v32i32_ty,llvm_v1024i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v1024i1_ty],
- [IntrNoMem]>;
-
-// tag : F2_sffixupr
-class Hexagon_float_float_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : V6_vandvrt_acc
-class Hexagon_v512i1_v512i1v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v512i1_ty,llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vandvrt_acc
-class Hexagon_v1024i1_v1024i1v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v1024i1_ty,llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_dfsub
-class Hexagon_double_doubledouble_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_double_ty], [llvm_double_ty,llvm_double_ty],
- [IntrNoMem, Throws]>;
-
-// tag : V6_vmpyowh_sacc
-class Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vmpyowh_sacc
-class Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
- [IntrNoMem]>;
-
-// tag : S2_insertp
-class Hexagon_i64_i64i64i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : F2_sfinvsqrta
-class Hexagon_floati32_float_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty,llvm_i32_ty], [llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : V6_vtran2x2_map
-class Hexagon_v16i32v16i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty,llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vtran2x2_map
-class Hexagon_v32i32v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty,llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vlutvwh_oracc
-class Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : V6_vlutvwh_oracc
-class Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- !listconcat([IntrNoMem], intr_properties)>;
-
-// tag : F2_dfcmpge
-class Hexagon_i32_doubledouble_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_double_ty,llvm_double_ty],
- [IntrNoMem, Throws]>;
-
-// tag : F2_conv_df2d_chop
-class Hexagon_i64_double_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_double_ty],
- [IntrNoMem]>;
-
-// tag : F2_conv_sf2w
-class Hexagon_i32_float_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_float_ty],
- [IntrNoMem]>;
-
-// tag : F2_sfclass
-class Hexagon_i32_floati32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_float_ty,llvm_i32_ty],
- [IntrNoMem, Throws, ImmArg<1>]>;
-
-// tag : F2_conv_sf2ud_chop
-class Hexagon_i64_float_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty], [llvm_float_ty],
- [IntrNoMem]>;
-
-// tag : V6_pred_scalar2v2
-class Hexagon_v512i1_i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_pred_scalar2v2
-class Hexagon_v1024i1_i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_sfrecipa
-class Hexagon_floati32_floatfloat_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty,llvm_i32_ty], [llvm_float_ty,llvm_float_ty],
- [IntrNoMem, Throws]>;
-
-// tag : V6_vprefixqh
-class Hexagon_v16i32_v512i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v512i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_vprefixqh
-class Hexagon_v32i32_v1024i1_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v1024i1_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhisat_acc
-class Hexagon_v16i32_v16i32v32i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v32i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : V6_vdmpyhisat_acc
-class Hexagon_v32i32_v32i32v64i32i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v64i32_ty,llvm_i32_ty],
- [IntrNoMem]>;
-
-// tag : F2_conv_ud2sf
-class Hexagon_float_i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : F2_conv_sf2df
-class Hexagon_double_float_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_double_ty], [llvm_float_ty],
- [IntrNoMem]>;
-
-// tag : F2_sffma_sc
-class Hexagon_float_floatfloatfloati32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_float_ty], [llvm_float_ty,llvm_float_ty,llvm_float_ty,llvm_i32_ty],
- [IntrNoMem, Throws]>;
-
-// tag : F2_dfclass
-class Hexagon_i32_doublei32_Intrinsic<string GCCIntSuffix,
- list<IntrinsicProperty> intr_properties = []>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_double_ty,llvm_i32_ty],
- !listconcat([IntrNoMem, Throws], intr_properties)>;
-
-// tag : V6_vd0
-class Hexagon_v16i32__Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v16i32_ty], [],
- [IntrNoMem]>;
-
-// tag : V6_vd0
-class Hexagon_v32i32__Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v32i32_ty], [],
- [IntrNoMem]>;
-
-// tag : V6_vdd0
-class Hexagon_v64i32__Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [],
- [IntrNoMem]>;
-
-// tag : S2_insert_rp
-class Hexagon_i32_i32i32i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_vassignp
-class Hexagon_v64i32_v64i32_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v64i32_ty], [llvm_v64i32_ty],
- [IntrNoMem]>;
-
-// tag : A6_vminub_RdP
-class Hexagon_i64i32_i64i64_Intrinsic<string GCCIntSuffix>
- : Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_i64_ty,llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty],
- [IntrNoMem]>;
-
-// tag : V6_pred_not
-class Hexagon_v512i1_v512i1_Intrinsic<string GCCIntSuffix>
+// tag : V6_vrmpybub_rtt_acc
+class Hexagon_v32i32_v32i32v16i32i64_rtt_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v512i1_ty], [llvm_v512i1_ty],
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_i64_ty],
[IntrNoMem]>;
-// tag : V6_pred_not
-class Hexagon_v1024i1_v1024i1_Intrinsic<string GCCIntSuffix>
+// tag : V6_vrmpybub_rtt_acc_128B
+class Hexagon_v64i32_v64i32v32i32i64_rtt_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
- [llvm_v1024i1_ty], [llvm_v1024i1_ty],
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_i64_ty],
[IntrNoMem]>;
-// V5 Scalar Instructions.
-
-def int_hexagon_S2_asr_r_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_or">;
-
-def int_hexagon_S2_vsatwh :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsatwh">;
-
-def int_hexagon_S2_tableidxd_goodsyntax :
-Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxd_goodsyntax">;
-
-def int_hexagon_M2_mpysu_up :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysu_up">;
-
-def int_hexagon_M2_mpyud_acc_ll_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s0">;
-
-def int_hexagon_M2_mpyud_acc_ll_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s1">;
-
-def int_hexagon_M2_cmpysc_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpysc_s1">;
-
-def int_hexagon_M2_cmpysc_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpysc_s0">;
-
-def int_hexagon_M4_cmpyi_whc :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyi_whc">;
-
-def int_hexagon_M2_mpy_sat_rnd_lh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s1">;
-
-def int_hexagon_M2_mpy_sat_rnd_lh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s0">;
-
-def int_hexagon_S2_tableidxb_goodsyntax :
-Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxb_goodsyntax">;
-
-def int_hexagon_S2_shuffoh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffoh">;
-
-def int_hexagon_F2_sfmax :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmax">;
-
-def int_hexagon_A2_vabswsat :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabswsat">;
-
-def int_hexagon_S2_asr_i_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r", [ImmArg<1>]>;
-
-def int_hexagon_S2_asr_i_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p", [ImmArg<1>]>;
-
-def int_hexagon_A4_combineri :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineri", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpy_nac_sat_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s1">;
-
-def int_hexagon_M4_vpmpyh_acc :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M4_vpmpyh_acc">;
-
-def int_hexagon_M2_vcmpy_s0_sat_i :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_i">;
-
-def int_hexagon_A2_notp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_notp">;
-
-def int_hexagon_M2_mpy_hl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hl_s1">;
-
-def int_hexagon_M2_mpy_hl_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hl_s0">;
-
-def int_hexagon_C4_or_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_and">;
-
-def int_hexagon_M2_vmac2s_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2s_s0">;
-
-def int_hexagon_M2_vmac2s_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2s_s1">;
-
-def int_hexagon_S2_brevp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_brevp">;
-
-def int_hexagon_M4_pmpyw_acc :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M4_pmpyw_acc">;
-
-def int_hexagon_S2_cl1 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_cl1">;
-
-def int_hexagon_C4_cmplte :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplte">;
-
-def int_hexagon_M2_mmpyul_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_s0">;
-
-def int_hexagon_A2_vaddws :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddws">;
-
-def int_hexagon_A2_maxup :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxup">;
-
-def int_hexagon_A4_vcmphgti :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgti", [ImmArg<1>]>;
-
-def int_hexagon_S2_interleave :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_interleave">;
-
-def int_hexagon_M2_vrcmpyi_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyi_s0">;
-
-def int_hexagon_A2_abssat :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_abssat">;
-
-def int_hexagon_A2_vcmpwgtu :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
-
-def int_hexagon_C2_cmpgtu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtu">;
-
-def int_hexagon_C2_cmpgtp :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtp">;
-
-def int_hexagon_A4_cmphgtui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtui", [ImmArg<1>]>;
-
-def int_hexagon_C2_cmpgti :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgti", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpyi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyi">;
-
-def int_hexagon_F2_conv_df2uw_chop :
-Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2uw_chop">;
-
-def int_hexagon_A4_cmpheq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheq">;
-
-def int_hexagon_M2_mpy_lh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_lh_s1">;
-
-def int_hexagon_M2_mpy_lh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_lh_s0">;
-
-def int_hexagon_S2_lsr_i_r_xacc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc", [ImmArg<2>]>;
-
-def int_hexagon_S2_vrcnegh :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vrcnegh">;
-
-def int_hexagon_S2_extractup :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S2_extractup", [ImmArg<1>, ImmArg<2>]>;
-
-def int_hexagon_S2_asr_i_p_rnd_goodsyntax :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax", [ImmArg<1>]>;
-
-def int_hexagon_S4_ntstbit_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_r">;
-
-def int_hexagon_F2_conv_w2sf :
-Hexagon_float_i32_Intrinsic<"HEXAGON_F2_conv_w2sf">;
-
-def int_hexagon_C2_not :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_not">;
-
-def int_hexagon_C2_tfrpr :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_tfrpr">;
-
-def int_hexagon_M2_mpy_ll_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_ll_s1">;
-
-def int_hexagon_M2_mpy_ll_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_ll_s0">;
-
-def int_hexagon_A4_cmpbgt :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgt">;
-
-def int_hexagon_S2_asr_r_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_and">;
-
-def int_hexagon_A4_rcmpneqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneqi", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_nac", [ImmArg<2>]>;
-
-def int_hexagon_M2_subacc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_subacc">;
-
-def int_hexagon_A2_orp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_orp">;
-
-def int_hexagon_M2_mpyu_up :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_up">;
-
-def int_hexagon_M2_mpy_acc_sat_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s1">;
-
-def int_hexagon_S2_asr_i_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vh", [ImmArg<1>]>;
-
-def int_hexagon_S2_asr_i_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vw", [ImmArg<1>]>;
-
-def int_hexagon_A4_cmpbgtu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtu">;
-
-def int_hexagon_A4_vcmpbeq_any :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
-
-def int_hexagon_A4_cmpbgti :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgti", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpyd_lh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_lh_s1">;
-
-def int_hexagon_S2_asl_r_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_nac">;
-
-def int_hexagon_S2_lsr_i_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_nac", [ImmArg<2>]>;
-
-def int_hexagon_A2_addsp :
-Hexagon_i64_i32i64_Intrinsic<"HEXAGON_A2_addsp">;
-
-def int_hexagon_S4_vxsubaddw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddw">;
-
-def int_hexagon_A4_vcmpheqi :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpheqi", [ImmArg<1>]>;
-
-def int_hexagon_S4_vxsubaddh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddh">;
-
-def int_hexagon_M4_pmpyw :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M4_pmpyw">;
-
-def int_hexagon_S2_vsathb :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsathb">;
-
-def int_hexagon_S2_asr_r_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_and">;
-
-def int_hexagon_M2_mpyu_acc_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s1">;
-
-def int_hexagon_M2_mpyu_acc_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s0">;
-
-def int_hexagon_S2_lsl_r_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_acc">;
-
-def int_hexagon_A2_pxorf :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_A2_pxorf">;
-
-def int_hexagon_C2_cmpgei :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgei", [ImmArg<1>]>;
-
-def int_hexagon_A2_vsubub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubub">;
-
-def int_hexagon_S2_asl_i_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_p", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r", [ImmArg<1>]>;
-
-def int_hexagon_A4_vrminuw :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminuw">;
-
-def int_hexagon_F2_sffma :
-Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffma">;
-
-def int_hexagon_A2_absp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_absp">;
-
-def int_hexagon_C2_all8 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_all8">;
-
-def int_hexagon_A4_vrminuh :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminuh">;
-
-def int_hexagon_F2_sffma_lib :
-Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffma_lib">;
-
-def int_hexagon_M4_vrmpyoh_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_s0">;
-
-def int_hexagon_M4_vrmpyoh_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_s1">;
-
-def int_hexagon_C2_bitsset :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsset">;
-
-def int_hexagon_M2_mpysip :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysip", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpysin :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysin", [ImmArg<1>]>;
-
-def int_hexagon_A4_boundscheck :
-Hexagon_i32_i32i64_Intrinsic<"HEXAGON_A4_boundscheck">;
-
-def int_hexagon_M5_vrmpybuu :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vrmpybuu">;
-
-def int_hexagon_C4_fastcorner9 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_fastcorner9">;
-
-def int_hexagon_M2_vrcmpys_s1rp :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_s1rp">;
-
-def int_hexagon_A2_neg :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_neg">;
-
-def int_hexagon_A2_subsat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subsat">;
-
-def int_hexagon_S2_asl_r_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_r_r">;
-
-def int_hexagon_S2_asl_r_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_p">;
-
-def int_hexagon_A2_vnavgh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgh">;
-
-def int_hexagon_M2_mpy_nac_sat_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s0">;
-
-def int_hexagon_F2_conv_ud2df :
-Hexagon_double_i64_Intrinsic<"HEXAGON_F2_conv_ud2df">;
-
-def int_hexagon_A2_vnavgw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgw">;
-
-def int_hexagon_S2_asl_i_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_acc", [ImmArg<2>]>;
-
-def int_hexagon_S4_subi_lsr_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_lsr_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_S2_vzxthw :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxthw">;
-
-def int_hexagon_F2_sfadd :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfadd">;
-
-def int_hexagon_A2_sub :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_sub">;
-
-def int_hexagon_M2_vmac2su_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2su_s0">;
-
-def int_hexagon_M2_vmac2su_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2su_s1">;
-
-def int_hexagon_M2_dpmpyss_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_s0">;
-
-def int_hexagon_S2_insert :
-Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_insert">;
-
-def int_hexagon_S2_packhl :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_S2_packhl">;
-
-def int_hexagon_A4_vcmpwgti :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgti", [ImmArg<1>]>;
-
-def int_hexagon_A2_vavguwr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguwr">;
-
-def int_hexagon_S2_asl_r_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_and">;
-
-def int_hexagon_A2_svsubhs :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubhs">;
-
-def int_hexagon_A2_addh_l16_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_hl">;
-
-def int_hexagon_M4_and_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_and">;
-
-def int_hexagon_F2_conv_d2df :
-Hexagon_double_i64_Intrinsic<"HEXAGON_F2_conv_d2df">;
-
-def int_hexagon_C2_cmpgtui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtui", [ImmArg<1>]>;
-
-def int_hexagon_A2_vconj :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vconj">;
-
-def int_hexagon_S2_lsr_r_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_vw">;
-
-def int_hexagon_S2_lsr_r_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_vh">;
-
-def int_hexagon_A2_subh_l16_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_hl">;
-
-def int_hexagon_S4_vxsubaddhr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddhr">;
-
-def int_hexagon_S2_clbp :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_clbp">;
-
-def int_hexagon_S2_deinterleave :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_deinterleave">;
-
-def int_hexagon_C2_any8 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_any8">;
-
-def int_hexagon_S2_togglebit_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_r">;
-
-def int_hexagon_S2_togglebit_i :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_i", [ImmArg<1>]>;
-
-def int_hexagon_F2_conv_uw2sf :
-Hexagon_float_i32_Intrinsic<"HEXAGON_F2_conv_uw2sf">;
-
-def int_hexagon_S2_vsathb_nopack :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsathb_nopack">;
-
-def int_hexagon_M2_cmacs_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacs_s0">;
-
-def int_hexagon_M2_cmacs_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacs_s1">;
-
-def int_hexagon_M2_mpy_sat_hh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s0">;
-
-def int_hexagon_M2_mpy_sat_hh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s1">;
-
-def int_hexagon_M2_mmacuhs_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_s1">;
-
-def int_hexagon_M2_mmacuhs_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_s0">;
-
-def int_hexagon_S2_clrbit_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_r">;
-
-def int_hexagon_C4_or_andn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_andn">;
-
-def int_hexagon_S2_asl_r_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_nac">;
-
-def int_hexagon_S2_asl_i_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_acc", [ImmArg<2>]>;
-
-def int_hexagon_A4_vcmpwgtui :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgtui", [ImmArg<1>]>;
-
-def int_hexagon_M4_vrmpyoh_acc_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s0">;
-
-def int_hexagon_M4_vrmpyoh_acc_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s1">;
-
-def int_hexagon_A4_vrmaxh :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxh">;
-
-def int_hexagon_A2_vcmpbeq :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpbeq">;
-
-def int_hexagon_A2_vcmphgt :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmphgt">;
-
-def int_hexagon_A2_vnavgwcr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgwcr">;
-
-def int_hexagon_M2_vrcmacr_s0c :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmacr_s0c">;
-
-def int_hexagon_A2_vavgwcr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgwcr">;
-
-def int_hexagon_S2_asl_i_p_xacc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_xacc", [ImmArg<2>]>;
-
-def int_hexagon_A4_vrmaxw :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxw">;
-
-def int_hexagon_A2_vnavghr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavghr">;
-
-def int_hexagon_M4_cmpyi_wh :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyi_wh">;
-
-def int_hexagon_A2_tfrsi :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrsi", [ImmArg<0>]>;
-
-def int_hexagon_S2_asr_i_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_acc", [ImmArg<2>]>;
-
-def int_hexagon_A2_svnavgh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svnavgh">;
-
-def int_hexagon_S2_lsr_i_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r", [ImmArg<1>]>;
-
-def int_hexagon_M2_vmac2 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2">;
-
-def int_hexagon_A4_vcmphgtui :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgtui", [ImmArg<1>]>;
-
-def int_hexagon_A2_svavgh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svavgh">;
-
-def int_hexagon_M4_vrmpyeh_acc_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s0">;
-
-def int_hexagon_M4_vrmpyeh_acc_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s1">;
-
-def int_hexagon_S2_lsr_i_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p", [ImmArg<1>]>;
-
-def int_hexagon_A2_combine_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_hl">;
-
-def int_hexagon_M2_mpy_up :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up">;
-
-def int_hexagon_A2_combine_hh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_hh">;
-
-def int_hexagon_A2_negsat :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_negsat">;
-
-def int_hexagon_M2_mpyd_hl_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hl_s0">;
-
-def int_hexagon_M2_mpyd_hl_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hl_s1">;
-
-def int_hexagon_A4_bitsplit :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitsplit">;
-
-def int_hexagon_A2_vabshsat :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabshsat">;
-
-def int_hexagon_M2_mpyui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyui">;
-
-def int_hexagon_A2_addh_l16_sat_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_sat_ll">;
-
-def int_hexagon_S2_lsl_r_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_and">;
-
-def int_hexagon_M2_mmpyul_rs0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs0">;
-
-def int_hexagon_S2_asr_i_r_rnd_goodsyntax :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_r_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_nac">;
-
-def int_hexagon_C2_cmplt :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmplt">;
-
-def int_hexagon_M2_cmacr_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacr_s0">;
-
-def int_hexagon_M4_or_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_and">;
-
-def int_hexagon_M4_mpyrr_addi :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addi", [ImmArg<0>]>;
-
-def int_hexagon_S4_or_andi :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andi", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpy_sat_hl_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s0">;
-
-def int_hexagon_M2_mpy_sat_hl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s1">;
-
-def int_hexagon_M4_mpyrr_addr :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addr">;
-
-def int_hexagon_M2_mmachs_rs0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_rs0">;
-
-def int_hexagon_M2_mmachs_rs1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_rs1">;
-
-def int_hexagon_M2_vrcmpyr_s0c :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyr_s0c">;
-
-def int_hexagon_M2_mpy_acc_sat_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s0">;
-
-def int_hexagon_M2_mpyd_acc_ll_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s1">;
-
-def int_hexagon_F2_sffixupn :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sffixupn">;
-
-def int_hexagon_M2_mpyd_acc_lh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s0">;
-
-def int_hexagon_M2_mpyd_acc_lh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s1">;
-
-def int_hexagon_M2_mpy_rnd_hh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s0">;
-
-def int_hexagon_M2_mpy_rnd_hh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s1">;
-
-def int_hexagon_A2_vadduhs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vadduhs">;
-
-def int_hexagon_A2_vsubuhs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubuhs">;
-
-def int_hexagon_A2_subh_h16_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_hl">;
-
-def int_hexagon_A2_subh_h16_hh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_hh">;
-
-def int_hexagon_A2_xorp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_xorp">;
-
-def int_hexagon_A4_tfrpcp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A4_tfrpcp">;
-
-def int_hexagon_A2_addh_h16_lh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_lh">;
-
-def int_hexagon_A2_addh_h16_sat_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_hl">;
-
-def int_hexagon_A2_addh_h16_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_ll">;
-
-def int_hexagon_A2_addh_h16_sat_hh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_hh">;
-
-def int_hexagon_A2_zxtb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_zxtb">;
-
-def int_hexagon_A2_zxth :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_zxth">;
-
-def int_hexagon_A2_vnavgwr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgwr">;
-
-def int_hexagon_M4_or_xor :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_xor">;
-
-def int_hexagon_M2_mpyud_acc_hh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s0">;
-
-def int_hexagon_M2_mpyud_acc_hh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s1">;
-
-def int_hexagon_M5_vmacbsu :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M5_vmacbsu">;
-
-def int_hexagon_M2_dpmpyuu_acc_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_acc_s0">;
-
-def int_hexagon_M2_mpy_rnd_hl_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s0">;
-
-def int_hexagon_M2_mpy_rnd_hl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s1">;
-
-def int_hexagon_F2_sffms_lib :
-Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms_lib">;
-
-def int_hexagon_C4_cmpneqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneqi", [ImmArg<1>]>;
-
-def int_hexagon_M4_and_xor :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_xor">;
-
-def int_hexagon_A2_sat :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_A2_sat">;
-
-def int_hexagon_M2_mpyd_nac_lh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s1">;
-
-def int_hexagon_M2_mpyd_nac_lh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s0">;
-
-def int_hexagon_A2_addsat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addsat">;
-
-def int_hexagon_A2_svavghs :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svavghs">;
-
-def int_hexagon_A2_vrsadub_acc :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_A2_vrsadub_acc">;
-
-def int_hexagon_C2_bitsclri :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclri", [ImmArg<1>]>;
-
-def int_hexagon_A2_subh_h16_sat_hh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_hh">;
-
-def int_hexagon_A2_subh_h16_sat_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_hl">;
-
-def int_hexagon_M2_mmaculs_rs0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_rs0">;
-
-def int_hexagon_M2_mmaculs_rs1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_rs1">;
-
-def int_hexagon_M2_vradduh :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vradduh">;
-
-def int_hexagon_A4_addp_c :
-Hexagon_i64i32_i64i64i32_Intrinsic<"HEXAGON_A4_addp_c">;
-
-def int_hexagon_C2_xor :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_xor">;
-
-def int_hexagon_S2_lsl_r_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_acc">;
-
-def int_hexagon_M2_mmpyh_rs1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_rs1">;
-
-def int_hexagon_M2_mmpyh_rs0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_rs0">;
-
-def int_hexagon_F2_conv_df2ud_chop :
-Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2ud_chop">;
-
-def int_hexagon_C4_or_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_or">;
-
-def int_hexagon_S4_vxaddsubhr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubhr">;
-
-def int_hexagon_S2_vsathub :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsathub">;
-
-def int_hexagon_F2_conv_df2sf :
-Hexagon_float_double_Intrinsic<"HEXAGON_F2_conv_df2sf">;
-
-def int_hexagon_M2_hmmpyh_rs1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyh_rs1">;
-
-def int_hexagon_M2_hmmpyh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyh_s1">;
-
-def int_hexagon_A2_vavgwr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgwr">;
-
-def int_hexagon_S2_tableidxh_goodsyntax :
-Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxh_goodsyntax">;
-
-def int_hexagon_A2_sxth :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sxth">;
-
-def int_hexagon_A2_sxtb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sxtb">;
-
-def int_hexagon_C4_or_orn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_orn">;
-
-def int_hexagon_M2_vrcmaci_s0c :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmaci_s0c">;
-
-def int_hexagon_A2_sxtw :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_sxtw">;
-
-def int_hexagon_M2_vabsdiffh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vabsdiffh">;
-
-def int_hexagon_M2_mpy_acc_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s1">;
-
-def int_hexagon_M2_mpy_acc_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s0">;
-
-def int_hexagon_M2_hmmpyl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyl_s1">;
-
-def int_hexagon_S2_cl1p :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_cl1p">;
-
-def int_hexagon_M2_vabsdiffw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vabsdiffw">;
-
-def int_hexagon_A4_andnp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A4_andnp">;
-
-def int_hexagon_C2_vmux :
-Hexagon_i64_i32i64i64_Intrinsic<"HEXAGON_C2_vmux">;
-
-def int_hexagon_S2_parityp :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_S2_parityp">;
-
-def int_hexagon_S2_lsr_i_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_and", [ImmArg<2>]>;
-
-def int_hexagon_S2_asr_i_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_or", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpyu_nac_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s0">;
-
-def int_hexagon_M2_mpyu_nac_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s1">;
-
-def int_hexagon_F2_sfcmpeq :
-Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpeq">;
-
-def int_hexagon_A2_vaddb_map :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddb_map">;
-
-def int_hexagon_S2_lsr_r_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_nac">;
-
-def int_hexagon_A2_vcmpheq :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpheq">;
-
-def int_hexagon_S2_clbnorm :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_clbnorm">;
-
-def int_hexagon_M2_cnacsc_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacsc_s1">;
-
-def int_hexagon_M2_cnacsc_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacsc_s0">;
-
-def int_hexagon_S4_subaddi :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subaddi", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpyud_nac_hl_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s1">;
-
-def int_hexagon_M2_mpyud_nac_hl_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s0">;
-
-def int_hexagon_S5_vasrhrnd_goodsyntax :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax", [ImmArg<1>]>;
-
-def int_hexagon_S2_tstbit_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_r">;
-
-def int_hexagon_S4_vrcrotate :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate", [ImmArg<2>]>;
-
-def int_hexagon_M2_mmachs_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s1">;
-
-def int_hexagon_M2_mmachs_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s0">;
-
-def int_hexagon_S2_tstbit_i :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_i", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpy_up_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up_s1">;
-
-def int_hexagon_S2_extractu_rp :
-Hexagon_i32_i32i64_Intrinsic<"HEXAGON_S2_extractu_rp">;
-
-def int_hexagon_M2_mmpyuh_rs0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs0">;
-
-def int_hexagon_S2_lsr_i_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vw", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpy_rnd_ll_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s0">;
-
-def int_hexagon_M2_mpy_rnd_ll_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s1">;
-
-def int_hexagon_M4_or_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_or">;
-
-def int_hexagon_M2_mpyu_hh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hh_s1">;
-
-def int_hexagon_M2_mpyu_hh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hh_s0">;
-
-def int_hexagon_S2_asl_r_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_acc">;
-
-def int_hexagon_M2_mpyu_nac_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s0">;
-
-def int_hexagon_M2_mpyu_nac_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s1">;
-
-def int_hexagon_M2_mpy_sat_ll_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s0">;
-
-def int_hexagon_M2_mpy_sat_ll_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s1">;
-
-def int_hexagon_F2_conv_w2df :
-Hexagon_double_i32_Intrinsic<"HEXAGON_F2_conv_w2df">;
-
-def int_hexagon_A2_subh_l16_sat_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_sat_hl">;
-
-def int_hexagon_C2_cmpeqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeqi", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_and", [ImmArg<2>]>;
-
-def int_hexagon_S2_vcnegh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_vcnegh">;
-
-def int_hexagon_A4_vcmpweqi :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpweqi", [ImmArg<1>]>;
-
-def int_hexagon_M2_vdmpyrs_s0 :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vdmpyrs_s0">;
-
-def int_hexagon_M2_vdmpyrs_s1 :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vdmpyrs_s1">;
-
-def int_hexagon_M4_xor_xacc :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_xor_xacc">;
-
-def int_hexagon_M2_vdmpys_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vdmpys_s1">;
-
-def int_hexagon_M2_vdmpys_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vdmpys_s0">;
-
-def int_hexagon_A2_vavgubr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgubr">;
-
-def int_hexagon_M2_mpyu_hl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hl_s1">;
-
-def int_hexagon_M2_mpyu_hl_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hl_s0">;
-
-def int_hexagon_S2_asl_r_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_acc">;
-
-def int_hexagon_S2_cl0p :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_cl0p">;
-
-def int_hexagon_S2_valignib :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignib", [ImmArg<2>]>;
-
-def int_hexagon_F2_sffixupd :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sffixupd">;
-
-def int_hexagon_M2_mpy_sat_rnd_hl_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s1">;
-
-def int_hexagon_M2_mpy_sat_rnd_hl_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s0">;
-
-def int_hexagon_M2_cmacsc_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacsc_s0">;
-
-def int_hexagon_M2_cmacsc_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacsc_s1">;
-
-def int_hexagon_S2_ct1 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_ct1">;
-
-def int_hexagon_S2_ct0 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_ct0">;
-
-def int_hexagon_M2_dpmpyuu_nac_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_nac_s0">;
-
-def int_hexagon_M2_mmpyul_rs1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs1">;
-
-def int_hexagon_S4_ntstbit_i :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_i", [ImmArg<1>]> ;
-
-def int_hexagon_F2_sffixupr :
-Hexagon_float_float_Intrinsic<"HEXAGON_F2_sffixupr">;
-
-def int_hexagon_S2_asr_r_p_xor :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_xor">;
-
-def int_hexagon_M2_mpyud_acc_hl_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s0">;
-
-def int_hexagon_M2_mpyud_acc_hl_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s1">;
-
-def int_hexagon_A2_vcmphgtu :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmphgtu">;
-
-def int_hexagon_C2_andn :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_andn">;
-
-def int_hexagon_M2_vmpy2s_s0pack :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s0pack">;
-
-def int_hexagon_S4_addaddi :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addaddi", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpyd_acc_ll_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s0">;
-
-def int_hexagon_M2_mpy_acc_sat_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s1">;
-
-def int_hexagon_A4_rcmpeqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeqi", [ImmArg<1>]>;
-
-def int_hexagon_M4_xor_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_and">;
-
-def int_hexagon_S2_asl_i_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_and", [ImmArg<2>]>;
-
-def int_hexagon_M2_mmpyuh_rs1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs1">;
-
-def int_hexagon_S2_asr_r_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_or">;
-
-def int_hexagon_A4_round_ri :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri", [ImmArg<1>]>;
-
-def int_hexagon_A2_max :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_max">;
-
-def int_hexagon_A4_round_rr :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_rr">;
-
-def int_hexagon_A4_combineii :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineii", [ImmArg<0>, ImmArg<1>]>;
-
-def int_hexagon_A4_combineir :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineir", [ImmArg<0>]>;
-
-def int_hexagon_C4_and_orn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_orn">;
-
-def int_hexagon_M5_vmacbuu :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M5_vmacbuu">;
-
-def int_hexagon_A4_rcmpeq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeq">;
-
-def int_hexagon_M4_cmpyr_whc :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_whc">;
-
-def int_hexagon_S2_lsr_i_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_acc", [ImmArg<2>]>;
-
-def int_hexagon_S2_vzxtbh :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxtbh">;
-
-def int_hexagon_M2_mmacuhs_rs1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_rs1">;
-
-def int_hexagon_S2_asr_r_r_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_sat">;
-
-def int_hexagon_A2_combinew :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combinew">;
-
-def int_hexagon_M2_mpy_acc_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s1">;
-
-def int_hexagon_M2_mpy_acc_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s0">;
-
-def int_hexagon_M2_cmpyi_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpyi_s0">;
-
-def int_hexagon_S2_asl_r_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_or">;
-
-def int_hexagon_S4_ori_asl_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_asl_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_C4_nbitsset :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsset">;
-
-def int_hexagon_M2_mpyu_acc_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s1">;
-
-def int_hexagon_M2_mpyu_acc_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s0">;
-
-def int_hexagon_M2_mpyu_ll_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_ll_s1">;
-
-def int_hexagon_M2_mpyu_ll_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_ll_s0">;
-
-def int_hexagon_A2_addh_l16_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_ll">;
-
-def int_hexagon_S2_lsr_r_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_and">;
-
-def int_hexagon_A4_modwrapu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_modwrapu">;
-
-def int_hexagon_A4_rcmpneq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneq">;
-
-def int_hexagon_M2_mpyd_acc_hh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s0">;
-
-def int_hexagon_M2_mpyd_acc_hh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s1">;
-
-def int_hexagon_F2_sfimm_p :
-Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_p", [ImmArg<0>]>;
-
-def int_hexagon_F2_sfimm_n :
-Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_n", [ImmArg<0>]>;
-
-def int_hexagon_M4_cmpyr_wh :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_wh">;
-
-def int_hexagon_S2_lsl_r_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_and">;
-
-def int_hexagon_A2_vavgub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgub">;
-
-def int_hexagon_F2_conv_d2sf :
-Hexagon_float_i64_Intrinsic<"HEXAGON_F2_conv_d2sf">;
-
-def int_hexagon_A2_vavguh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguh">;
-
-def int_hexagon_A4_cmpbeqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeqi", [ImmArg<1>]>;
-
-def int_hexagon_F2_sfcmpuo :
-Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpuo">;
-
-def int_hexagon_A2_vavguw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguw">;
-
-def int_hexagon_S2_asr_i_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_nac", [ImmArg<2>]>;
-
-def int_hexagon_S2_vsatwh_nopack :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsatwh_nopack">;
-
-def int_hexagon_M2_mpyd_hh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hh_s0">;
-
-def int_hexagon_M2_mpyd_hh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hh_s1">;
-
-def int_hexagon_S2_lsl_r_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_or">;
-
-def int_hexagon_A2_minu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_minu">;
-
-def int_hexagon_M2_mpy_sat_lh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s1">;
-
-def int_hexagon_M4_or_andn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_andn">;
-
-def int_hexagon_A2_minp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_minp">;
-
-def int_hexagon_S4_or_andix :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andix", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpy_rnd_lh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s0">;
-
-def int_hexagon_M2_mpy_rnd_lh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s1">;
-
-def int_hexagon_M2_mmpyuh_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_s0">;
-
-def int_hexagon_M2_mmpyuh_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_s1">;
-
-def int_hexagon_M2_mpy_acc_sat_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s0">;
-
-def int_hexagon_F2_sfcmpge :
-Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpge">;
-
-def int_hexagon_F2_sfmin :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmin">;
-
-def int_hexagon_F2_sfcmpgt :
-Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpgt">;
-
-def int_hexagon_M4_vpmpyh :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M4_vpmpyh">;
-
-def int_hexagon_M2_mmacuhs_rs0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_rs0">;
-
-def int_hexagon_M2_mpyd_rnd_lh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s1">;
-
-def int_hexagon_M2_mpyd_rnd_lh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s0">;
-
-def int_hexagon_A2_roundsat :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_A2_roundsat">;
-
-def int_hexagon_S2_ct1p :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_ct1p">;
-
-def int_hexagon_S4_extract_rp :
-Hexagon_i32_i32i64_Intrinsic<"HEXAGON_S4_extract_rp">;
-
-def int_hexagon_S2_lsl_r_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_or">;
-
-def int_hexagon_C4_cmplteui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteui", [ImmArg<1>]>;
-
-def int_hexagon_S4_addi_lsr_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_lsr_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_A4_tfrcpp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A4_tfrcpp">;
-
-def int_hexagon_S2_asr_i_svw_trun :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_i_svw_trun", [ImmArg<1>]>;
-
-def int_hexagon_A4_cmphgti :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgti", [ImmArg<1>]>;
-
-def int_hexagon_A4_vrminh :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminh">;
-
-def int_hexagon_A4_vrminw :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminw">;
-
-def int_hexagon_A4_cmphgtu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtu">;
-
-def int_hexagon_S2_insertp_rp :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_S2_insertp_rp">;
-
-def int_hexagon_A2_vnavghcr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavghcr">;
-
-def int_hexagon_S4_subi_asl_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_asl_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_S2_lsl_r_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vh">;
-
-def int_hexagon_M2_mpy_hh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hh_s0">;
-
-def int_hexagon_A2_vsubws :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubws">;
-
-def int_hexagon_A2_sath :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sath">;
-
-def int_hexagon_S2_asl_r_p_xor :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_xor">;
-
-def int_hexagon_A2_satb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satb">;
-
-def int_hexagon_C2_cmpltu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpltu">;
-
-def int_hexagon_S2_insertp :
-Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S2_insertp", [ImmArg<2>, ImmArg<3>]>;
-
-def int_hexagon_M2_mpyd_rnd_ll_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s1">;
-
-def int_hexagon_M2_mpyd_rnd_ll_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s0">;
-
-def int_hexagon_S2_lsr_i_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_nac", [ImmArg<2>]>;
-
-def int_hexagon_S2_extractup_rp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_extractup_rp">;
-
-def int_hexagon_S4_vxaddsubw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubw">;
-
-def int_hexagon_S4_vxaddsubh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubh">;
-
-def int_hexagon_A2_asrh :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_asrh">;
-
-def int_hexagon_S4_extractp_rp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_extractp_rp">;
-
-def int_hexagon_S2_lsr_r_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_acc">;
-
-def int_hexagon_M2_mpyd_nac_ll_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s1">;
-
-def int_hexagon_M2_mpyd_nac_ll_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s0">;
-
-def int_hexagon_C2_or :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_or">;
-
-def int_hexagon_M2_mmpyul_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_s1">;
-
-def int_hexagon_M2_vrcmacr_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmacr_s0">;
-
-def int_hexagon_A2_xor :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_xor">;
-
-def int_hexagon_A2_add :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_add">;
-
-def int_hexagon_A2_vsububs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsububs">;
-
-def int_hexagon_M2_vmpy2s_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s1">;
-
-def int_hexagon_M2_vmpy2s_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s0">;
-
-def int_hexagon_A2_vraddub_acc :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_A2_vraddub_acc">;
-
-def int_hexagon_F2_sfinvsqrta :
-Hexagon_floati32_float_Intrinsic<"HEXAGON_F2_sfinvsqrta">;
-
-def int_hexagon_S2_ct0p :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_ct0p">;
-
-def int_hexagon_A2_svaddh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svaddh">;
-
-def int_hexagon_S2_vcrotate :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_vcrotate">;
-
-def int_hexagon_A2_aslh :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_aslh">;
-
-def int_hexagon_A2_subh_h16_lh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_lh">;
-
-def int_hexagon_A2_subh_h16_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_ll">;
-
-def int_hexagon_M2_hmmpyl_rs1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyl_rs1">;
-
-def int_hexagon_S2_asr_r_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_p">;
-
-def int_hexagon_S2_vsplatrh :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsplatrh">;
-
-def int_hexagon_S2_asr_r_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_r_r">;
-
-def int_hexagon_A2_addh_h16_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_hl">;
-
-def int_hexagon_S2_vsplatrb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_vsplatrb">;
-
-def int_hexagon_A2_addh_h16_hh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_hh">;
-
-def int_hexagon_M2_cmpyr_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpyr_s0">;
-
-def int_hexagon_M2_dpmpyss_rnd_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_rnd_s0">;
-
-def int_hexagon_C2_muxri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxri", [ImmArg<1>]>;
-
-def int_hexagon_M2_vmac2es_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es_s0">;
-
-def int_hexagon_M2_vmac2es_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es_s1">;
-
-def int_hexagon_C2_pxfer_map :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_pxfer_map">;
-
-def int_hexagon_M2_mpyu_lh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_lh_s1">;
-
-def int_hexagon_M2_mpyu_lh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_lh_s0">;
-
-def int_hexagon_S2_asl_i_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_or", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpyd_acc_hl_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s0">;
-
-def int_hexagon_M2_mpyd_acc_hl_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s1">;
-
-def int_hexagon_S2_asr_r_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_nac">;
-
-def int_hexagon_A2_vaddw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddw">;
-
-def int_hexagon_S2_asr_i_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_and", [ImmArg<2>]>;
-
-def int_hexagon_A2_vaddh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddh">;
-
-def int_hexagon_M2_mpy_nac_sat_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s1">;
-
-def int_hexagon_M2_mpy_nac_sat_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s0">;
-
-def int_hexagon_C2_cmpeqp :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpeqp">;
-
-def int_hexagon_M4_mpyri_addi :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addi", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_A2_not :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_not">;
-
-def int_hexagon_S4_andi_lsr_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_lsr_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_M2_macsip :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsip", [ImmArg<2>]>;
-
-def int_hexagon_A2_tfrcrr :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrcrr">;
-
-def int_hexagon_M2_macsin :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsin", [ImmArg<2>]>;
-
-def int_hexagon_C2_orn :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_orn">;
-
-def int_hexagon_M4_and_andn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_andn">;
-
-def int_hexagon_F2_sfmpy :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmpy">;
-
-def int_hexagon_M2_mpyud_nac_hh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s1">;
-
-def int_hexagon_M2_mpyud_nac_hh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s0">;
-
-def int_hexagon_S2_lsr_r_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_acc">;
-
-def int_hexagon_S2_asr_r_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_vw">;
-
-def int_hexagon_M4_and_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_or">;
-
-def int_hexagon_S2_asr_r_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_vh">;
-
-def int_hexagon_C2_mask :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_C2_mask">;
-
-def int_hexagon_M2_mpy_nac_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s0">;
-
-def int_hexagon_M2_mpy_nac_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s1">;
-
-def int_hexagon_M2_mpy_up_s1_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up_s1_sat">;
-
-def int_hexagon_A4_vcmpbgt :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A4_vcmpbgt">;
-
-def int_hexagon_M5_vrmacbsu :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vrmacbsu">;
-
-def int_hexagon_S2_tableidxw_goodsyntax :
-Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxw_goodsyntax">;
-
-def int_hexagon_A2_vrsadub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vrsadub">;
-
-def int_hexagon_A2_tfrrcr :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrrcr">;
-
-def int_hexagon_M2_vrcmpys_acc_s1 :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_acc_s1">;
-
-def int_hexagon_F2_dfcmpge :
-Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpge">;
-
-def int_hexagon_M2_accii :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_accii", [ImmArg<2>]>;
-
-def int_hexagon_A5_vaddhubs :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A5_vaddhubs">;
-
-def int_hexagon_A2_vmaxw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxw">;
-
-def int_hexagon_A2_vmaxb :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxb">;
-
-def int_hexagon_A2_vmaxh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxh">;
-
-def int_hexagon_S2_vsxthw :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsxthw">;
-
-def int_hexagon_S4_andi_asl_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_asl_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_S2_asl_i_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_nac", [ImmArg<2>]>;
-
-def int_hexagon_S2_lsl_r_p_xor :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_xor">;
-
-def int_hexagon_C2_cmpgt :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgt">;
-
-def int_hexagon_F2_conv_df2d_chop :
-Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2d_chop">;
-
-def int_hexagon_M2_mpyu_nac_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s0">;
-
-def int_hexagon_M2_mpyu_nac_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s1">;
-
-def int_hexagon_F2_conv_sf2w :
-Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2w">;
-
-def int_hexagon_S2_lsr_r_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_or">;
-
-def int_hexagon_F2_sfclass :
-Hexagon_i32_floati32_Intrinsic<"HEXAGON_F2_sfclass">;
-
-def int_hexagon_M2_mpyud_acc_lh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s0">;
-
-def int_hexagon_M4_xor_andn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_andn">;
-
-def int_hexagon_S2_addasl_rrri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_addasl_rrri", [ImmArg<2>]>;
-
-def int_hexagon_M5_vdmpybsu :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vdmpybsu">;
-
-def int_hexagon_M2_mpyu_nac_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s0">;
-
-def int_hexagon_M2_mpyu_nac_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s1">;
-
-def int_hexagon_A2_addi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addi", [ImmArg<1>]>;
-
-def int_hexagon_A2_addp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addp">;
-
-def int_hexagon_M2_vmpy2s_s1pack :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s1pack">;
-
-def int_hexagon_S4_clbpnorm :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S4_clbpnorm">;
-
-def int_hexagon_A4_round_rr_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_rr_sat">;
-
-def int_hexagon_M2_nacci :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_nacci">;
-
-def int_hexagon_S2_shuffeh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffeh">;
-
-def int_hexagon_S2_lsr_i_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_and", [ImmArg<2>]>;
-
-def int_hexagon_M2_mpy_sat_rnd_hh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s1">;
-
-def int_hexagon_M2_mpy_sat_rnd_hh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s0">;
-
-def int_hexagon_F2_conv_sf2uw :
-Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2uw">;
-
-def int_hexagon_A2_vsubh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubh">;
-
-def int_hexagon_F2_conv_sf2ud :
-Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2ud">;
-
-def int_hexagon_A2_vsubw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubw">;
-
-def int_hexagon_A2_vcmpwgt :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpwgt">;
-
-def int_hexagon_M4_xor_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_or">;
-
-def int_hexagon_F2_conv_sf2uw_chop :
-Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2uw_chop">;
-
-def int_hexagon_S2_asl_r_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_vw">;
-
-def int_hexagon_S2_vsatwuh_nopack :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsatwuh_nopack">;
-
-def int_hexagon_S2_asl_r_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_vh">;
-
-def int_hexagon_A2_svsubuhs :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubuhs">;
-
-def int_hexagon_M5_vmpybsu :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M5_vmpybsu">;
-
-def int_hexagon_A2_subh_l16_sat_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_sat_ll">;
-
-def int_hexagon_C4_and_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_and">;
-
-def int_hexagon_M2_mpyu_acc_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s1">;
-
-def int_hexagon_M2_mpyu_acc_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s0">;
-
-def int_hexagon_S2_lsr_r_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p">;
-
-def int_hexagon_S2_lsr_r_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r">;
-
-def int_hexagon_A4_subp_c :
-Hexagon_i64i32_i64i64i32_Intrinsic<"HEXAGON_A4_subp_c">;
-
-def int_hexagon_A2_vsubhs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubhs">;
-
-def int_hexagon_C2_vitpack :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_vitpack">;
-
-def int_hexagon_A2_vavguhr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguhr">;
-
-def int_hexagon_S2_vsplicerb :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vsplicerb">;
-
-def int_hexagon_C4_nbitsclr :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclr">;
-
-def int_hexagon_A2_vcmpbgtu :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
-
-def int_hexagon_M2_cmpys_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpys_s1">;
-
-def int_hexagon_M2_cmpys_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpys_s0">;
-
-def int_hexagon_F2_dfcmpuo :
-Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpuo">;
-
-def int_hexagon_S2_shuffob :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffob">;
-
-def int_hexagon_C2_and :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_and">;
-
-def int_hexagon_S5_popcountp :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S5_popcountp">;
-
-def int_hexagon_S4_extractp :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_extractp", [ImmArg<1>, ImmArg<2>]>;
-
-def int_hexagon_S2_cl0 :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_cl0">;
-
-def int_hexagon_A4_vcmpbgti :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgti", [ImmArg<1>]>;
-
-def int_hexagon_M2_mmacls_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_s1">;
-
-def int_hexagon_M2_mmacls_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_s0">;
-
-def int_hexagon_C4_cmpneq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneq">;
-
-def int_hexagon_M2_vmac2es :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es">;
-
-def int_hexagon_M2_vdmacs_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vdmacs_s0">;
-
-def int_hexagon_M2_vdmacs_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vdmacs_s1">;
-
-def int_hexagon_M2_mpyud_ll_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_ll_s0">;
-
-def int_hexagon_M2_mpyud_ll_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_ll_s1">;
-
-def int_hexagon_S2_clb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_clb">;
-
-def int_hexagon_M2_mpy_nac_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s0">;
-
-def int_hexagon_M2_mpy_nac_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s1">;
-
-def int_hexagon_M2_mpyd_nac_hl_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s1">;
-
-def int_hexagon_M2_mpyd_nac_hl_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s0">;
-
-def int_hexagon_M2_maci :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_maci">;
-
-def int_hexagon_A2_vmaxuh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxuh">;
-
-def int_hexagon_A4_bitspliti :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitspliti", [ImmArg<1>]>;
-
-def int_hexagon_A2_vmaxub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxub">;
-
-def int_hexagon_M2_mpyud_hh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hh_s0">;
-
-def int_hexagon_M2_mpyud_hh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hh_s1">;
-
-def int_hexagon_M2_vrmac_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrmac_s0">;
-
-def int_hexagon_M2_mpy_sat_lh_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s0">;
-
-def int_hexagon_S2_asl_r_r_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_sat">;
-
-def int_hexagon_F2_conv_sf2d :
-Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2d">;
-
-def int_hexagon_S2_asr_r_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_nac">;
-
-def int_hexagon_F2_dfimm_n :
-Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_n", [ImmArg<0>]>;
-
-def int_hexagon_A4_cmphgt :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgt">;
-
-def int_hexagon_F2_dfimm_p :
-Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_p", [ImmArg<0>]>;
-
-def int_hexagon_M2_mpyud_acc_lh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s1">;
-
-def int_hexagon_M2_vcmpy_s1_sat_r :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_r">;
-
-def int_hexagon_M4_mpyri_addr_u2 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr_u2", [ImmArg<1>]>;
-
-def int_hexagon_M2_vcmpy_s1_sat_i :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_i">;
-
-def int_hexagon_S2_lsl_r_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_nac">;
-
-def int_hexagon_M5_vrmacbuu :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vrmacbuu">;
-
-def int_hexagon_S5_asrhub_rnd_sat_goodsyntax :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax", [ImmArg<1>]>;
-
-def int_hexagon_S2_vspliceib :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vspliceib", [ImmArg<2>]>;
-
-def int_hexagon_M2_dpmpyss_acc_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_acc_s0">;
-
-def int_hexagon_M2_cnacs_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacs_s1">;
-
-def int_hexagon_M2_cnacs_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacs_s0">;
-
-def int_hexagon_A2_maxu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_maxu">;
-
-def int_hexagon_A2_maxp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxp">;
-
-def int_hexagon_A2_andir :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_andir", [ImmArg<1>]>;
-
-def int_hexagon_F2_sfrecipa :
-Hexagon_floati32_floatfloat_Intrinsic<"HEXAGON_F2_sfrecipa">;
-
-def int_hexagon_A2_combineii :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combineii", [ImmArg<0>, ImmArg<1>]>;
-
-def int_hexagon_A4_orn :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_orn">;
-
-def int_hexagon_A4_cmpbgtui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtui", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_r_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_or">;
-
-def int_hexagon_A4_vcmpbeqi :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbeqi", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsl_r_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r">;
-
-def int_hexagon_S2_lsl_r_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p">;
-
-def int_hexagon_A2_or :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_or">;
-
-def int_hexagon_F2_dfcmpeq :
-Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpeq">;
-
-def int_hexagon_C2_cmpeq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeq">;
-
-def int_hexagon_A2_tfrp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_tfrp">;
-
-def int_hexagon_C4_and_andn :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_andn">;
-
-def int_hexagon_S2_vsathub_nopack :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsathub_nopack">;
-
-def int_hexagon_A2_satuh :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satuh">;
-
-def int_hexagon_A2_satub :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satub">;
-
-def int_hexagon_M2_vrcmpys_s1 :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_s1">;
-
-def int_hexagon_S4_or_ori :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_ori", [ImmArg<2>]>;
-
-def int_hexagon_C4_fastcorner9_not :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
-
-def int_hexagon_A2_tfrih :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfrih", [ImmArg<1>]>;
-
-def int_hexagon_A2_tfril :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfril", [ImmArg<1>]>;
-
-def int_hexagon_M4_mpyri_addr :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr", [ImmArg<2>]>;
-
-def int_hexagon_S2_vtrunehb :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vtrunehb">;
-
-def int_hexagon_A2_vabsw :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabsw">;
-
-def int_hexagon_A2_vabsh :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabsh">;
-
-def int_hexagon_F2_sfsub :
-Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfsub">;
-
-def int_hexagon_C2_muxii :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxii", [ImmArg<1>, ImmArg<2>]>;
-
-def int_hexagon_C2_muxir :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxir", [ImmArg<2>]>;
-
-def int_hexagon_A2_swiz :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_swiz">;
-
-def int_hexagon_S2_asr_i_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_and", [ImmArg<2>]>;
-
-def int_hexagon_M2_cmpyrsc_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrsc_s0">;
-
-def int_hexagon_M2_cmpyrsc_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrsc_s1">;
-
-def int_hexagon_A2_vraddub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vraddub">;
-
-def int_hexagon_A4_tlbmatch :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_tlbmatch">;
-
-def int_hexagon_F2_conv_df2w_chop :
-Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2w_chop">;
-
-def int_hexagon_A2_and :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_and">;
-
-def int_hexagon_S2_lsr_r_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_and">;
-
-def int_hexagon_M2_mpy_nac_sat_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s1">;
-
-def int_hexagon_M2_mpy_nac_sat_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s0">;
-
-def int_hexagon_S4_extract :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_extract", [ImmArg<1>, ImmArg<2>]>;
-
-def int_hexagon_A2_vcmpweq :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpweq">;
-
-def int_hexagon_M2_acci :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_acci">;
-
-def int_hexagon_S2_lsr_i_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_acc", [ImmArg<2>]>;
-
-def int_hexagon_S2_lsr_i_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_or", [ImmArg<2>]>;
-
-def int_hexagon_F2_conv_ud2sf :
-Hexagon_float_i64_Intrinsic<"HEXAGON_F2_conv_ud2sf">;
-
-def int_hexagon_A2_tfr :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfr">;
-
-def int_hexagon_S2_asr_i_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_or", [ImmArg<2>]>;
-
-def int_hexagon_A2_subri :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subri", [ImmArg<0>]>;
-
-def int_hexagon_A4_vrmaxuw :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuw">;
-
-def int_hexagon_M5_vmpybuu :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M5_vmpybuu">;
-
-def int_hexagon_A4_vrmaxuh :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuh">;
-
-def int_hexagon_S2_asl_i_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vw", [ImmArg<1>]>;
-
-def int_hexagon_A2_vavgw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgw">;
-
-def int_hexagon_S2_brev :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_brev">;
-
-def int_hexagon_A2_vavgh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgh">;
-
-def int_hexagon_S2_clrbit_i :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_i", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vh", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_i_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_or", [ImmArg<2>]>;
-
-def int_hexagon_S2_lsl_r_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_nac">;
-
-def int_hexagon_M2_mmpyl_rs1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_rs1">;
-
-def int_hexagon_M2_mpyud_hl_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hl_s1">;
-
-def int_hexagon_M2_mmpyl_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_s0">;
-
-def int_hexagon_M2_mmpyl_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_s1">;
-
-def int_hexagon_M2_naccii :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_naccii", [ImmArg<2>]>;
-
-def int_hexagon_S2_vrndpackwhs :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vrndpackwhs">;
-
-def int_hexagon_S2_vtrunewh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_vtrunewh">;
-
-def int_hexagon_M2_dpmpyss_nac_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_nac_s0">;
-
-def int_hexagon_M2_mpyd_ll_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_ll_s0">;
-
-def int_hexagon_M2_mpyd_ll_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_ll_s1">;
-
-def int_hexagon_M4_mac_up_s1_sat :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mac_up_s1_sat">;
-
-def int_hexagon_S4_vrcrotate_acc :
-Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate_acc", [ImmArg<3>]>;
-
-def int_hexagon_F2_conv_uw2df :
-Hexagon_double_i32_Intrinsic<"HEXAGON_F2_conv_uw2df">;
-
-def int_hexagon_A2_vaddubs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddubs">;
-
-def int_hexagon_S2_asr_r_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_acc">;
-
-def int_hexagon_A2_orir :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_orir", [ImmArg<1>]>;
-
-def int_hexagon_A2_andp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_andp">;
-
-def int_hexagon_S2_lfsp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_lfsp">;
-
-def int_hexagon_A2_min :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_min">;
-
-def int_hexagon_M2_mpysmi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysmi", [ImmArg<1>]>;
-
-def int_hexagon_M2_vcmpy_s0_sat_r :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_r">;
-
-def int_hexagon_M2_mpyu_acc_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s1">;
-
-def int_hexagon_M2_mpyu_acc_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s0">;
-
-def int_hexagon_S2_asr_r_svw_trun :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_r_svw_trun">;
-
-def int_hexagon_M2_mmpyh_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_s0">;
-
-def int_hexagon_M2_mmpyh_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_s1">;
-
-def int_hexagon_F2_conv_sf2df :
-Hexagon_double_float_Intrinsic<"HEXAGON_F2_conv_sf2df">;
-
-def int_hexagon_S2_vtrunohb :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vtrunohb">;
-
-def int_hexagon_F2_conv_sf2d_chop :
-Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2d_chop">;
-
-def int_hexagon_M2_mpyd_lh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_lh_s0">;
-
-def int_hexagon_F2_conv_df2w :
-Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2w">;
-
-def int_hexagon_S5_asrhub_sat :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_sat", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_r_xacc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_xacc", [ImmArg<2>]>;
-
-def int_hexagon_F2_conv_df2d :
-Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2d">;
-
-def int_hexagon_M2_mmaculs_s1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_s1">;
-
-def int_hexagon_M2_mmaculs_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_s0">;
-
-def int_hexagon_A2_svadduhs :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svadduhs">;
-
-def int_hexagon_F2_conv_sf2w_chop :
-Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2w_chop">;
-
-def int_hexagon_S2_svsathub :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_svsathub">;
-
-def int_hexagon_M2_mpyd_rnd_hl_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s1">;
-
-def int_hexagon_M2_mpyd_rnd_hl_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s0">;
-
-def int_hexagon_S2_setbit_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_r">;
-
-def int_hexagon_A2_vavghr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavghr">;
-
-def int_hexagon_F2_sffma_sc :
-Hexagon_float_floatfloatfloati32_Intrinsic<"HEXAGON_F2_sffma_sc">;
-
-def int_hexagon_F2_dfclass :
-Hexagon_i32_doublei32_Intrinsic<"HEXAGON_F2_dfclass", [ImmArg<1>]>;
-
-def int_hexagon_F2_conv_df2ud :
-Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2ud">;
-
-def int_hexagon_F2_conv_df2uw :
-Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2uw">;
-
-def int_hexagon_M2_cmpyrs_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrs_s0">;
-
-def int_hexagon_M2_cmpyrs_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrs_s1">;
-
-def int_hexagon_C4_cmpltei :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpltei", [ImmArg<1>]>;
-
-def int_hexagon_C4_cmplteu :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteu">;
-
-def int_hexagon_A2_vsubb_map :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubb_map">;
-
-def int_hexagon_A2_subh_l16_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_ll">;
-
-def int_hexagon_S2_asr_i_r_rnd :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd", [ImmArg<1>]>;
-
-def int_hexagon_M2_vrmpy_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrmpy_s0">;
-
-def int_hexagon_M2_mpyd_rnd_hh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s1">;
-
-def int_hexagon_M2_mpyd_rnd_hh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s0">;
-
-def int_hexagon_A2_minup :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_minup">;
-
-def int_hexagon_S2_valignrb :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignrb">;
-
-def int_hexagon_S2_asr_r_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_acc">;
-
-def int_hexagon_M2_mmpyl_rs0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_rs0">;
-
-def int_hexagon_M2_vrcmaci_s0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmaci_s0">;
-
-def int_hexagon_A2_vaddub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddub">;
-
-def int_hexagon_A2_combine_lh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_lh">;
-
-def int_hexagon_M5_vdmacbsu :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vdmacbsu">;
-
-def int_hexagon_A2_combine_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_ll">;
-
-def int_hexagon_M2_mpyud_hl_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hl_s0">;
-
-def int_hexagon_M2_vrcmpyi_s0c :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyi_s0c">;
-
-def int_hexagon_S2_asr_i_p_rnd :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd", [ImmArg<1>]>;
-
-def int_hexagon_A2_addpsat :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addpsat">;
-
-def int_hexagon_A2_svaddhs :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svaddhs">;
-
-def int_hexagon_S4_ori_lsr_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_lsr_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_M2_mpy_sat_rnd_ll_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s1">;
-
-def int_hexagon_M2_mpy_sat_rnd_ll_s0 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s0">;
-
-def int_hexagon_A2_vminw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminw">;
-
-def int_hexagon_A2_vminh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminh">;
-
-def int_hexagon_M2_vrcmpyr_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyr_s0">;
-
-def int_hexagon_A2_vminb :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminb">;
-
-def int_hexagon_M2_vcmac_s0_sat_i :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_i">;
-
-def int_hexagon_M2_mpyud_lh_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_lh_s0">;
-
-def int_hexagon_M2_mpyud_lh_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_lh_s1">;
-
-def int_hexagon_S2_asl_r_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_or">;
-
-def int_hexagon_S4_lsli :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_lsli", [ImmArg<0>]>;
-
-def int_hexagon_S2_lsl_r_vw :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vw">;
-
-def int_hexagon_M2_mpy_hh_s1 :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hh_s1">;
-
-def int_hexagon_M4_vrmpyeh_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_s0">;
-
-def int_hexagon_M4_vrmpyeh_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_s1">;
-
-def int_hexagon_M2_mpy_nac_lh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s0">;
-
-def int_hexagon_M2_mpy_nac_lh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s1">;
-
-def int_hexagon_M2_vraddh :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vraddh">;
-
-def int_hexagon_C2_tfrrp :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_tfrrp">;
-
-def int_hexagon_M2_mpy_acc_sat_ll_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s0">;
-
-def int_hexagon_M2_mpy_acc_sat_ll_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s1">;
-
-def int_hexagon_S2_vtrunowh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_vtrunowh">;
-
-def int_hexagon_A2_abs :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_abs">;
-
-def int_hexagon_A4_cmpbeq :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeq">;
-
-def int_hexagon_A2_negp :
-Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_negp">;
-
-def int_hexagon_S2_asl_i_r_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_sat", [ImmArg<1>]>;
-
-def int_hexagon_A2_addh_l16_sat_hl :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_sat_hl">;
-
-def int_hexagon_S2_vsatwuh :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsatwuh">;
-
-def int_hexagon_F2_dfcmpgt :
-Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpgt">;
-
-def int_hexagon_S2_svsathb :
-Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_svsathb">;
-
-def int_hexagon_C2_cmpgtup :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtup">;
-
-def int_hexagon_A4_cround_ri :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_ri", [ImmArg<1>]>;
-
-def int_hexagon_S4_clbpaddi :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S4_clbpaddi", [ImmArg<1>]>;
-
-def int_hexagon_A4_cround_rr :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_rr">;
-
-def int_hexagon_C2_mux :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_mux">;
-
-def int_hexagon_M2_dpmpyuu_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_s0">;
-
-def int_hexagon_S2_shuffeb :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffeb">;
-
-def int_hexagon_A2_vminuw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminuw">;
-
-def int_hexagon_A2_vaddhs :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddhs">;
-
-def int_hexagon_S2_insert_rp :
-Hexagon_i32_i32i32i64_Intrinsic<"HEXAGON_S2_insert_rp">;
-
-def int_hexagon_A2_vminuh :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminuh">;
-
-def int_hexagon_A2_vminub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminub">;
-
-def int_hexagon_S2_extractu :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_extractu", [ImmArg<1>, ImmArg<2>]>;
-
-def int_hexagon_A2_svsubh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubh">;
-
-def int_hexagon_S4_clbaddi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_clbaddi", [ImmArg<1>]>;
-
-def int_hexagon_F2_sffms :
-Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms">;
-
-def int_hexagon_S2_vsxtbh :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsxtbh">;
-
-def int_hexagon_M2_mpyud_nac_ll_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s1">;
-
-def int_hexagon_M2_mpyud_nac_ll_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s0">;
-
-def int_hexagon_A2_subp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_subp">;
-
-def int_hexagon_M2_vmpy2es_s1 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vmpy2es_s1">;
-
-def int_hexagon_M2_vmpy2es_s0 :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vmpy2es_s0">;
-
-def int_hexagon_S4_parity :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_parity">;
-
-def int_hexagon_M2_mpy_acc_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s1">;
-
-def int_hexagon_M2_mpy_acc_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s0">;
-
-def int_hexagon_S4_addi_asl_ri :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_asl_ri", [ImmArg<0>, ImmArg<2>]>;
-
-def int_hexagon_M2_mpyd_nac_hh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s1">;
-
-def int_hexagon_M2_mpyd_nac_hh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s0">;
-
-def int_hexagon_S2_asr_i_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_nac", [ImmArg<2>]>;
-
-def int_hexagon_A4_cmpheqi :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheqi", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_r_p_xor :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_xor">;
-
-def int_hexagon_M2_mpy_acc_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s1">;
-
-def int_hexagon_M2_mpy_acc_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s0">;
-
-def int_hexagon_F2_conv_sf2ud_chop :
-Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2ud_chop">;
-
-def int_hexagon_C2_cmpgeui :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgeui", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpy_acc_sat_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s0">;
-
-def int_hexagon_M2_mpy_acc_sat_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s1">;
-
-def int_hexagon_S2_asl_r_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_and">;
-
-def int_hexagon_A2_addh_h16_sat_lh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_lh">;
-
-def int_hexagon_A2_addh_h16_sat_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_ll">;
-
-def int_hexagon_M4_nac_up_s1_sat :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_nac_up_s1_sat">;
-
-def int_hexagon_M2_mpyud_nac_lh_s1 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s1">;
-
-def int_hexagon_M2_mpyud_nac_lh_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s0">;
-
-def int_hexagon_A4_round_ri_sat :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri_sat", [ImmArg<1>]>;
-
-def int_hexagon_M2_mpy_nac_hl_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s0">;
-
-def int_hexagon_M2_mpy_nac_hl_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s1">;
-
-def int_hexagon_A2_vavghcr :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavghcr">;
-
-def int_hexagon_M2_mmacls_rs0 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_rs0">;
-
-def int_hexagon_M2_mmacls_rs1 :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_rs1">;
-
-def int_hexagon_M2_cmaci_s0 :
-Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmaci_s0">;
-
-def int_hexagon_S2_setbit_i :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_i", [ImmArg<1>]>;
-
-def int_hexagon_S2_asl_i_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_or", [ImmArg<2>]>;
-
-def int_hexagon_A4_andn :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_andn">;
-
-def int_hexagon_M5_vrmpybsu :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vrmpybsu">;
-
-def int_hexagon_S2_vrndpackwh :
-Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vrndpackwh">;
-
-def int_hexagon_M2_vcmac_s0_sat_r :
-Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_r">;
-
-def int_hexagon_A2_vmaxuw :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxuw">;
-
-def int_hexagon_C2_bitsclr :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclr">;
-
-def int_hexagon_M2_xor_xacc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_xor_xacc">;
-
-def int_hexagon_A4_vcmpbgtui :
-Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgtui", [ImmArg<1>]>;
-
-def int_hexagon_A4_ornp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A4_ornp">;
-
-def int_hexagon_A2_tfrpi :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_tfrpi", [ImmArg<0>]>;
-
-def int_hexagon_C4_and_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_or">;
-
-def int_hexagon_M2_mpy_nac_sat_hh_s1 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s1">;
-
-def int_hexagon_M2_mpy_nac_sat_hh_s0 :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s0">;
-
-def int_hexagon_A2_subh_h16_sat_ll :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_ll">;
-
-def int_hexagon_A2_subh_h16_sat_lh :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_lh">;
-
-def int_hexagon_M2_vmpy2su_s1 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2su_s1">;
-
-def int_hexagon_M2_vmpy2su_s0 :
-Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2su_s0">;
-
-def int_hexagon_S2_asr_i_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_acc", [ImmArg<2>]>;
-
-def int_hexagon_C4_nbitsclri :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclri", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_i_vh :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vh", [ImmArg<1>]>;
-
-def int_hexagon_S2_lsr_i_p_xacc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc", [ImmArg<2>]>;
-
-// V55 Scalar Instructions.
-
-def int_hexagon_A5_ACS :
-Hexagon_i64i32_i64i64i64_Intrinsic<"HEXAGON_A5_ACS">;
-
-// V60 Scalar Instructions.
-
-def int_hexagon_S6_rol_i_p_and :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_and", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_r_xacc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_xacc", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_r_and :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_and", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_r_acc :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_acc", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_p_xacc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_xacc", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_p :
-Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S6_rol_i_p", [ImmArg<1>]>;
-
-def int_hexagon_S6_rol_i_p_nac :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_nac", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_p_acc :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_acc", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_r_or :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_or", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_r :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S6_rol_i_r", [ImmArg<1>]>;
-
-def int_hexagon_S6_rol_i_r_nac :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_nac", [ImmArg<2>]>;
-
-def int_hexagon_S6_rol_i_p_or :
-Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_or", [ImmArg<2>]>;
-
-// V62 Scalar Instructions.
-
-def int_hexagon_S6_vtrunehb_ppp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S6_vtrunehb_ppp">;
-
-def int_hexagon_V6_ldntnt0 :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_ldntnt0">;
-
-def int_hexagon_M6_vabsdiffub :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M6_vabsdiffub">;
-
-def int_hexagon_S6_vtrunohb_ppp :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S6_vtrunohb_ppp">;
-
-def int_hexagon_M6_vabsdiffb :
-Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M6_vabsdiffb">;
-
-def int_hexagon_A6_vminub_RdP :
-Hexagon_i64i32_i64i64_Intrinsic<"HEXAGON_A6_vminub_RdP">;
-
-def int_hexagon_S6_vsplatrbp :
-Hexagon_i64_i32_Intrinsic<"HEXAGON_S6_vsplatrbp">;
-
-// V65 Scalar Instructions.
-
-def int_hexagon_A6_vcmpbeq_notany :
-Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A6_vcmpbeq_notany">;
-
-// V66 Scalar Instructions.
-
-def int_hexagon_F2_dfsub :
-Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfsub">;
-
-def int_hexagon_F2_dfadd :
-Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfadd">;
-
-def int_hexagon_M2_mnaci :
-Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mnaci">;
-
-def int_hexagon_S2_mask :
-Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_mask", [ImmArg<0>, ImmArg<1>]>;
-
-// V60 HVX Instructions.
-
-def int_hexagon_V6_veqb_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqb_or">;
-
-def int_hexagon_V6_veqb_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqb_or_128B">;
-
-def int_hexagon_V6_vminub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminub">;
-
-def int_hexagon_V6_vminub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminub_128B">;
-
-def int_hexagon_V6_vaslw_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vaslw_acc">;
-
-def int_hexagon_V6_vaslw_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vaslw_acc_128B">;
-
-def int_hexagon_V6_vmpyhvsrs :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhvsrs">;
-
-def int_hexagon_V6_vmpyhvsrs_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhvsrs_128B">;
-
-def int_hexagon_V6_vsathub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsathub">;
-
-def int_hexagon_V6_vsathub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsathub_128B">;
-
-def int_hexagon_V6_vaddh_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddh_dv">;
-
-def int_hexagon_V6_vaddh_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddh_dv_128B">;
-
-def int_hexagon_V6_vrmpybusi :
-Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vrmpybusi_128B :
-Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vshufoh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoh">;
-
-def int_hexagon_V6_vshufoh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoh_128B">;
-
-def int_hexagon_V6_vasrwv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vasrwv">;
-
-def int_hexagon_V6_vasrwv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vasrwv_128B">;
-
-def int_hexagon_V6_vdmpyhsuisat :
-Hexagon_v16i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat">;
-
-def int_hexagon_V6_vdmpyhsuisat_128B :
-Hexagon_v32i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_128B">;
-
-def int_hexagon_V6_vrsadubi_acc :
-Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc", [ImmArg<3>]>;
-
-def int_hexagon_V6_vrsadubi_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc_128B", [ImmArg<3>]>;
-
-def int_hexagon_V6_vnavgw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgw">;
-
-def int_hexagon_V6_vnavgw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgw_128B">;
-
-def int_hexagon_V6_vnavgh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgh">;
-
-def int_hexagon_V6_vnavgh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgh_128B">;
-
-def int_hexagon_V6_vavgub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgub">;
-
-def int_hexagon_V6_vavgub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgub_128B">;
-
-def int_hexagon_V6_vsubb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubb">;
-
-def int_hexagon_V6_vsubb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubb_128B">;
-
-def int_hexagon_V6_vgtw_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtw_and">;
-
-def int_hexagon_V6_vgtw_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtw_and_128B">;
-
-def int_hexagon_V6_vavgubrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgubrnd">;
-
-def int_hexagon_V6_vavgubrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgubrnd_128B">;
-
-def int_hexagon_V6_vrmpybusv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybusv">;
-
-def int_hexagon_V6_vrmpybusv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybusv_128B">;
-
-def int_hexagon_V6_vsubbnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubbnq">;
-
-def int_hexagon_V6_vsubbnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbnq_128B">;
-
-def int_hexagon_V6_vroundhb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundhb">;
-
-def int_hexagon_V6_vroundhb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundhb_128B">;
-
-def int_hexagon_V6_vadduhsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhsat_dv">;
-
-def int_hexagon_V6_vadduhsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vadduhsat_dv_128B">;
-
-def int_hexagon_V6_vsububsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsububsat">;
-
-def int_hexagon_V6_vsububsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububsat_128B">;
-
-def int_hexagon_V6_vmpabus_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpabus_acc">;
-
-def int_hexagon_V6_vmpabus_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpabus_acc_128B">;
-
-def int_hexagon_V6_vmux :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vmux">;
-
-def int_hexagon_V6_vmux_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vmux_128B">;
-
-def int_hexagon_V6_vmpyhus :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhus">;
-
-def int_hexagon_V6_vmpyhus_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhus_128B">;
-
-def int_hexagon_V6_vpackeb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackeb">;
-
-def int_hexagon_V6_vpackeb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackeb_128B">;
-
-def int_hexagon_V6_vsubhnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhnq">;
-
-def int_hexagon_V6_vsubhnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhnq_128B">;
-
-def int_hexagon_V6_vavghrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavghrnd">;
-
-def int_hexagon_V6_vavghrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavghrnd_128B">;
-
-def int_hexagon_V6_vtran2x2_map :
-Hexagon_v16i32v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vtran2x2_map">;
-
-def int_hexagon_V6_vtran2x2_map_128B :
-Hexagon_v32i32v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtran2x2_map_128B">;
-
-def int_hexagon_V6_vdelta :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdelta">;
-
-def int_hexagon_V6_vdelta_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdelta_128B">;
-
-def int_hexagon_V6_vgtuh_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuh_and">;
-
-def int_hexagon_V6_vgtuh_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuh_and_128B">;
-
-def int_hexagon_V6_vtmpyhb :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb">;
-
-def int_hexagon_V6_vtmpyhb_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_128B">;
-
-def int_hexagon_V6_vpackob :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackob">;
-
-def int_hexagon_V6_vpackob_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackob_128B">;
-
-def int_hexagon_V6_vmaxh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxh">;
-
-def int_hexagon_V6_vmaxh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxh_128B">;
-
-def int_hexagon_V6_vtmpybus_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_acc">;
-
-def int_hexagon_V6_vtmpybus_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_acc_128B">;
-
-def int_hexagon_V6_vsubuhsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuhsat">;
-
-def int_hexagon_V6_vsubuhsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhsat_128B">;
-
-def int_hexagon_V6_vasrw_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrw_acc">;
-
-def int_hexagon_V6_vasrw_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrw_acc_128B">;
-
-def int_hexagon_V6_pred_or :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_pred_or">;
-
-def int_hexagon_V6_pred_or_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_pred_or_128B">;
-
-def int_hexagon_V6_vrmpyub_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_acc">;
-
-def int_hexagon_V6_vrmpyub_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_acc_128B">;
-
-def int_hexagon_V6_lo :
-Hexagon_v16i32_v32i32_Intrinsic<"HEXAGON_V6_lo">;
-
-def int_hexagon_V6_lo_128B :
-Hexagon_v32i32_v64i32_Intrinsic<"HEXAGON_V6_lo_128B">;
-
-def int_hexagon_V6_vsubb_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubb_dv">;
-
-def int_hexagon_V6_vsubb_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubb_dv_128B">;
-
-def int_hexagon_V6_vsubhsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhsat_dv">;
-
-def int_hexagon_V6_vsubhsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubhsat_dv_128B">;
-
-def int_hexagon_V6_vmpyiwh :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh">;
-
-def int_hexagon_V6_vmpyiwh_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_128B">;
-
-def int_hexagon_V6_vmpyiwb :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb">;
-
-def int_hexagon_V6_vmpyiwb_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_128B">;
-
-def int_hexagon_V6_ldu0 :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_ldu0">;
-
-def int_hexagon_V6_ldu0_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_ldu0_128B">;
-
-def int_hexagon_V6_vgtuh_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuh_xor">;
-
-def int_hexagon_V6_vgtuh_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuh_xor_128B">;
-
-def int_hexagon_V6_vgth_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgth_or">;
-
-def int_hexagon_V6_vgth_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgth_or_128B">;
-
-def int_hexagon_V6_vavgh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgh">;
-
-def int_hexagon_V6_vavgh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgh_128B">;
-
-def int_hexagon_V6_vlalignb :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignb">;
-
-def int_hexagon_V6_vlalignb_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignb_128B">;
-
-def int_hexagon_V6_vsh :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vsh">;
-
-def int_hexagon_V6_vsh_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vsh_128B">;
-
-def int_hexagon_V6_pred_and_n :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_pred_and_n">;
-
-def int_hexagon_V6_pred_and_n_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_pred_and_n_128B">;
-
-def int_hexagon_V6_vsb :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vsb">;
-
-def int_hexagon_V6_vsb_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vsb_128B">;
-
-def int_hexagon_V6_vroundwuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundwuh">;
-
-def int_hexagon_V6_vroundwuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundwuh_128B">;
-
-def int_hexagon_V6_vasrhv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vasrhv">;
-
-def int_hexagon_V6_vasrhv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vasrhv_128B">;
-
-def int_hexagon_V6_vshuffh :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vshuffh">;
-
-def int_hexagon_V6_vshuffh_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vshuffh_128B">;
-
-def int_hexagon_V6_vaddhsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhsat_dv">;
-
-def int_hexagon_V6_vaddhsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddhsat_dv_128B">;
-
-def int_hexagon_V6_vnavgub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgub">;
-
-def int_hexagon_V6_vnavgub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgub_128B">;
-
-def int_hexagon_V6_vrmpybv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybv">;
-
-def int_hexagon_V6_vrmpybv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybv_128B">;
-
-def int_hexagon_V6_vnormamth :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnormamth">;
-
-def int_hexagon_V6_vnormamth_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnormamth_128B">;
-
-def int_hexagon_V6_vdmpyhb :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb">;
-
-def int_hexagon_V6_vdmpyhb_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_128B">;
-
-def int_hexagon_V6_vavguh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguh">;
-
-def int_hexagon_V6_vavguh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguh_128B">;
-
-def int_hexagon_V6_vlsrwv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vlsrwv">;
-
-def int_hexagon_V6_vlsrwv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vlsrwv_128B">;
-
-def int_hexagon_V6_vlsrhv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vlsrhv">;
-
-def int_hexagon_V6_vlsrhv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vlsrhv_128B">;
-
-def int_hexagon_V6_vdmpyhisat :
-Hexagon_v16i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat">;
-
-def int_hexagon_V6_vdmpyhisat_128B :
-Hexagon_v32i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_128B">;
-
-def int_hexagon_V6_vdmpyhvsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat">;
-
-def int_hexagon_V6_vdmpyhvsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_128B">;
-
-def int_hexagon_V6_vaddw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddw">;
-
-def int_hexagon_V6_vaddw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddw_128B">;
-
-def int_hexagon_V6_vzh :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vzh">;
-
-def int_hexagon_V6_vzh_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vzh_128B">;
-
-def int_hexagon_V6_vaddh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddh">;
-
-def int_hexagon_V6_vaddh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddh_128B">;
-
-def int_hexagon_V6_vmaxub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxub">;
-
-def int_hexagon_V6_vmaxub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxub_128B">;
-
-def int_hexagon_V6_vmpyhv_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhv_acc">;
-
-def int_hexagon_V6_vmpyhv_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhv_acc_128B">;
-
-def int_hexagon_V6_vadduhsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhsat">;
-
-def int_hexagon_V6_vadduhsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhsat_128B">;
-
-def int_hexagon_V6_vshufoeh :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoeh">;
-
-def int_hexagon_V6_vshufoeh_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoeh_128B">;
-
-def int_hexagon_V6_vmpyuhv_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyuhv_acc">;
-
-def int_hexagon_V6_vmpyuhv_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyuhv_acc_128B">;
-
-def int_hexagon_V6_veqh :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_veqh">;
-
-def int_hexagon_V6_veqh_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_veqh_128B">;
-
-def int_hexagon_V6_vmpabuuv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpabuuv">;
-
-def int_hexagon_V6_vmpabuuv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vmpabuuv_128B">;
-
-def int_hexagon_V6_vasrwhsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwhsat">;
-
-def int_hexagon_V6_vasrwhsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwhsat_128B">;
-
-def int_hexagon_V6_vminuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminuh">;
-
-def int_hexagon_V6_vminuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminuh_128B">;
-
-def int_hexagon_V6_vror :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vror">;
-
-def int_hexagon_V6_vror_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vror_128B">;
-
-def int_hexagon_V6_vmpyowh_rnd_sacc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc">;
-
-def int_hexagon_V6_vmpyowh_rnd_sacc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc_128B">;
-
-def int_hexagon_V6_vmaxuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxuh">;
-
-def int_hexagon_V6_vmaxuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxuh_128B">;
-
-def int_hexagon_V6_vabsh_sat :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsh_sat">;
-
-def int_hexagon_V6_vabsh_sat_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsh_sat_128B">;
-
-def int_hexagon_V6_pred_or_n :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_pred_or_n">;
-
-def int_hexagon_V6_pred_or_n_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_pred_or_n_128B">;
-
-def int_hexagon_V6_vdealb :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vdealb">;
-
-def int_hexagon_V6_vdealb_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vdealb_128B">;
-
-def int_hexagon_V6_vmpybusv :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybusv">;
-
-def int_hexagon_V6_vmpybusv_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybusv_128B">;
-
-def int_hexagon_V6_vzb :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vzb">;
-
-def int_hexagon_V6_vzb_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vzb_128B">;
-
-def int_hexagon_V6_vdmpybus_dv :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv">;
-
-def int_hexagon_V6_vdmpybus_dv_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_128B">;
-
-def int_hexagon_V6_vaddbq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddbq">;
-
-def int_hexagon_V6_vaddbq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbq_128B">;
-
-def int_hexagon_V6_vaddb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddb">;
-
-def int_hexagon_V6_vaddb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddb_128B">;
-
-def int_hexagon_V6_vaddwq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddwq">;
-
-def int_hexagon_V6_vaddwq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwq_128B">;
-
-def int_hexagon_V6_vasrhubrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhubrndsat">;
-
-def int_hexagon_V6_vasrhubrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhubrndsat_128B">;
-
-def int_hexagon_V6_vasrhubsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhubsat">;
-
-def int_hexagon_V6_vasrhubsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhubsat_128B">;
-
-def int_hexagon_V6_vshufoeb :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoeb">;
-
-def int_hexagon_V6_vshufoeb_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoeb_128B">;
-
-def int_hexagon_V6_vpackhub_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackhub_sat">;
-
-def int_hexagon_V6_vpackhub_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackhub_sat_128B">;
-
-def int_hexagon_V6_vmpyiwh_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_acc">;
-
-def int_hexagon_V6_vmpyiwh_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_acc_128B">;
-
-def int_hexagon_V6_vtmpyb :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyb">;
-
-def int_hexagon_V6_vtmpyb_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_128B">;
-
-def int_hexagon_V6_vmpabusv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpabusv">;
-
-def int_hexagon_V6_vmpabusv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vmpabusv_128B">;
-
-def int_hexagon_V6_pred_and :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_pred_and">;
-
-def int_hexagon_V6_pred_and_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_pred_and_128B">;
-
-def int_hexagon_V6_vsubwnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubwnq">;
-
-def int_hexagon_V6_vsubwnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwnq_128B">;
-
-def int_hexagon_V6_vpackwuh_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackwuh_sat">;
-
-def int_hexagon_V6_vpackwuh_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackwuh_sat_128B">;
-
-def int_hexagon_V6_vswap :
-Hexagon_v32i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vswap">;
-
-def int_hexagon_V6_vswap_128B :
-Hexagon_v64i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vswap_128B">;
-
-def int_hexagon_V6_vrmpyubv_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpyubv_acc">;
-
-def int_hexagon_V6_vrmpyubv_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpyubv_acc_128B">;
-
-def int_hexagon_V6_vgtb_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtb_and">;
-
-def int_hexagon_V6_vgtb_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtb_and_128B">;
-
-def int_hexagon_V6_vaslw :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vaslw">;
-
-def int_hexagon_V6_vaslw_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vaslw_128B">;
-
-def int_hexagon_V6_vpackhb_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackhb_sat">;
-
-def int_hexagon_V6_vpackhb_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackhb_sat_128B">;
-
-def int_hexagon_V6_vmpyih_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyih_acc">;
-
-def int_hexagon_V6_vmpyih_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyih_acc_128B">;
-
-def int_hexagon_V6_vshuffvdd :
-Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vshuffvdd">;
-
-def int_hexagon_V6_vshuffvdd_128B :
-Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vshuffvdd_128B">;
-
-def int_hexagon_V6_vaddb_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddb_dv">;
-
-def int_hexagon_V6_vaddb_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddb_dv_128B">;
-
-def int_hexagon_V6_vunpackub :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackub">;
-
-def int_hexagon_V6_vunpackub_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackub_128B">;
-
-def int_hexagon_V6_vgtuw :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuw">;
-
-def int_hexagon_V6_vgtuw_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuw_128B">;
-
-def int_hexagon_V6_vlutvwh :
-Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh">;
-
-def int_hexagon_V6_vlutvwh_128B :
-Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_128B">;
-
-def int_hexagon_V6_vgtub :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtub">;
-
-def int_hexagon_V6_vgtub_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtub_128B">;
-
-def int_hexagon_V6_vmpyowh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh">;
-
-def int_hexagon_V6_vmpyowh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_128B">;
-
-def int_hexagon_V6_vmpyieoh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyieoh">;
-
-def int_hexagon_V6_vmpyieoh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyieoh_128B">;
-
-def int_hexagon_V6_extractw :
-Hexagon_i32_v16i32i32_Intrinsic<"HEXAGON_V6_extractw">;
-
-def int_hexagon_V6_extractw_128B :
-Hexagon_i32_v32i32i32_Intrinsic<"HEXAGON_V6_extractw_128B">;
-
-def int_hexagon_V6_vavgwrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgwrnd">;
-
-def int_hexagon_V6_vavgwrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgwrnd_128B">;
-
-def int_hexagon_V6_vdmpyhsat_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc">;
-
-def int_hexagon_V6_vdmpyhsat_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc_128B">;
-
-def int_hexagon_V6_vgtub_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtub_xor">;
-
-def int_hexagon_V6_vgtub_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtub_xor_128B">;
-
-def int_hexagon_V6_vmpyub :
-Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyub">;
-
-def int_hexagon_V6_vmpyub_128B :
-Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyub_128B">;
-
-def int_hexagon_V6_vmpyuh :
-Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuh">;
-
-def int_hexagon_V6_vmpyuh_128B :
-Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_128B">;
-
-def int_hexagon_V6_vunpackob :
-Hexagon_v32i32_v32i32v16i32_Intrinsic<"HEXAGON_V6_vunpackob">;
-
-def int_hexagon_V6_vunpackob_128B :
-Hexagon_v64i32_v64i32v32i32_Intrinsic<"HEXAGON_V6_vunpackob_128B">;
-
-def int_hexagon_V6_vmpahb :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpahb">;
-
-def int_hexagon_V6_vmpahb_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpahb_128B">;
-
-def int_hexagon_V6_veqw_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqw_or">;
-
-def int_hexagon_V6_veqw_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqw_or_128B">;
-
-def int_hexagon_V6_vandqrt :
-Hexagon_v16i32_v512i1i32_Intrinsic<"HEXAGON_V6_vandqrt">;
-
-def int_hexagon_V6_vandqrt_128B :
-Hexagon_v32i32_v1024i1i32_Intrinsic<"HEXAGON_V6_vandqrt_128B">;
-
-def int_hexagon_V6_vxor :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vxor">;
-
-def int_hexagon_V6_vxor_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vxor_128B">;
-
-def int_hexagon_V6_vasrwhrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwhrndsat">;
-
-def int_hexagon_V6_vasrwhrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwhrndsat_128B">;
-
-def int_hexagon_V6_vmpyhsat_acc :
-Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhsat_acc">;
-
-def int_hexagon_V6_vmpyhsat_acc_128B :
-Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhsat_acc_128B">;
-
-def int_hexagon_V6_vrmpybus_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_acc">;
-
-def int_hexagon_V6_vrmpybus_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_acc_128B">;
-
-def int_hexagon_V6_vsubhw :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhw">;
-
-def int_hexagon_V6_vsubhw_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhw_128B">;
-
-def int_hexagon_V6_vdealb4w :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdealb4w">;
-
-def int_hexagon_V6_vdealb4w_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdealb4w_128B">;
-
-def int_hexagon_V6_vmpyowh_sacc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_sacc">;
-
-def int_hexagon_V6_vmpyowh_sacc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_sacc_128B">;
-
-def int_hexagon_V6_vmpybv :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybv">;
-
-def int_hexagon_V6_vmpybv_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybv_128B">;
-
-def int_hexagon_V6_vabsdiffh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffh">;
-
-def int_hexagon_V6_vabsdiffh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffh_128B">;
-
-def int_hexagon_V6_vshuffob :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshuffob">;
-
-def int_hexagon_V6_vshuffob_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshuffob_128B">;
-
-def int_hexagon_V6_vmpyub_acc :
-Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyub_acc">;
-
-def int_hexagon_V6_vmpyub_acc_128B :
-Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyub_acc_128B">;
-
-def int_hexagon_V6_vnormamtw :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnormamtw">;
-
-def int_hexagon_V6_vnormamtw_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnormamtw_128B">;
-
-def int_hexagon_V6_vunpackuh :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackuh">;
-
-def int_hexagon_V6_vunpackuh_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackuh_128B">;
-
-def int_hexagon_V6_vgtuh_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuh_or">;
-
-def int_hexagon_V6_vgtuh_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuh_or_128B">;
-
-def int_hexagon_V6_vmpyiewuh_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc">;
-
-def int_hexagon_V6_vmpyiewuh_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc_128B">;
-
-def int_hexagon_V6_vunpackoh :
-Hexagon_v32i32_v32i32v16i32_Intrinsic<"HEXAGON_V6_vunpackoh">;
-
-def int_hexagon_V6_vunpackoh_128B :
-Hexagon_v64i32_v64i32v32i32_Intrinsic<"HEXAGON_V6_vunpackoh_128B">;
-
-def int_hexagon_V6_vdmpyhsat :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat">;
-
-def int_hexagon_V6_vdmpyhsat_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_128B">;
-
-def int_hexagon_V6_vmpyubv :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyubv">;
-
-def int_hexagon_V6_vmpyubv_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyubv_128B">;
-
-def int_hexagon_V6_vmpyhss :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhss">;
-
-def int_hexagon_V6_vmpyhss_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhss_128B">;
-
-def int_hexagon_V6_hi :
-Hexagon_v16i32_v32i32_Intrinsic<"HEXAGON_V6_hi">;
-
-def int_hexagon_V6_hi_128B :
-Hexagon_v32i32_v64i32_Intrinsic<"HEXAGON_V6_hi_128B">;
-
-def int_hexagon_V6_vasrwuhsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwuhsat">;
-
-def int_hexagon_V6_vasrwuhsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwuhsat_128B">;
-
-def int_hexagon_V6_veqw :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_veqw">;
-
-def int_hexagon_V6_veqw_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_veqw_128B">;
-
-def int_hexagon_V6_vdsaduh :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdsaduh">;
-
-def int_hexagon_V6_vdsaduh_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_128B">;
-
-def int_hexagon_V6_vsubw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubw">;
-
-def int_hexagon_V6_vsubw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubw_128B">;
-
-def int_hexagon_V6_vsubw_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubw_dv">;
-
-def int_hexagon_V6_vsubw_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubw_dv_128B">;
-
-def int_hexagon_V6_veqb_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqb_and">;
-
-def int_hexagon_V6_veqb_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqb_and_128B">;
-
-def int_hexagon_V6_vmpyih :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyih">;
-
-def int_hexagon_V6_vmpyih_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyih_128B">;
-
-def int_hexagon_V6_vtmpyb_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_acc">;
-
-def int_hexagon_V6_vtmpyb_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_acc_128B">;
-
-def int_hexagon_V6_vrmpybus :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vrmpybus">;
-
-def int_hexagon_V6_vrmpybus_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_128B">;
-
-def int_hexagon_V6_vmpybus_acc :
-Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpybus_acc">;
-
-def int_hexagon_V6_vmpybus_acc_128B :
-Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpybus_acc_128B">;
-
-def int_hexagon_V6_vgth_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgth_xor">;
-
-def int_hexagon_V6_vgth_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgth_xor_128B">;
-
-def int_hexagon_V6_vsubhsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhsat">;
-
-def int_hexagon_V6_vsubhsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhsat_128B">;
-
-def int_hexagon_V6_vrmpyubi_acc :
-Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc", [ImmArg<3>]>;
-
-def int_hexagon_V6_vrmpyubi_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc_128B", [ImmArg<3>]>;
-
-def int_hexagon_V6_vabsw :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsw">;
-
-def int_hexagon_V6_vabsw_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsw_128B">;
-
-def int_hexagon_V6_vaddwsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwsat_dv">;
-
-def int_hexagon_V6_vaddwsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddwsat_dv_128B">;
-
-def int_hexagon_V6_vlsrw :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrw">;
-
-def int_hexagon_V6_vlsrw_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrw_128B">;
-
-def int_hexagon_V6_vabsh :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsh">;
-
-def int_hexagon_V6_vabsh_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsh_128B">;
-
-def int_hexagon_V6_vlsrh :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrh">;
-
-def int_hexagon_V6_vlsrh_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrh_128B">;
-
-def int_hexagon_V6_valignb :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignb">;
-
-def int_hexagon_V6_valignb_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignb_128B">;
-
-def int_hexagon_V6_vsubhq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhq">;
-
-def int_hexagon_V6_vsubhq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhq_128B">;
-
-def int_hexagon_V6_vpackoh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackoh">;
-
-def int_hexagon_V6_vpackoh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackoh_128B">;
-
-def int_hexagon_V6_vdmpybus_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_acc">;
-
-def int_hexagon_V6_vdmpybus_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_acc_128B">;
-
-def int_hexagon_V6_vdmpyhvsat_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc">;
-
-def int_hexagon_V6_vdmpyhvsat_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc_128B">;
-
-def int_hexagon_V6_vrmpybv_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybv_acc">;
-
-def int_hexagon_V6_vrmpybv_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybv_acc_128B">;
-
-def int_hexagon_V6_vaddhsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhsat">;
-
-def int_hexagon_V6_vaddhsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhsat_128B">;
-
-def int_hexagon_V6_vcombine :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vcombine">;
-
-def int_hexagon_V6_vcombine_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vcombine_128B">;
-
-def int_hexagon_V6_vandqrt_acc :
-Hexagon_v16i32_v16i32v512i1i32_Intrinsic<"HEXAGON_V6_vandqrt_acc">;
-
-def int_hexagon_V6_vandqrt_acc_128B :
-Hexagon_v32i32_v32i32v1024i1i32_Intrinsic<"HEXAGON_V6_vandqrt_acc_128B">;
-
-def int_hexagon_V6_vaslhv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaslhv">;
-
-def int_hexagon_V6_vaslhv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaslhv_128B">;
-
-def int_hexagon_V6_vinsertwr :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vinsertwr">;
-
-def int_hexagon_V6_vinsertwr_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vinsertwr_128B">;
-
-def int_hexagon_V6_vsubh_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubh_dv">;
-
-def int_hexagon_V6_vsubh_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubh_dv_128B">;
-
-def int_hexagon_V6_vshuffb :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vshuffb">;
-
-def int_hexagon_V6_vshuffb_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vshuffb_128B">;
-
-def int_hexagon_V6_vand :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vand">;
-
-def int_hexagon_V6_vand_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vand_128B">;
-
-def int_hexagon_V6_vmpyhv :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhv">;
-
-def int_hexagon_V6_vmpyhv_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhv_128B">;
-
-def int_hexagon_V6_vdmpyhsuisat_acc :
-Hexagon_v16i32_v16i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc">;
-
-def int_hexagon_V6_vdmpyhsuisat_acc_128B :
-Hexagon_v32i32_v32i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc_128B">;
-
-def int_hexagon_V6_vsububsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububsat_dv">;
-
-def int_hexagon_V6_vsububsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsububsat_dv_128B">;
-
-def int_hexagon_V6_vgtb_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtb_xor">;
-
-def int_hexagon_V6_vgtb_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtb_xor_128B">;
-
-def int_hexagon_V6_vdsaduh_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_acc">;
-
-def int_hexagon_V6_vdsaduh_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_acc_128B">;
-
-def int_hexagon_V6_vrmpyub :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vrmpyub">;
-
-def int_hexagon_V6_vrmpyub_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_128B">;
-
-def int_hexagon_V6_vmpyuh_acc :
-Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_acc">;
-
-def int_hexagon_V6_vmpyuh_acc_128B :
-Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_acc_128B">;
-
-def int_hexagon_V6_vcl0h :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vcl0h">;
-
-def int_hexagon_V6_vcl0h_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vcl0h_128B">;
-
-def int_hexagon_V6_vmpyhus_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhus_acc">;
-
-def int_hexagon_V6_vmpyhus_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhus_acc_128B">;
-
-def int_hexagon_V6_vmpybv_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybv_acc">;
-
-def int_hexagon_V6_vmpybv_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybv_acc_128B">;
-
-def int_hexagon_V6_vrsadubi :
-Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vrsadubi_128B :
-Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vdmpyhb_dv_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc">;
-
-def int_hexagon_V6_vdmpyhb_dv_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc_128B">;
-
-def int_hexagon_V6_vshufeh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufeh">;
-
-def int_hexagon_V6_vshufeh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufeh_128B">;
-
-def int_hexagon_V6_vmpyewuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyewuh">;
-
-def int_hexagon_V6_vmpyewuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyewuh_128B">;
-
-def int_hexagon_V6_vmpyhsrs :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhsrs">;
-
-def int_hexagon_V6_vmpyhsrs_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhsrs_128B">;
-
-def int_hexagon_V6_vdmpybus_dv_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc">;
-
-def int_hexagon_V6_vdmpybus_dv_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc_128B">;
-
-def int_hexagon_V6_vaddubh :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubh">;
-
-def int_hexagon_V6_vaddubh_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubh_128B">;
-
-def int_hexagon_V6_vasrwh :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwh">;
-
-def int_hexagon_V6_vasrwh_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwh_128B">;
-
-def int_hexagon_V6_ld0 :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_ld0">;
-
-def int_hexagon_V6_ld0_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_ld0_128B">;
-
-def int_hexagon_V6_vpopcounth :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vpopcounth">;
-
-def int_hexagon_V6_vpopcounth_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vpopcounth_128B">;
-
-def int_hexagon_V6_ldnt0 :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_ldnt0">;
-
-def int_hexagon_V6_ldnt0_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_ldnt0_128B">;
-
-def int_hexagon_V6_vgth_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgth_and">;
-
-def int_hexagon_V6_vgth_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgth_and_128B">;
-
-def int_hexagon_V6_vaddubsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubsat_dv">;
-
-def int_hexagon_V6_vaddubsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddubsat_dv_128B">;
-
-def int_hexagon_V6_vpackeh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackeh">;
-
-def int_hexagon_V6_vpackeh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackeh_128B">;
-
-def int_hexagon_V6_vmpyh :
-Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyh">;
-
-def int_hexagon_V6_vmpyh_128B :
-Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyh_128B">;
-
-def int_hexagon_V6_vminh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminh">;
-
-def int_hexagon_V6_vminh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminh_128B">;
-
-def int_hexagon_V6_pred_scalar2 :
-Hexagon_v512i1_i32_Intrinsic<"HEXAGON_V6_pred_scalar2">;
-
-def int_hexagon_V6_pred_scalar2_128B :
-Hexagon_v1024i1_i32_Intrinsic<"HEXAGON_V6_pred_scalar2_128B">;
-
-def int_hexagon_V6_vdealh :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vdealh">;
-
-def int_hexagon_V6_vdealh_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vdealh_128B">;
-
-def int_hexagon_V6_vpackwh_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackwh_sat">;
-
-def int_hexagon_V6_vpackwh_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackwh_sat_128B">;
-
-def int_hexagon_V6_vaslh :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vaslh">;
-
-def int_hexagon_V6_vaslh_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vaslh_128B">;
-
-def int_hexagon_V6_vgtuw_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuw_and">;
-
-def int_hexagon_V6_vgtuw_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuw_and_128B">;
-
-def int_hexagon_V6_vor :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vor">;
-
-def int_hexagon_V6_vor_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vor_128B">;
-
-def int_hexagon_V6_vlutvvb :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb">;
-
-def int_hexagon_V6_vlutvvb_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_128B">;
-
-def int_hexagon_V6_vmpyiowh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiowh">;
-
-def int_hexagon_V6_vmpyiowh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiowh_128B">;
-
-def int_hexagon_V6_vlutvvb_oracc :
-Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracc">;
-
-def int_hexagon_V6_vlutvvb_oracc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracc_128B">;
-
-def int_hexagon_V6_vandvrt :
-Hexagon_v512i1_v16i32i32_Intrinsic<"HEXAGON_V6_vandvrt">;
-
-def int_hexagon_V6_vandvrt_128B :
-Hexagon_v1024i1_v32i32i32_Intrinsic<"HEXAGON_V6_vandvrt_128B">;
-
-def int_hexagon_V6_veqh_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqh_xor">;
-
-def int_hexagon_V6_veqh_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqh_xor_128B">;
-
-def int_hexagon_V6_vadduhw :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhw">;
-
-def int_hexagon_V6_vadduhw_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhw_128B">;
-
-def int_hexagon_V6_vcl0w :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vcl0w">;
-
-def int_hexagon_V6_vcl0w_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vcl0w_128B">;
-
-def int_hexagon_V6_vmpyihb :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyihb">;
-
-def int_hexagon_V6_vmpyihb_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_128B">;
-
-def int_hexagon_V6_vtmpybus :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpybus">;
-
-def int_hexagon_V6_vtmpybus_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_128B">;
-
-def int_hexagon_V6_vd0 :
-Hexagon_v16i32__Intrinsic<"HEXAGON_V6_vd0">;
-
-def int_hexagon_V6_vd0_128B :
-Hexagon_v32i32__Intrinsic<"HEXAGON_V6_vd0_128B">;
-
-def int_hexagon_V6_veqh_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqh_or">;
-
-def int_hexagon_V6_veqh_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqh_or_128B">;
-
-def int_hexagon_V6_vgtw_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtw_or">;
-
-def int_hexagon_V6_vgtw_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtw_or_128B">;
-
-def int_hexagon_V6_vdmpybus :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpybus">;
-
-def int_hexagon_V6_vdmpybus_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_128B">;
-
-def int_hexagon_V6_vgtub_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtub_or">;
-
-def int_hexagon_V6_vgtub_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtub_or_128B">;
-
-def int_hexagon_V6_vmpybus :
-Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpybus">;
-
-def int_hexagon_V6_vmpybus_128B :
-Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpybus_128B">;
-
-def int_hexagon_V6_vdmpyhb_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_acc">;
-
-def int_hexagon_V6_vdmpyhb_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_acc_128B">;
-
-def int_hexagon_V6_vandvrt_acc :
-Hexagon_v512i1_v512i1v16i32i32_Intrinsic<"HEXAGON_V6_vandvrt_acc">;
-
-def int_hexagon_V6_vandvrt_acc_128B :
-Hexagon_v1024i1_v1024i1v32i32i32_Intrinsic<"HEXAGON_V6_vandvrt_acc_128B">;
-
-def int_hexagon_V6_vassign :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vassign">;
-
-def int_hexagon_V6_vassign_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vassign_128B">;
-
-def int_hexagon_V6_vaddwnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddwnq">;
-
-def int_hexagon_V6_vaddwnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwnq_128B">;
-
-def int_hexagon_V6_vgtub_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtub_and">;
-
-def int_hexagon_V6_vgtub_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtub_and_128B">;
-
-def int_hexagon_V6_vdmpyhb_dv :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv">;
-
-def int_hexagon_V6_vdmpyhb_dv_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_128B">;
-
-def int_hexagon_V6_vunpackb :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackb">;
-
-def int_hexagon_V6_vunpackb_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackb_128B">;
-
-def int_hexagon_V6_vunpackh :
-Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackh">;
-
-def int_hexagon_V6_vunpackh_128B :
-Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackh_128B">;
-
-def int_hexagon_V6_vmpahb_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpahb_acc">;
-
-def int_hexagon_V6_vmpahb_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpahb_acc_128B">;
-
-def int_hexagon_V6_vaddbnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddbnq">;
-
-def int_hexagon_V6_vaddbnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbnq_128B">;
-
-def int_hexagon_V6_vlalignbi :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignbi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vlalignbi_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignbi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vsatwh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatwh">;
-
-def int_hexagon_V6_vsatwh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatwh_128B">;
-
-def int_hexagon_V6_vgtuh :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuh">;
-
-def int_hexagon_V6_vgtuh_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuh_128B">;
-
-def int_hexagon_V6_vmpyihb_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_acc">;
-
-def int_hexagon_V6_vmpyihb_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_acc_128B">;
-
-def int_hexagon_V6_vrmpybusv_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybusv_acc">;
-
-def int_hexagon_V6_vrmpybusv_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybusv_acc_128B">;
-
-def int_hexagon_V6_vrdelta :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrdelta">;
-
-def int_hexagon_V6_vrdelta_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrdelta_128B">;
-
-def int_hexagon_V6_vroundwh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundwh">;
-
-def int_hexagon_V6_vroundwh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundwh_128B">;
-
-def int_hexagon_V6_vaddw_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddw_dv">;
-
-def int_hexagon_V6_vaddw_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddw_dv_128B">;
-
-def int_hexagon_V6_vmpyiwb_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_acc">;
-
-def int_hexagon_V6_vmpyiwb_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_acc_128B">;
-
-def int_hexagon_V6_vsubbq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubbq">;
-
-def int_hexagon_V6_vsubbq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbq_128B">;
-
-def int_hexagon_V6_veqh_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqh_and">;
-
-def int_hexagon_V6_veqh_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqh_and_128B">;
-
-def int_hexagon_V6_valignbi :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignbi", [ImmArg<2>]>;
-
-def int_hexagon_V6_valignbi_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignbi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vaddwsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddwsat">;
-
-def int_hexagon_V6_vaddwsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwsat_128B">;
-
-def int_hexagon_V6_veqw_and :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqw_and">;
-
-def int_hexagon_V6_veqw_and_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqw_and_128B">;
-
-def int_hexagon_V6_vabsdiffub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffub">;
-
-def int_hexagon_V6_vabsdiffub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffub_128B">;
-
-def int_hexagon_V6_vshuffeb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshuffeb">;
-
-def int_hexagon_V6_vshuffeb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshuffeb_128B">;
-
-def int_hexagon_V6_vabsdiffuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffuh">;
-
-def int_hexagon_V6_vabsdiffuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffuh_128B">;
-
-def int_hexagon_V6_veqw_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqw_xor">;
-
-def int_hexagon_V6_veqw_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqw_xor_128B">;
-
-def int_hexagon_V6_vgth :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgth">;
-
-def int_hexagon_V6_vgth_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgth_128B">;
-
-def int_hexagon_V6_vgtuw_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuw_xor">;
-
-def int_hexagon_V6_vgtuw_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuw_xor_128B">;
-
-def int_hexagon_V6_vgtb :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtb">;
-
-def int_hexagon_V6_vgtb_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtb_128B">;
-
-def int_hexagon_V6_vgtw :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtw">;
-
-def int_hexagon_V6_vgtw_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtw_128B">;
-
-def int_hexagon_V6_vsubwq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubwq">;
-
-def int_hexagon_V6_vsubwq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwq_128B">;
-
-def int_hexagon_V6_vnot :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnot">;
-
-def int_hexagon_V6_vnot_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnot_128B">;
-
-def int_hexagon_V6_vgtb_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtb_or">;
-
-def int_hexagon_V6_vgtb_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtb_or_128B">;
-
-def int_hexagon_V6_vgtuw_or :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtuw_or">;
-
-def int_hexagon_V6_vgtuw_or_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtuw_or_128B">;
-
-def int_hexagon_V6_vaddubsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubsat">;
-
-def int_hexagon_V6_vaddubsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubsat_128B">;
-
-def int_hexagon_V6_vmaxw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxw">;
-
-def int_hexagon_V6_vmaxw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxw_128B">;
-
-def int_hexagon_V6_vaslwv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaslwv">;
-
-def int_hexagon_V6_vaslwv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaslwv_128B">;
-
-def int_hexagon_V6_vabsw_sat :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsw_sat">;
-
-def int_hexagon_V6_vabsw_sat_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsw_sat_128B">;
-
-def int_hexagon_V6_vsubwsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwsat_dv">;
-
-def int_hexagon_V6_vsubwsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubwsat_dv_128B">;
-
-def int_hexagon_V6_vroundhub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundhub">;
-
-def int_hexagon_V6_vroundhub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundhub_128B">;
-
-def int_hexagon_V6_vdmpyhisat_acc :
-Hexagon_v16i32_v16i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc">;
-
-def int_hexagon_V6_vdmpyhisat_acc_128B :
-Hexagon_v32i32_v32i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc_128B">;
-
-def int_hexagon_V6_vmpabus :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpabus">;
-
-def int_hexagon_V6_vmpabus_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpabus_128B">;
-
-def int_hexagon_V6_vassignp :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vassignp">;
-
-def int_hexagon_V6_vassignp_128B :
-Hexagon_v64i32_v64i32_Intrinsic<"HEXAGON_V6_vassignp_128B">;
-
-def int_hexagon_V6_veqb :
-Hexagon_v512i1_v16i32v16i32_Intrinsic<"HEXAGON_V6_veqb">;
-
-def int_hexagon_V6_veqb_128B :
-Hexagon_v1024i1_v32i32v32i32_Intrinsic<"HEXAGON_V6_veqb_128B">;
-
-def int_hexagon_V6_vsububh :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsububh">;
-
-def int_hexagon_V6_vsububh_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububh_128B">;
-
-def int_hexagon_V6_lvsplatw :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplatw">;
-
-def int_hexagon_V6_lvsplatw_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplatw_128B">;
-
-def int_hexagon_V6_vaddhnq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhnq">;
-
-def int_hexagon_V6_vaddhnq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhnq_128B">;
-
-def int_hexagon_V6_vdmpyhsusat :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat">;
-
-def int_hexagon_V6_vdmpyhsusat_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_128B">;
-
-def int_hexagon_V6_pred_not :
-Hexagon_v512i1_v512i1_Intrinsic<"HEXAGON_V6_pred_not">;
-
-def int_hexagon_V6_pred_not_128B :
-Hexagon_v1024i1_v1024i1_Intrinsic<"HEXAGON_V6_pred_not_128B">;
-
-def int_hexagon_V6_vlutvwh_oracc :
-Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracc">;
-
-def int_hexagon_V6_vlutvwh_oracc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracc_128B">;
-
-def int_hexagon_V6_vmpyiewh_acc :
-Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewh_acc">;
-
-def int_hexagon_V6_vmpyiewh_acc_128B :
-Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewh_acc_128B">;
-
-def int_hexagon_V6_vdealvdd :
-Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdealvdd">;
-
-def int_hexagon_V6_vdealvdd_128B :
-Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdealvdd_128B">;
-
-def int_hexagon_V6_vavgw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgw">;
-
-def int_hexagon_V6_vavgw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgw_128B">;
-
-def int_hexagon_V6_vdmpyhsusat_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc">;
-
-def int_hexagon_V6_vdmpyhsusat_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc_128B">;
-
-def int_hexagon_V6_vgtw_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vgtw_xor">;
-
-def int_hexagon_V6_vgtw_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vgtw_xor_128B">;
-
-def int_hexagon_V6_vtmpyhb_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_acc">;
-
-def int_hexagon_V6_vtmpyhb_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_acc_128B">;
-
-def int_hexagon_V6_vaddhw :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhw">;
-
-def int_hexagon_V6_vaddhw_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhw_128B">;
-
-def int_hexagon_V6_vaddhq :
-Hexagon_v16i32_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhq">;
-
-def int_hexagon_V6_vaddhq_128B :
-Hexagon_v32i32_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhq_128B">;
-
-def int_hexagon_V6_vrmpyubv :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpyubv">;
-
-def int_hexagon_V6_vrmpyubv_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpyubv_128B">;
-
-def int_hexagon_V6_vsubh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubh">;
-
-def int_hexagon_V6_vsubh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubh_128B">;
-
-def int_hexagon_V6_vrmpyubi :
-Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vrmpyubi_128B :
-Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vminw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminw">;
-
-def int_hexagon_V6_vminw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminw_128B">;
-
-def int_hexagon_V6_vmpyubv_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyubv_acc">;
-
-def int_hexagon_V6_vmpyubv_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyubv_acc_128B">;
-
-def int_hexagon_V6_pred_xor :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_pred_xor">;
-
-def int_hexagon_V6_pred_xor_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_pred_xor_128B">;
-
-def int_hexagon_V6_veqb_xor :
-Hexagon_v512i1_v512i1v16i32v16i32_Intrinsic<"HEXAGON_V6_veqb_xor">;
-
-def int_hexagon_V6_veqb_xor_128B :
-Hexagon_v1024i1_v1024i1v32i32v32i32_Intrinsic<"HEXAGON_V6_veqb_xor_128B">;
-
-def int_hexagon_V6_vmpyiewuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewuh">;
-
-def int_hexagon_V6_vmpyiewuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_128B">;
-
-def int_hexagon_V6_vmpybusv_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybusv_acc">;
-
-def int_hexagon_V6_vmpybusv_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybusv_acc_128B">;
-
-def int_hexagon_V6_vavguhrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguhrnd">;
-
-def int_hexagon_V6_vavguhrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguhrnd_128B">;
-
-def int_hexagon_V6_vmpyowh_rnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd">;
-
-def int_hexagon_V6_vmpyowh_rnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_128B">;
-
-def int_hexagon_V6_vsubwsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubwsat">;
-
-def int_hexagon_V6_vsubwsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwsat_128B">;
-
-def int_hexagon_V6_vsubuhw :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuhw">;
-
-def int_hexagon_V6_vsubuhw_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhw_128B">;
-
-def int_hexagon_V6_vrmpybusi_acc :
-Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc", [ImmArg<3>]>;
-
-def int_hexagon_V6_vrmpybusi_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc_128B", [ImmArg<3>]>;
-
-def int_hexagon_V6_vasrw :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vasrw">;
-
-def int_hexagon_V6_vasrw_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vasrw_128B">;
-
-def int_hexagon_V6_vasrh :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vasrh">;
-
-def int_hexagon_V6_vasrh_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vasrh_128B">;
-
-def int_hexagon_V6_vmpyuhv :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyuhv">;
-
-def int_hexagon_V6_vmpyuhv_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyuhv_128B">;
-
-def int_hexagon_V6_vasrhbrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhbrndsat">;
-
-def int_hexagon_V6_vasrhbrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhbrndsat_128B">;
-
-def int_hexagon_V6_vsubuhsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhsat_dv">;
-
-def int_hexagon_V6_vsubuhsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubuhsat_dv_128B">;
-
-def int_hexagon_V6_vabsdiffw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffw">;
-
-def int_hexagon_V6_vabsdiffw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffw_128B">;
-
-// V62 HVX Instructions.
-
-def int_hexagon_V6_vandnqrt_acc :
-Hexagon_v16i32_v16i32v512i1i32_Intrinsic<"HEXAGON_V6_vandnqrt_acc">;
-
-def int_hexagon_V6_vandnqrt_acc_128B :
-Hexagon_v32i32_v32i32v1024i1i32_Intrinsic<"HEXAGON_V6_vandnqrt_acc_128B">;
-
-def int_hexagon_V6_vaddclbh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddclbh">;
-
-def int_hexagon_V6_vaddclbh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddclbh_128B">;
-
-def int_hexagon_V6_vmpyowh_64_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc">;
-
-def int_hexagon_V6_vmpyowh_64_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc_128B">;
-
-def int_hexagon_V6_vmpyewuh_64 :
-Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyewuh_64">;
-
-def int_hexagon_V6_vmpyewuh_64_128B :
-Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyewuh_64_128B">;
-
-def int_hexagon_V6_vsatuwuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatuwuh">;
-
-def int_hexagon_V6_vsatuwuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatuwuh_128B">;
-
-def int_hexagon_V6_shuffeqh :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_shuffeqh">;
-
-def int_hexagon_V6_shuffeqh_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_shuffeqh_128B">;
-
-def int_hexagon_V6_shuffeqw :
-Hexagon_v512i1_v512i1v512i1_Intrinsic<"HEXAGON_V6_shuffeqw">;
-
-def int_hexagon_V6_shuffeqw_128B :
-Hexagon_v1024i1_v1024i1v1024i1_Intrinsic<"HEXAGON_V6_shuffeqw_128B">;
-
-def int_hexagon_V6_ldcnpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldcnpnt0">;
-
-def int_hexagon_V6_ldcnpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldcnpnt0_128B">;
-
-def int_hexagon_V6_vsubcarry :
-Hexagon_custom_v16i32v512i1_v16i32v16i32v512i1_Intrinsic;
-
-def int_hexagon_V6_vsubcarry_128B :
-Hexagon_custom_v32i32v1024i1_v32i32v32i32v1024i1_Intrinsic_128B;
-
-def int_hexagon_V6_vasrhbsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhbsat">;
-
-def int_hexagon_V6_vasrhbsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhbsat_128B">;
-
-def int_hexagon_V6_vminb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminb">;
-
-def int_hexagon_V6_vminb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminb_128B">;
-
-def int_hexagon_V6_vmpauhb_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_acc">;
-
-def int_hexagon_V6_vmpauhb_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_acc_128B">;
-
-def int_hexagon_V6_vaddhw_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhw_acc">;
-
-def int_hexagon_V6_vaddhw_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhw_acc_128B">;
-
-def int_hexagon_V6_vlsrb :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrb">;
-
-def int_hexagon_V6_vlsrb_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrb_128B">;
-
-def int_hexagon_V6_vlutvwhi :
-Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vlutvwhi_128B :
-Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vaddububb_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddububb_sat">;
-
-def int_hexagon_V6_vaddububb_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddububb_sat_128B">;
-
-def int_hexagon_V6_vsubbsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbsat_dv">;
-
-def int_hexagon_V6_vsubbsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubbsat_dv_128B">;
-
-def int_hexagon_V6_ldtp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldtp0">;
-
-def int_hexagon_V6_ldtp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldtp0_128B">;
-
-def int_hexagon_V6_vlutvvb_oracci :
-Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci", [ImmArg<3>]>;
-
-def int_hexagon_V6_vlutvvb_oracci_128B :
-Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci_128B", [ImmArg<3>]>;
-
-def int_hexagon_V6_vsubuwsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuwsat_dv">;
-
-def int_hexagon_V6_vsubuwsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubuwsat_dv_128B">;
-
-def int_hexagon_V6_ldpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldpnt0">;
-
-def int_hexagon_V6_ldpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldpnt0_128B">;
-
-def int_hexagon_V6_vandvnqv :
-Hexagon_v16i32_v512i1v16i32_Intrinsic<"HEXAGON_V6_vandvnqv">;
-
-def int_hexagon_V6_vandvnqv_128B :
-Hexagon_v32i32_v1024i1v32i32_Intrinsic<"HEXAGON_V6_vandvnqv_128B">;
-
-def int_hexagon_V6_lvsplatb :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplatb">;
-
-def int_hexagon_V6_lvsplatb_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplatb_128B">;
-
-def int_hexagon_V6_lvsplath :
-Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplath">;
-
-def int_hexagon_V6_lvsplath_128B :
-Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplath_128B">;
-
-def int_hexagon_V6_ldtpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldtpnt0">;
-
-def int_hexagon_V6_ldtpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldtpnt0_128B">;
-
-def int_hexagon_V6_vlutvwh_nm :
-Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_nm">;
-
-def int_hexagon_V6_vlutvwh_nm_128B :
-Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_nm_128B">;
-
-def int_hexagon_V6_ldnpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldnpnt0">;
-
-def int_hexagon_V6_ldnpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldnpnt0_128B">;
-
-def int_hexagon_V6_vmpauhb :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpauhb">;
-
-def int_hexagon_V6_vmpauhb_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_128B">;
-
-def int_hexagon_V6_ldtnp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldtnp0">;
-
-def int_hexagon_V6_ldtnp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldtnp0_128B">;
-
-def int_hexagon_V6_vrounduhub :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrounduhub">;
-
-def int_hexagon_V6_vrounduhub_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrounduhub_128B">;
-
-def int_hexagon_V6_vadduhw_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhw_acc">;
-
-def int_hexagon_V6_vadduhw_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhw_acc_128B">;
-
-def int_hexagon_V6_ldcp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldcp0">;
-
-def int_hexagon_V6_ldcp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldcp0_128B">;
-
-def int_hexagon_V6_vadduwsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduwsat">;
-
-def int_hexagon_V6_vadduwsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduwsat_128B">;
-
-def int_hexagon_V6_ldtnpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldtnpnt0">;
-
-def int_hexagon_V6_ldtnpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldtnpnt0_128B">;
-
-def int_hexagon_V6_vaddbsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddbsat">;
-
-def int_hexagon_V6_vaddbsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbsat_128B">;
-
-def int_hexagon_V6_vandnqrt :
-Hexagon_v16i32_v512i1i32_Intrinsic<"HEXAGON_V6_vandnqrt">;
-
-def int_hexagon_V6_vandnqrt_128B :
-Hexagon_v32i32_v1024i1i32_Intrinsic<"HEXAGON_V6_vandnqrt_128B">;
-
-def int_hexagon_V6_vmpyiwub_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_acc">;
-
-def int_hexagon_V6_vmpyiwub_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_acc_128B">;
-
-def int_hexagon_V6_vmaxb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxb">;
-
-def int_hexagon_V6_vmaxb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxb_128B">;
-
-def int_hexagon_V6_vandvqv :
-Hexagon_v16i32_v512i1v16i32_Intrinsic<"HEXAGON_V6_vandvqv">;
-
-def int_hexagon_V6_vandvqv_128B :
-Hexagon_v32i32_v1024i1v32i32_Intrinsic<"HEXAGON_V6_vandvqv_128B">;
-
-def int_hexagon_V6_vaddcarry :
-Hexagon_custom_v16i32v512i1_v16i32v16i32v512i1_Intrinsic;
-
-def int_hexagon_V6_vaddcarry_128B :
-Hexagon_custom_v32i32v1024i1_v32i32v32i32v1024i1_Intrinsic_128B;
-
-def int_hexagon_V6_vasrwuhrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwuhrndsat">;
-
-def int_hexagon_V6_vasrwuhrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwuhrndsat_128B">;
-
-def int_hexagon_V6_vlutvvbi :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi", [ImmArg<2>]>;
-
-def int_hexagon_V6_vlutvvbi_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi_128B", [ImmArg<2>]>;
-
-def int_hexagon_V6_vsubuwsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuwsat">;
-
-def int_hexagon_V6_vsubuwsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuwsat_128B">;
-
-def int_hexagon_V6_vaddbsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbsat_dv">;
-
-def int_hexagon_V6_vaddbsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddbsat_dv_128B">;
-
-def int_hexagon_V6_ldnp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldnp0">;
-
-def int_hexagon_V6_ldnp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldnp0_128B">;
-
-def int_hexagon_V6_vasruwuhrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruwuhrndsat">;
-
-def int_hexagon_V6_vasruwuhrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruwuhrndsat_128B">;
-
-def int_hexagon_V6_vrounduwuh :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrounduwuh">;
-
-def int_hexagon_V6_vrounduwuh_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrounduwuh_128B">;
-
-def int_hexagon_V6_vlutvvb_nm :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_nm">;
-
-def int_hexagon_V6_vlutvvb_nm_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_nm_128B">;
-
-def int_hexagon_V6_pred_scalar2v2 :
-Hexagon_v512i1_i32_Intrinsic<"HEXAGON_V6_pred_scalar2v2">;
-
-def int_hexagon_V6_pred_scalar2v2_128B :
-Hexagon_v1024i1_i32_Intrinsic<"HEXAGON_V6_pred_scalar2v2_128B">;
-
-def int_hexagon_V6_ldp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldp0">;
-
-def int_hexagon_V6_ldp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldp0_128B">;
-
-def int_hexagon_V6_vaddubh_acc :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubh_acc">;
-
-def int_hexagon_V6_vaddubh_acc_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubh_acc_128B">;
-
-def int_hexagon_V6_vaddclbw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddclbw">;
-
-def int_hexagon_V6_vaddclbw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddclbw_128B">;
-
-def int_hexagon_V6_ldcpnt0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldcpnt0">;
-
-def int_hexagon_V6_ldcpnt0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldcpnt0_128B">;
-
-def int_hexagon_V6_vadduwsat_dv :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduwsat_dv">;
-
-def int_hexagon_V6_vadduwsat_dv_128B :
-Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vadduwsat_dv_128B">;
-
-def int_hexagon_V6_vmpyiwub :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub">;
-
-def int_hexagon_V6_vmpyiwub_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_128B">;
-
-def int_hexagon_V6_vsubububb_sat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubububb_sat">;
-
-def int_hexagon_V6_vsubububb_sat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubububb_sat_128B">;
-
-def int_hexagon_V6_ldcnp0 :
-Hexagon_v16i32_i32i32_Intrinsic<"HEXAGON_V6_ldcnp0">;
-
-def int_hexagon_V6_ldcnp0_128B :
-Hexagon_v32i32_i32i32_Intrinsic<"HEXAGON_V6_ldcnp0_128B">;
-
-def int_hexagon_V6_vlutvwh_oracci :
-Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci", [ImmArg<3>]>;
-
-def int_hexagon_V6_vlutvwh_oracci_128B :
-Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci_128B", [ImmArg<3>]>;
-
-def int_hexagon_V6_vsubbsat :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubbsat">;
-
-def int_hexagon_V6_vsubbsat_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbsat_128B">;
-
-// V65 HVX Instructions.
-
-def int_hexagon_V6_vasruhubrndsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruhubrndsat">;
-
-def int_hexagon_V6_vasruhubrndsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruhubrndsat_128B">;
-
def int_hexagon_V6_vrmpybub_rtt :
-Hexagon_v32i32_v16i32i64_Intrinsic<"HEXAGON_V6_vrmpybub_rtt">;
+Hexagon_v32i32_v16i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpybub_rtt">;
def int_hexagon_V6_vrmpybub_rtt_128B :
-Hexagon_v64i32_v32i32i64_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_128B">;
-
-def int_hexagon_V6_vmpahhsat :
-Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpahhsat">;
-
-def int_hexagon_V6_vmpahhsat_128B :
-Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpahhsat_128B">;
-
-def int_hexagon_V6_vavguwrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguwrnd">;
-
-def int_hexagon_V6_vavguwrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguwrnd_128B">;
-
-def int_hexagon_V6_vnavgb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgb">;
-
-def int_hexagon_V6_vnavgb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgb_128B">;
-
-def int_hexagon_V6_vasrh_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrh_acc">;
-
-def int_hexagon_V6_vasrh_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrh_acc_128B">;
-
-def int_hexagon_V6_vmpauhuhsat :
-Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpauhuhsat">;
-
-def int_hexagon_V6_vmpauhuhsat_128B :
-Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpauhuhsat_128B">;
-
-def int_hexagon_V6_vmpyh_acc :
-Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyh_acc">;
-
-def int_hexagon_V6_vmpyh_acc_128B :
-Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyh_acc_128B">;
+Hexagon_v64i32_v32i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_128B">;
def int_hexagon_V6_vrmpybub_rtt_acc :
-Hexagon_v32i32_v32i32v16i32i64_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_acc">;
+Hexagon_v32i32_v32i32v16i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_acc">;
def int_hexagon_V6_vrmpybub_rtt_acc_128B :
-Hexagon_v64i32_v64i32v32i32i64_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_acc_128B">;
-
-def int_hexagon_V6_vavgb :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgb">;
-
-def int_hexagon_V6_vavgb_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgb_128B">;
-
-def int_hexagon_V6_vaslh_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vaslh_acc">;
-
-def int_hexagon_V6_vaslh_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vaslh_acc_128B">;
-
-def int_hexagon_V6_vavguw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguw">;
-
-def int_hexagon_V6_vavguw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguw_128B">;
-
-def int_hexagon_V6_vlut4 :
-Hexagon_v16i32_v16i32i64_Intrinsic<"HEXAGON_V6_vlut4">;
-
-def int_hexagon_V6_vlut4_128B :
-Hexagon_v32i32_v32i32i64_Intrinsic<"HEXAGON_V6_vlut4_128B">;
-
-def int_hexagon_V6_vmpyuhe_acc :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_acc">;
-
-def int_hexagon_V6_vmpyuhe_acc_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_acc_128B">;
+Hexagon_v64i32_v64i32v32i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpybub_rtt_acc_128B">;
def int_hexagon_V6_vrmpyub_rtt :
-Hexagon_v32i32_v16i32i64_Intrinsic<"HEXAGON_V6_vrmpyub_rtt">;
+Hexagon_v32i32_v16i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpyub_rtt">;
def int_hexagon_V6_vrmpyub_rtt_128B :
-Hexagon_v64i32_v32i32i64_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_128B">;
-
-def int_hexagon_V6_vmpsuhuhsat :
-Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpsuhuhsat">;
-
-def int_hexagon_V6_vmpsuhuhsat_128B :
-Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpsuhuhsat_128B">;
-
-def int_hexagon_V6_vasruhubsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruhubsat">;
-
-def int_hexagon_V6_vasruhubsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruhubsat_128B">;
-
-def int_hexagon_V6_vmpyuhe :
-Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe">;
-
-def int_hexagon_V6_vmpyuhe_128B :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_128B">;
+Hexagon_v64i32_v32i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_128B">;
def int_hexagon_V6_vrmpyub_rtt_acc :
-Hexagon_v32i32_v32i32v16i32i64_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_acc">;
+Hexagon_v32i32_v32i32v16i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_acc">;
def int_hexagon_V6_vrmpyub_rtt_acc_128B :
-Hexagon_v64i32_v64i32v32i32i64_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_acc_128B">;
-
-def int_hexagon_V6_vasruwuhsat :
-Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruwuhsat">;
-
-def int_hexagon_V6_vasruwuhsat_128B :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruwuhsat_128B">;
-
-def int_hexagon_V6_vmpabuu_acc :
-Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_acc">;
-
-def int_hexagon_V6_vmpabuu_acc_128B :
-Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_acc_128B">;
-
-def int_hexagon_V6_vprefixqw :
-Hexagon_v16i32_v512i1_Intrinsic<"HEXAGON_V6_vprefixqw">;
-
-def int_hexagon_V6_vprefixqw_128B :
-Hexagon_v32i32_v1024i1_Intrinsic<"HEXAGON_V6_vprefixqw_128B">;
-
-def int_hexagon_V6_vprefixqh :
-Hexagon_v16i32_v512i1_Intrinsic<"HEXAGON_V6_vprefixqh">;
-
-def int_hexagon_V6_vprefixqh_128B :
-Hexagon_v32i32_v1024i1_Intrinsic<"HEXAGON_V6_vprefixqh_128B">;
-
-def int_hexagon_V6_vprefixqb :
-Hexagon_v16i32_v512i1_Intrinsic<"HEXAGON_V6_vprefixqb">;
+Hexagon_v64i32_v64i32v32i32i64_rtt_Intrinsic<"HEXAGON_V6_vrmpyub_rtt_acc_128B">;
-def int_hexagon_V6_vprefixqb_128B :
-Hexagon_v32i32_v1024i1_Intrinsic<"HEXAGON_V6_vprefixqb_128B">;
+// HVX Vector predicate casts.
+// These intrinsics do not emit (nor do they correspond to) any instructions,
+// they are no-ops.
-def int_hexagon_V6_vabsb :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsb">;
+def int_hexagon_V6_pred_typecast :
+Hexagon_NonGCC_Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_hexagon_V6_vabsb_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsb_128B">;
+def int_hexagon_V6_pred_typecast_128B :
+Hexagon_NonGCC_Intrinsic<[llvm_anyvector_ty], [llvm_anyvector_ty], [IntrNoMem]>;
-def int_hexagon_V6_vavgbrnd :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgbrnd">;
-
-def int_hexagon_V6_vavgbrnd_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgbrnd_128B">;
-
-def int_hexagon_V6_vdd0 :
-Hexagon_v32i32__Intrinsic<"HEXAGON_V6_vdd0">;
-
-def int_hexagon_V6_vdd0_128B :
-Hexagon_v64i32__Intrinsic<"HEXAGON_V6_vdd0_128B">;
-
-def int_hexagon_V6_vmpabuu :
-Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpabuu">;
-
-def int_hexagon_V6_vmpabuu_128B :
-Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_128B">;
-
-def int_hexagon_V6_vabsb_sat :
-Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsb_sat">;
-
-def int_hexagon_V6_vabsb_sat_128B :
-Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsb_sat_128B">;
-
-// V66 HVX Instructions.
-
-def int_hexagon_V6_vaddcarrysat :
-Hexagon_v16i32_v16i32v16i32v512i1_Intrinsic<"HEXAGON_V6_vaddcarrysat">;
-
-def int_hexagon_V6_vaddcarrysat_128B :
-Hexagon_v32i32_v32i32v32i32v1024i1_Intrinsic<"HEXAGON_V6_vaddcarrysat_128B">;
-
-def int_hexagon_V6_vasr_into :
-Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vasr_into">;
-
-def int_hexagon_V6_vasr_into_128B :
-Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vasr_into_128B">;
+// Masked vector stores
+//
-def int_hexagon_V6_vsatdw :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatdw">;
+class Hexagon_custom_vms_Intrinsic
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v64i1_ty,llvm_ptr_ty,llvm_v16i32_ty], [IntrWriteMem]>;
-def int_hexagon_V6_vsatdw_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatdw_128B">;
+class Hexagon_custom_vms_Intrinsic_128B
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v128i1_ty,llvm_ptr_ty,llvm_v32i32_ty], [IntrWriteMem]>;
-def int_hexagon_V6_vrotr :
-Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrotr">;
+def int_hexagon_V6_vmaskedstoreq: Hexagon_custom_vms_Intrinsic;
+def int_hexagon_V6_vmaskedstorenq: Hexagon_custom_vms_Intrinsic;
+def int_hexagon_V6_vmaskedstorentq: Hexagon_custom_vms_Intrinsic;
+def int_hexagon_V6_vmaskedstorentnq: Hexagon_custom_vms_Intrinsic;
-def int_hexagon_V6_vrotr_128B :
-Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrotr_128B">;
+def int_hexagon_V6_vmaskedstoreq_128B: Hexagon_custom_vms_Intrinsic_128B;
+def int_hexagon_V6_vmaskedstorenq_128B: Hexagon_custom_vms_Intrinsic_128B;
+def int_hexagon_V6_vmaskedstorentq_128B: Hexagon_custom_vms_Intrinsic_128B;
+def int_hexagon_V6_vmaskedstorentnq_128B: Hexagon_custom_vms_Intrinsic_128B;
+include "llvm/IR/IntrinsicsHexagonDep.td"
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagonDep.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagonDep.td
new file mode 100644
index 000000000000..198b6a7ab0d1
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsHexagonDep.td
@@ -0,0 +1,6144 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// Automatically generated file, do not edit!
+//===----------------------------------------------------------------------===//
+
+// tag : C2_cmpeq
+class Hexagon_i32_i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : C2_cmpeqp
+class Hexagon_i32_i64i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : C2_not
+class Hexagon_i32_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : C4_and_and
+class Hexagon_i32_i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : C2_vmux
+class Hexagon_i64_i32i64i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty,llvm_i64_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : C2_mask
+class Hexagon_i64_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : A4_vcmpbeqi
+class Hexagon_i32_i64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : A4_boundscheck
+class Hexagon_i32_i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : M2_mpyd_acc_hh_s0
+class Hexagon_i64_i64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : M2_mpyd_hh_s0
+class Hexagon_i64_i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : M2_vmpy2es_s0
+class Hexagon_i64_i64i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : M2_vmac2es_s0
+class Hexagon_i64_i64i64i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : M2_vrcmpys_s1
+class Hexagon_i64_i64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : M2_vrcmpys_acc_s1
+class Hexagon_i64_i64i64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : S4_vrcrotate_acc
+class Hexagon_i64_i64i64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty,llvm_i64_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : A2_addsp
+class Hexagon_i64_i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : A2_vconj
+class Hexagon_i64_i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_i64_ty],
+ intr_properties>;
+
+// tag : A2_sat
+class Hexagon_i32_i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i64_ty],
+ intr_properties>;
+
+// tag : F2_sfadd
+class Hexagon_float_floatfloat_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty,llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_sffma
+class Hexagon_float_floatfloatfloat_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty,llvm_float_ty,llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_sffma_sc
+class Hexagon_float_floatfloatfloati32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty,llvm_float_ty,llvm_float_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : F2_sfcmpeq
+class Hexagon_i32_floatfloat_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_float_ty,llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_sfclass
+class Hexagon_i32_floati32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_float_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : F2_sfimm_p
+class Hexagon_float_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : F2_sffixupr
+class Hexagon_float_float_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_dfadd
+class Hexagon_double_doubledouble_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty,llvm_double_ty],
+ intr_properties>;
+
+// tag : F2_dfmpylh
+class Hexagon_double_doubledoubledouble_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_double_ty,llvm_double_ty,llvm_double_ty],
+ intr_properties>;
+
+// tag : F2_dfcmpeq
+class Hexagon_i32_doubledouble_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_double_ty,llvm_double_ty],
+ intr_properties>;
+
+// tag : F2_dfclass
+class Hexagon_i32_doublei32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_double_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : F2_dfimm_p
+class Hexagon_double_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : F2_conv_sf2df
+class Hexagon_double_float_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_conv_df2sf
+class Hexagon_float_double_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_double_ty],
+ intr_properties>;
+
+// tag : F2_conv_ud2sf
+class Hexagon_float_i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_float_ty], [llvm_i64_ty],
+ intr_properties>;
+
+// tag : F2_conv_ud2df
+class Hexagon_double_i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_double_ty], [llvm_i64_ty],
+ intr_properties>;
+
+// tag : F2_conv_sf2uw
+class Hexagon_i32_float_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_conv_sf2ud
+class Hexagon_i64_float_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_float_ty],
+ intr_properties>;
+
+// tag : F2_conv_df2uw
+class Hexagon_i32_double_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_double_ty],
+ intr_properties>;
+
+// tag : F2_conv_df2ud
+class Hexagon_i64_double_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_double_ty],
+ intr_properties>;
+
+// tag : S2_insert
+class Hexagon_i32_i32i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : S2_insert_rp
+class Hexagon_i32_i32i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_i32_ty,llvm_i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : Y2_dcfetch
+class Hexagon__ptr_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty],
+ intr_properties>;
+
+// tag : Y4_l2fetch
+class Hexagon__ptri32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : Y5_l2fetch
+class Hexagon__ptri64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32__Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32__Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [],
+ intr_properties>;
+
+// tag :
+class Hexagon_i32_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_i64_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i64_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_i64_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v4i32_v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v4i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v4i32_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v4i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v4i32v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v4i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v8i32v64i32v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v8i32_ty,llvm_v64i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v64i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v64i32v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v4i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v4i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v32i32_v32i32v32i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag :
+class Hexagon_v64i32_v64i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vS32b_qpred_ai
+class Hexagon_custom__v64i1ptrv16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v64i1_ty,llvm_ptr_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vS32b_qpred_ai
+class Hexagon_custom__v128i1ptrv32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v128i1_ty,llvm_ptr_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_valignb
+class Hexagon_v16i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vror
+class Hexagon_v16i32_v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vunpackub
+class Hexagon_v32i32_v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vunpackob
+class Hexagon_v32i32_v32i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vpackeb
+class Hexagon_v16i32_v16i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vdmpyhvsat_acc
+class Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vdmpyhisat
+class Hexagon_v16i32_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vdmpyhisat_acc
+class Hexagon_v16i32_v16i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vdmpyhisat_acc
+class Hexagon_v32i32_v32i32v64i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v64i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vrmpyubi
+class Hexagon_v32i32_v32i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vrmpyubi
+class Hexagon_v64i32_v64i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vrmpyubi_acc
+class Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vrmpyubi_acc
+class Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v64i32_ty,llvm_i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vasr_into
+class Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vaddcarrysat
+class Hexagon_custom_v16i32_v16i32v16i32v64i1_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v64i1_ty],
+ intr_properties>;
+
+// tag : V6_vaddcarrysat
+class Hexagon_custom_v32i32_v32i32v32i32v128i1_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v128i1_ty],
+ intr_properties>;
+
+// tag : V6_vaddcarry
+class Hexagon_custom_v16i32v64i1_v16i32v16i32v64i1_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty,llvm_v64i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v64i1_ty],
+ intr_properties>;
+
+// tag : V6_vaddcarry
+class Hexagon_custom_v32i32v128i1_v32i32v32i32v128i1_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty,llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty,llvm_v128i1_ty],
+ intr_properties>;
+
+// tag : V6_vaddubh
+class Hexagon_v32i32_v16i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vd0
+class Hexagon_v16i32__Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [],
+ intr_properties>;
+
+// tag : V6_vaddbq
+class Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v64i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vaddbq
+class Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v128i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vabsb
+class Hexagon_v16i32_v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vmpyub
+class Hexagon_v32i32_v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vmpyub
+class Hexagon_v64i32_v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vmpyub_acc
+class Hexagon_v32i32_v32i32v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vmpyub_acc
+class Hexagon_v64i32_v64i32v32i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v64i32_ty], [llvm_v64i32_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandqrt
+class Hexagon_custom_v16i32_v64i1i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v64i1_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandqrt
+class Hexagon_custom_v32i32_v128i1i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v128i1_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandqrt_acc
+class Hexagon_custom_v16i32_v16i32v64i1i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v64i1_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandqrt_acc
+class Hexagon_custom_v32i32_v32i32v128i1i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v128i1_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvrt
+class Hexagon_custom_v64i1_v16i32i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvrt
+class Hexagon_custom_v128i1_v32i32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvrt_acc
+class Hexagon_custom_v64i1_v64i1v16i32i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v64i1_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvrt_acc
+class Hexagon_custom_v128i1_v128i1v32i32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v128i1_ty,llvm_v32i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvqv
+class Hexagon_custom_v16i32_v64i1v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v64i1_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vandvqv
+class Hexagon_custom_v32i32_v128i1v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v128i1_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgtw
+class Hexagon_custom_v64i1_v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vgtw
+class Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgtw_and
+class Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v64i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vgtw_and
+class Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v128i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_pred_scalar2
+class Hexagon_custom_v64i1_i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_pred_scalar2
+class Hexagon_custom_v128i1_i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_shuffeqw
+class Hexagon_custom_v64i1_v64i1v64i1_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v64i1_ty,llvm_v64i1_ty],
+ intr_properties>;
+
+// tag : V6_shuffeqw
+class Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v128i1_ty,llvm_v128i1_ty],
+ intr_properties>;
+
+// tag : V6_pred_not
+class Hexagon_custom_v64i1_v64i1_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i1_ty], [llvm_v64i1_ty],
+ intr_properties>;
+
+// tag : V6_pred_not
+class Hexagon_custom_v128i1_v128i1_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v128i1_ty], [llvm_v128i1_ty],
+ intr_properties>;
+
+// tag : V6_vswap
+class Hexagon_custom_v32i32_v64i1v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v64i1_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vswap
+class Hexagon_custom_v64i32_v128i1v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v64i32_ty], [llvm_v128i1_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vshuffvdd
+class Hexagon_v32i32_v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_extractw
+class Hexagon_i32_v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_i32_ty], [llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_lvsplatw
+class Hexagon_v16i32_i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vlutvvb_oracc
+class Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vlutvwh_oracc
+class Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v32i32_ty], [llvm_v32i32_ty,llvm_v16i32_ty,llvm_v16i32_ty,llvm_i32_ty],
+ intr_properties>;
+
+// tag : V6_vmpahhsat
+class Hexagon_v16i32_v16i32v16i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_v16i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : V6_vlut4
+class Hexagon_v16i32_v16i32i64_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v16i32_ty,llvm_i64_ty],
+ intr_properties>;
+
+// tag : V6_hi
+class Hexagon_v16i32_v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_v16i32_ty], [llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermw
+class Hexagon__ptri32i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermw
+class Hexagon__ptri32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermhw
+class Hexagon__ptri32i32v64i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_ptr_ty,llvm_i32_ty,llvm_i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermwq
+class Hexagon_custom__ptrv64i1i32i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_ptr_ty,llvm_v64i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermwq
+class Hexagon_custom__ptrv128i1i32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_ptr_ty,llvm_v128i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermhwq
+class Hexagon_custom__ptrv64i1i32i32v32i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_ptr_ty,llvm_v64i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vgathermhwq
+class Hexagon_custom__ptrv128i1i32i32v64i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_ptr_ty,llvm_v128i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v64i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermw
+class Hexagon__i32i32v16i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_i32_ty,llvm_i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermw
+class Hexagon__i32i32v32i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermwq
+class Hexagon_custom__v64i1i32i32v16i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v64i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v16i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermwq
+class Hexagon_custom__v128i1i32i32v32i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v128i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermhw
+class Hexagon__i32i32v32i32v16i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermhw
+class Hexagon__i32i32v64i32v32i32_Intrinsic<string GCCIntSuffix,
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [], [llvm_i32_ty,llvm_i32_ty,llvm_v64i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermhwq
+class Hexagon_custom__v64i1i32i32v32i32v16i32_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v64i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v32i32_ty,llvm_v16i32_ty],
+ intr_properties>;
+
+// tag : V6_vscattermhwq
+class Hexagon_custom__v128i1i32i32v64i32v32i32_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [], [llvm_v128i1_ty,llvm_i32_ty,llvm_i32_ty,llvm_v64i32_ty,llvm_v32i32_ty],
+ intr_properties>;
+
+// tag : V6_vprefixqb
+class Hexagon_custom_v16i32_v64i1_Intrinsic<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v16i32_ty], [llvm_v64i1_ty],
+ intr_properties>;
+
+// tag : V6_vprefixqb
+class Hexagon_custom_v32i32_v128i1_Intrinsic_128B<
+ list<IntrinsicProperty> intr_properties = [IntrNoMem]>
+ : Hexagon_NonGCC_Intrinsic<
+ [llvm_v32i32_ty], [llvm_v128i1_ty],
+ intr_properties>;
+
+// V5 Scalar Instructions.
+
+def int_hexagon_C2_cmpeq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeq">;
+
+def int_hexagon_C2_cmpgt :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgt">;
+
+def int_hexagon_C2_cmpgtu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtu">;
+
+def int_hexagon_C2_cmpeqp :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpeqp">;
+
+def int_hexagon_C2_cmpgtp :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtp">;
+
+def int_hexagon_C2_cmpgtup :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_C2_cmpgtup">;
+
+def int_hexagon_A4_rcmpeqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_rcmpneqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_rcmpeq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpeq">;
+
+def int_hexagon_A4_rcmpneq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_rcmpneq">;
+
+def int_hexagon_C2_bitsset :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsset">;
+
+def int_hexagon_C2_bitsclr :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclr">;
+
+def int_hexagon_C4_nbitsset :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsset">;
+
+def int_hexagon_C4_nbitsclr :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclr">;
+
+def int_hexagon_C2_cmpeqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpeqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_cmpgti :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_cmpgtui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_cmpgei :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgei", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_cmpgeui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpgeui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_cmplt :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmplt">;
+
+def int_hexagon_C2_cmpltu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_cmpltu">;
+
+def int_hexagon_C2_bitsclri :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_bitsclri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C4_nbitsclri :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_nbitsclri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C4_cmpneqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C4_cmpltei :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpltei", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C4_cmplteui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C4_cmpneq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmpneq">;
+
+def int_hexagon_C4_cmplte :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplte">;
+
+def int_hexagon_C4_cmplteu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_cmplteu">;
+
+def int_hexagon_C2_and :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_and">;
+
+def int_hexagon_C2_or :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_or">;
+
+def int_hexagon_C2_xor :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_xor">;
+
+def int_hexagon_C2_andn :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_andn">;
+
+def int_hexagon_C2_not :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_not">;
+
+def int_hexagon_C2_orn :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_orn">;
+
+def int_hexagon_C4_and_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_and">;
+
+def int_hexagon_C4_and_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_or">;
+
+def int_hexagon_C4_or_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_and">;
+
+def int_hexagon_C4_or_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_or">;
+
+def int_hexagon_C4_and_andn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_andn">;
+
+def int_hexagon_C4_and_orn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_and_orn">;
+
+def int_hexagon_C4_or_andn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_andn">;
+
+def int_hexagon_C4_or_orn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C4_or_orn">;
+
+def int_hexagon_C2_pxfer_map :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_pxfer_map">;
+
+def int_hexagon_C2_any8 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_any8">;
+
+def int_hexagon_C2_all8 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_all8">;
+
+def int_hexagon_C2_vitpack :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C2_vitpack">;
+
+def int_hexagon_C2_mux :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_mux">;
+
+def int_hexagon_C2_muxii :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxii", [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_C2_muxir :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxir", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_C2_muxri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_C2_muxri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_C2_vmux :
+Hexagon_i64_i32i64i64_Intrinsic<"HEXAGON_C2_vmux">;
+
+def int_hexagon_C2_mask :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_C2_mask">;
+
+def int_hexagon_A2_vcmpbeq :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpbeq">;
+
+def int_hexagon_A4_vcmpbeqi :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbeqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmpbeq_any :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A4_vcmpbeq_any">;
+
+def int_hexagon_A2_vcmpbgtu :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpbgtu">;
+
+def int_hexagon_A4_vcmpbgtui :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmpbgt :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A4_vcmpbgt">;
+
+def int_hexagon_A4_vcmpbgti :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpbgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmpbeq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeq">;
+
+def int_hexagon_A4_cmpbeqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbeqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmpbgtu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtu">;
+
+def int_hexagon_A4_cmpbgtui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmpbgt :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgt">;
+
+def int_hexagon_A4_cmpbgti :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpbgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_vcmpheq :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpheq">;
+
+def int_hexagon_A2_vcmphgt :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmphgt">;
+
+def int_hexagon_A2_vcmphgtu :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmphgtu">;
+
+def int_hexagon_A4_vcmpheqi :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpheqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmphgti :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmphgtui :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmphgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmpheq :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheq">;
+
+def int_hexagon_A4_cmphgt :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgt">;
+
+def int_hexagon_A4_cmphgtu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtu">;
+
+def int_hexagon_A4_cmpheqi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmpheqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmphgti :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cmphgtui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cmphgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_vcmpweq :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpweq">;
+
+def int_hexagon_A2_vcmpwgt :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpwgt">;
+
+def int_hexagon_A2_vcmpwgtu :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A2_vcmpwgtu">;
+
+def int_hexagon_A4_vcmpweqi :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpweqi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmpwgti :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_vcmpwgtui :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_vcmpwgtui", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_boundscheck :
+Hexagon_i32_i32i64_Intrinsic<"HEXAGON_A4_boundscheck">;
+
+def int_hexagon_A4_tlbmatch :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_A4_tlbmatch">;
+
+def int_hexagon_C2_tfrpr :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_tfrpr">;
+
+def int_hexagon_C2_tfrrp :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_C2_tfrrp">;
+
+def int_hexagon_C4_fastcorner9 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_fastcorner9">;
+
+def int_hexagon_C4_fastcorner9_not :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_C4_fastcorner9_not">;
+
+def int_hexagon_M2_mpy_acc_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s0">;
+
+def int_hexagon_M2_mpy_acc_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hh_s1">;
+
+def int_hexagon_M2_mpy_acc_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s0">;
+
+def int_hexagon_M2_mpy_acc_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_hl_s1">;
+
+def int_hexagon_M2_mpy_acc_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s0">;
+
+def int_hexagon_M2_mpy_acc_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_lh_s1">;
+
+def int_hexagon_M2_mpy_acc_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s0">;
+
+def int_hexagon_M2_mpy_acc_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_ll_s1">;
+
+def int_hexagon_M2_mpy_nac_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s0">;
+
+def int_hexagon_M2_mpy_nac_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hh_s1">;
+
+def int_hexagon_M2_mpy_nac_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s0">;
+
+def int_hexagon_M2_mpy_nac_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_hl_s1">;
+
+def int_hexagon_M2_mpy_nac_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s0">;
+
+def int_hexagon_M2_mpy_nac_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_lh_s1">;
+
+def int_hexagon_M2_mpy_nac_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s0">;
+
+def int_hexagon_M2_mpy_nac_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_ll_s1">;
+
+def int_hexagon_M2_mpy_acc_sat_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s0">;
+
+def int_hexagon_M2_mpy_acc_sat_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hh_s1">;
+
+def int_hexagon_M2_mpy_acc_sat_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s0">;
+
+def int_hexagon_M2_mpy_acc_sat_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_hl_s1">;
+
+def int_hexagon_M2_mpy_acc_sat_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s0">;
+
+def int_hexagon_M2_mpy_acc_sat_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_lh_s1">;
+
+def int_hexagon_M2_mpy_acc_sat_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s0">;
+
+def int_hexagon_M2_mpy_acc_sat_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_acc_sat_ll_s1">;
+
+def int_hexagon_M2_mpy_nac_sat_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s0">;
+
+def int_hexagon_M2_mpy_nac_sat_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hh_s1">;
+
+def int_hexagon_M2_mpy_nac_sat_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s0">;
+
+def int_hexagon_M2_mpy_nac_sat_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_hl_s1">;
+
+def int_hexagon_M2_mpy_nac_sat_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s0">;
+
+def int_hexagon_M2_mpy_nac_sat_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_lh_s1">;
+
+def int_hexagon_M2_mpy_nac_sat_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s0">;
+
+def int_hexagon_M2_mpy_nac_sat_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpy_nac_sat_ll_s1">;
+
+def int_hexagon_M2_mpy_hh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hh_s0">;
+
+def int_hexagon_M2_mpy_hh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hh_s1">;
+
+def int_hexagon_M2_mpy_hl_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hl_s0">;
+
+def int_hexagon_M2_mpy_hl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_hl_s1">;
+
+def int_hexagon_M2_mpy_lh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_lh_s0">;
+
+def int_hexagon_M2_mpy_lh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_lh_s1">;
+
+def int_hexagon_M2_mpy_ll_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_ll_s0">;
+
+def int_hexagon_M2_mpy_ll_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_ll_s1">;
+
+def int_hexagon_M2_mpy_sat_hh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s0">;
+
+def int_hexagon_M2_mpy_sat_hh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hh_s1">;
+
+def int_hexagon_M2_mpy_sat_hl_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s0">;
+
+def int_hexagon_M2_mpy_sat_hl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_hl_s1">;
+
+def int_hexagon_M2_mpy_sat_lh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s0">;
+
+def int_hexagon_M2_mpy_sat_lh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_lh_s1">;
+
+def int_hexagon_M2_mpy_sat_ll_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s0">;
+
+def int_hexagon_M2_mpy_sat_ll_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_ll_s1">;
+
+def int_hexagon_M2_mpy_rnd_hh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s0">;
+
+def int_hexagon_M2_mpy_rnd_hh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hh_s1">;
+
+def int_hexagon_M2_mpy_rnd_hl_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s0">;
+
+def int_hexagon_M2_mpy_rnd_hl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_hl_s1">;
+
+def int_hexagon_M2_mpy_rnd_lh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s0">;
+
+def int_hexagon_M2_mpy_rnd_lh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_lh_s1">;
+
+def int_hexagon_M2_mpy_rnd_ll_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s0">;
+
+def int_hexagon_M2_mpy_rnd_ll_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_rnd_ll_s1">;
+
+def int_hexagon_M2_mpy_sat_rnd_hh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s0">;
+
+def int_hexagon_M2_mpy_sat_rnd_hh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hh_s1">;
+
+def int_hexagon_M2_mpy_sat_rnd_hl_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s0">;
+
+def int_hexagon_M2_mpy_sat_rnd_hl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_hl_s1">;
+
+def int_hexagon_M2_mpy_sat_rnd_lh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s0">;
+
+def int_hexagon_M2_mpy_sat_rnd_lh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_lh_s1">;
+
+def int_hexagon_M2_mpy_sat_rnd_ll_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s0">;
+
+def int_hexagon_M2_mpy_sat_rnd_ll_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_sat_rnd_ll_s1">;
+
+def int_hexagon_M2_mpyd_acc_hh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s0">;
+
+def int_hexagon_M2_mpyd_acc_hh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hh_s1">;
+
+def int_hexagon_M2_mpyd_acc_hl_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s0">;
+
+def int_hexagon_M2_mpyd_acc_hl_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_hl_s1">;
+
+def int_hexagon_M2_mpyd_acc_lh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s0">;
+
+def int_hexagon_M2_mpyd_acc_lh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_lh_s1">;
+
+def int_hexagon_M2_mpyd_acc_ll_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s0">;
+
+def int_hexagon_M2_mpyd_acc_ll_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_acc_ll_s1">;
+
+def int_hexagon_M2_mpyd_nac_hh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s0">;
+
+def int_hexagon_M2_mpyd_nac_hh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hh_s1">;
+
+def int_hexagon_M2_mpyd_nac_hl_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s0">;
+
+def int_hexagon_M2_mpyd_nac_hl_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_hl_s1">;
+
+def int_hexagon_M2_mpyd_nac_lh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s0">;
+
+def int_hexagon_M2_mpyd_nac_lh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_lh_s1">;
+
+def int_hexagon_M2_mpyd_nac_ll_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s0">;
+
+def int_hexagon_M2_mpyd_nac_ll_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyd_nac_ll_s1">;
+
+def int_hexagon_M2_mpyd_hh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hh_s0">;
+
+def int_hexagon_M2_mpyd_hh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hh_s1">;
+
+def int_hexagon_M2_mpyd_hl_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hl_s0">;
+
+def int_hexagon_M2_mpyd_hl_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_hl_s1">;
+
+def int_hexagon_M2_mpyd_lh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_lh_s0">;
+
+def int_hexagon_M2_mpyd_lh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_lh_s1">;
+
+def int_hexagon_M2_mpyd_ll_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_ll_s0">;
+
+def int_hexagon_M2_mpyd_ll_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_ll_s1">;
+
+def int_hexagon_M2_mpyd_rnd_hh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s0">;
+
+def int_hexagon_M2_mpyd_rnd_hh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hh_s1">;
+
+def int_hexagon_M2_mpyd_rnd_hl_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s0">;
+
+def int_hexagon_M2_mpyd_rnd_hl_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_hl_s1">;
+
+def int_hexagon_M2_mpyd_rnd_lh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s0">;
+
+def int_hexagon_M2_mpyd_rnd_lh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_lh_s1">;
+
+def int_hexagon_M2_mpyd_rnd_ll_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s0">;
+
+def int_hexagon_M2_mpyd_rnd_ll_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyd_rnd_ll_s1">;
+
+def int_hexagon_M2_mpyu_acc_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s0">;
+
+def int_hexagon_M2_mpyu_acc_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hh_s1">;
+
+def int_hexagon_M2_mpyu_acc_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s0">;
+
+def int_hexagon_M2_mpyu_acc_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_hl_s1">;
+
+def int_hexagon_M2_mpyu_acc_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s0">;
+
+def int_hexagon_M2_mpyu_acc_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_lh_s1">;
+
+def int_hexagon_M2_mpyu_acc_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s0">;
+
+def int_hexagon_M2_mpyu_acc_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_acc_ll_s1">;
+
+def int_hexagon_M2_mpyu_nac_hh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s0">;
+
+def int_hexagon_M2_mpyu_nac_hh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hh_s1">;
+
+def int_hexagon_M2_mpyu_nac_hl_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s0">;
+
+def int_hexagon_M2_mpyu_nac_hl_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_hl_s1">;
+
+def int_hexagon_M2_mpyu_nac_lh_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s0">;
+
+def int_hexagon_M2_mpyu_nac_lh_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_lh_s1">;
+
+def int_hexagon_M2_mpyu_nac_ll_s0 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s0">;
+
+def int_hexagon_M2_mpyu_nac_ll_s1 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mpyu_nac_ll_s1">;
+
+def int_hexagon_M2_mpyu_hh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hh_s0">;
+
+def int_hexagon_M2_mpyu_hh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hh_s1">;
+
+def int_hexagon_M2_mpyu_hl_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hl_s0">;
+
+def int_hexagon_M2_mpyu_hl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_hl_s1">;
+
+def int_hexagon_M2_mpyu_lh_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_lh_s0">;
+
+def int_hexagon_M2_mpyu_lh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_lh_s1">;
+
+def int_hexagon_M2_mpyu_ll_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_ll_s0">;
+
+def int_hexagon_M2_mpyu_ll_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_ll_s1">;
+
+def int_hexagon_M2_mpyud_acc_hh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s0">;
+
+def int_hexagon_M2_mpyud_acc_hh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hh_s1">;
+
+def int_hexagon_M2_mpyud_acc_hl_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s0">;
+
+def int_hexagon_M2_mpyud_acc_hl_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_hl_s1">;
+
+def int_hexagon_M2_mpyud_acc_lh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s0">;
+
+def int_hexagon_M2_mpyud_acc_lh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_lh_s1">;
+
+def int_hexagon_M2_mpyud_acc_ll_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s0">;
+
+def int_hexagon_M2_mpyud_acc_ll_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_acc_ll_s1">;
+
+def int_hexagon_M2_mpyud_nac_hh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s0">;
+
+def int_hexagon_M2_mpyud_nac_hh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hh_s1">;
+
+def int_hexagon_M2_mpyud_nac_hl_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s0">;
+
+def int_hexagon_M2_mpyud_nac_hl_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_hl_s1">;
+
+def int_hexagon_M2_mpyud_nac_lh_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s0">;
+
+def int_hexagon_M2_mpyud_nac_lh_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_lh_s1">;
+
+def int_hexagon_M2_mpyud_nac_ll_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s0">;
+
+def int_hexagon_M2_mpyud_nac_ll_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_mpyud_nac_ll_s1">;
+
+def int_hexagon_M2_mpyud_hh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hh_s0">;
+
+def int_hexagon_M2_mpyud_hh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hh_s1">;
+
+def int_hexagon_M2_mpyud_hl_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hl_s0">;
+
+def int_hexagon_M2_mpyud_hl_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_hl_s1">;
+
+def int_hexagon_M2_mpyud_lh_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_lh_s0">;
+
+def int_hexagon_M2_mpyud_lh_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_lh_s1">;
+
+def int_hexagon_M2_mpyud_ll_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_ll_s0">;
+
+def int_hexagon_M2_mpyud_ll_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_mpyud_ll_s1">;
+
+def int_hexagon_M2_mpysmi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysmi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_M2_macsip :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsip", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M2_macsin :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_macsin", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M2_dpmpyss_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_s0">;
+
+def int_hexagon_M2_dpmpyss_acc_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_acc_s0">;
+
+def int_hexagon_M2_dpmpyss_nac_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_nac_s0">;
+
+def int_hexagon_M2_dpmpyuu_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_s0">;
+
+def int_hexagon_M2_dpmpyuu_acc_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_acc_s0">;
+
+def int_hexagon_M2_dpmpyuu_nac_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_dpmpyuu_nac_s0">;
+
+def int_hexagon_M2_mpy_up :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up">;
+
+def int_hexagon_M2_mpy_up_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up_s1">;
+
+def int_hexagon_M2_mpy_up_s1_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpy_up_s1_sat">;
+
+def int_hexagon_M2_mpyu_up :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyu_up">;
+
+def int_hexagon_M2_mpysu_up :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpysu_up">;
+
+def int_hexagon_M2_dpmpyss_rnd_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_dpmpyss_rnd_s0">;
+
+def int_hexagon_M4_mac_up_s1_sat :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mac_up_s1_sat">;
+
+def int_hexagon_M4_nac_up_s1_sat :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_nac_up_s1_sat">;
+
+def int_hexagon_M2_mpyi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyi">;
+
+def int_hexagon_M2_mpyui :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_mpyui">;
+
+def int_hexagon_M2_maci :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_maci">;
+
+def int_hexagon_M2_acci :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_acci">;
+
+def int_hexagon_M2_accii :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_accii", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M2_nacci :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_nacci">;
+
+def int_hexagon_M2_naccii :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_naccii", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M2_subacc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_subacc">;
+
+def int_hexagon_M4_mpyrr_addr :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addr">;
+
+def int_hexagon_M4_mpyri_addr_u2 :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr_u2", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_M4_mpyri_addr :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addr", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M4_mpyri_addi :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyri_addi", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M4_mpyrr_addi :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_mpyrr_addi", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_M2_vmpy2s_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s0">;
+
+def int_hexagon_M2_vmpy2s_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s1">;
+
+def int_hexagon_M2_vmac2s_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2s_s0">;
+
+def int_hexagon_M2_vmac2s_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2s_s1">;
+
+def int_hexagon_M2_vmpy2su_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2su_s0">;
+
+def int_hexagon_M2_vmpy2su_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_vmpy2su_s1">;
+
+def int_hexagon_M2_vmac2su_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2su_s0">;
+
+def int_hexagon_M2_vmac2su_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2su_s1">;
+
+def int_hexagon_M2_vmpy2s_s0pack :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s0pack">;
+
+def int_hexagon_M2_vmpy2s_s1pack :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_vmpy2s_s1pack">;
+
+def int_hexagon_M2_vmac2 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_vmac2">;
+
+def int_hexagon_M2_vmpy2es_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vmpy2es_s0">;
+
+def int_hexagon_M2_vmpy2es_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vmpy2es_s1">;
+
+def int_hexagon_M2_vmac2es_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es_s0">;
+
+def int_hexagon_M2_vmac2es_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es_s1">;
+
+def int_hexagon_M2_vmac2es :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vmac2es">;
+
+def int_hexagon_M2_vrmac_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrmac_s0">;
+
+def int_hexagon_M2_vrmpy_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrmpy_s0">;
+
+def int_hexagon_M2_vdmpyrs_s0 :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vdmpyrs_s0">;
+
+def int_hexagon_M2_vdmpyrs_s1 :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vdmpyrs_s1">;
+
+def int_hexagon_M5_vrmpybuu :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vrmpybuu">;
+
+def int_hexagon_M5_vrmacbuu :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vrmacbuu">;
+
+def int_hexagon_M5_vrmpybsu :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vrmpybsu">;
+
+def int_hexagon_M5_vrmacbsu :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vrmacbsu">;
+
+def int_hexagon_M5_vmpybuu :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M5_vmpybuu">;
+
+def int_hexagon_M5_vmpybsu :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M5_vmpybsu">;
+
+def int_hexagon_M5_vmacbuu :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M5_vmacbuu">;
+
+def int_hexagon_M5_vmacbsu :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M5_vmacbsu">;
+
+def int_hexagon_M5_vdmpybsu :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M5_vdmpybsu">;
+
+def int_hexagon_M5_vdmacbsu :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M5_vdmacbsu">;
+
+def int_hexagon_M2_vdmacs_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vdmacs_s0">;
+
+def int_hexagon_M2_vdmacs_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vdmacs_s1">;
+
+def int_hexagon_M2_vdmpys_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vdmpys_s0">;
+
+def int_hexagon_M2_vdmpys_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vdmpys_s1">;
+
+def int_hexagon_M2_cmpyrs_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrs_s0">;
+
+def int_hexagon_M2_cmpyrs_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrs_s1">;
+
+def int_hexagon_M2_cmpyrsc_s0 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrsc_s0">;
+
+def int_hexagon_M2_cmpyrsc_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_cmpyrsc_s1">;
+
+def int_hexagon_M2_cmacs_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacs_s0">;
+
+def int_hexagon_M2_cmacs_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacs_s1">;
+
+def int_hexagon_M2_cmacsc_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacsc_s0">;
+
+def int_hexagon_M2_cmacsc_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacsc_s1">;
+
+def int_hexagon_M2_cmpys_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpys_s0">;
+
+def int_hexagon_M2_cmpys_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpys_s1">;
+
+def int_hexagon_M2_cmpysc_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpysc_s0">;
+
+def int_hexagon_M2_cmpysc_s1 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpysc_s1">;
+
+def int_hexagon_M2_cnacs_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacs_s0">;
+
+def int_hexagon_M2_cnacs_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacs_s1">;
+
+def int_hexagon_M2_cnacsc_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacsc_s0">;
+
+def int_hexagon_M2_cnacsc_s1 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cnacsc_s1">;
+
+def int_hexagon_M2_vrcmpys_s1 :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_s1">;
+
+def int_hexagon_M2_vrcmpys_acc_s1 :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_acc_s1">;
+
+def int_hexagon_M2_vrcmpys_s1rp :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M2_vrcmpys_s1rp">;
+
+def int_hexagon_M2_mmacls_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_s0">;
+
+def int_hexagon_M2_mmacls_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_s1">;
+
+def int_hexagon_M2_mmachs_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s0">;
+
+def int_hexagon_M2_mmachs_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_s1">;
+
+def int_hexagon_M2_mmpyl_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_s0">;
+
+def int_hexagon_M2_mmpyl_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_s1">;
+
+def int_hexagon_M2_mmpyh_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_s0">;
+
+def int_hexagon_M2_mmpyh_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_s1">;
+
+def int_hexagon_M2_mmacls_rs0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_rs0">;
+
+def int_hexagon_M2_mmacls_rs1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacls_rs1">;
+
+def int_hexagon_M2_mmachs_rs0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_rs0">;
+
+def int_hexagon_M2_mmachs_rs1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmachs_rs1">;
+
+def int_hexagon_M2_mmpyl_rs0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_rs0">;
+
+def int_hexagon_M2_mmpyl_rs1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyl_rs1">;
+
+def int_hexagon_M2_mmpyh_rs0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_rs0">;
+
+def int_hexagon_M2_mmpyh_rs1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyh_rs1">;
+
+def int_hexagon_M4_vrmpyeh_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_s0">;
+
+def int_hexagon_M4_vrmpyeh_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_s1">;
+
+def int_hexagon_M4_vrmpyeh_acc_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s0">;
+
+def int_hexagon_M4_vrmpyeh_acc_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyeh_acc_s1">;
+
+def int_hexagon_M4_vrmpyoh_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_s0">;
+
+def int_hexagon_M4_vrmpyoh_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_s1">;
+
+def int_hexagon_M4_vrmpyoh_acc_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s0">;
+
+def int_hexagon_M4_vrmpyoh_acc_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_vrmpyoh_acc_s1">;
+
+def int_hexagon_M2_hmmpyl_rs1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyl_rs1">;
+
+def int_hexagon_M2_hmmpyh_rs1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyh_rs1">;
+
+def int_hexagon_M2_hmmpyl_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyl_s1">;
+
+def int_hexagon_M2_hmmpyh_s1 :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_M2_hmmpyh_s1">;
+
+def int_hexagon_M2_mmaculs_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_s0">;
+
+def int_hexagon_M2_mmaculs_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_s1">;
+
+def int_hexagon_M2_mmacuhs_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_s0">;
+
+def int_hexagon_M2_mmacuhs_s1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_s1">;
+
+def int_hexagon_M2_mmpyul_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_s0">;
+
+def int_hexagon_M2_mmpyul_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_s1">;
+
+def int_hexagon_M2_mmpyuh_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_s0">;
+
+def int_hexagon_M2_mmpyuh_s1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_s1">;
+
+def int_hexagon_M2_mmaculs_rs0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_rs0">;
+
+def int_hexagon_M2_mmaculs_rs1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmaculs_rs1">;
+
+def int_hexagon_M2_mmacuhs_rs0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_rs0">;
+
+def int_hexagon_M2_mmacuhs_rs1 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_mmacuhs_rs1">;
+
+def int_hexagon_M2_mmpyul_rs0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs0">;
+
+def int_hexagon_M2_mmpyul_rs1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyul_rs1">;
+
+def int_hexagon_M2_mmpyuh_rs0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs0">;
+
+def int_hexagon_M2_mmpyuh_rs1 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_mmpyuh_rs1">;
+
+def int_hexagon_M2_vrcmaci_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmaci_s0">;
+
+def int_hexagon_M2_vrcmacr_s0 :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmacr_s0">;
+
+def int_hexagon_M2_vrcmaci_s0c :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmaci_s0c">;
+
+def int_hexagon_M2_vrcmacr_s0c :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vrcmacr_s0c">;
+
+def int_hexagon_M2_cmaci_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmaci_s0">;
+
+def int_hexagon_M2_cmacr_s0 :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M2_cmacr_s0">;
+
+def int_hexagon_M2_vrcmpyi_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyi_s0">;
+
+def int_hexagon_M2_vrcmpyr_s0 :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyr_s0">;
+
+def int_hexagon_M2_vrcmpyi_s0c :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyi_s0c">;
+
+def int_hexagon_M2_vrcmpyr_s0c :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vrcmpyr_s0c">;
+
+def int_hexagon_M2_cmpyi_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpyi_s0">;
+
+def int_hexagon_M2_cmpyr_s0 :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M2_cmpyr_s0">;
+
+def int_hexagon_M4_cmpyi_wh :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyi_wh">;
+
+def int_hexagon_M4_cmpyr_wh :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_wh">;
+
+def int_hexagon_M4_cmpyi_whc :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyi_whc">;
+
+def int_hexagon_M4_cmpyr_whc :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_M4_cmpyr_whc">;
+
+def int_hexagon_M2_vcmpy_s0_sat_i :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_i">;
+
+def int_hexagon_M2_vcmpy_s0_sat_r :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s0_sat_r">;
+
+def int_hexagon_M2_vcmpy_s1_sat_i :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_i">;
+
+def int_hexagon_M2_vcmpy_s1_sat_r :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vcmpy_s1_sat_r">;
+
+def int_hexagon_M2_vcmac_s0_sat_i :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_i">;
+
+def int_hexagon_M2_vcmac_s0_sat_r :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M2_vcmac_s0_sat_r">;
+
+def int_hexagon_S2_vcrotate :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_vcrotate">;
+
+def int_hexagon_S4_vrcrotate_acc :
+Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate_acc", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S4_vrcrotate :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_vrcrotate", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_vcnegh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_vcnegh">;
+
+def int_hexagon_S2_vrcnegh :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vrcnegh">;
+
+def int_hexagon_M4_pmpyw :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M4_pmpyw">;
+
+def int_hexagon_M4_vpmpyh :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_M4_vpmpyh">;
+
+def int_hexagon_M4_pmpyw_acc :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M4_pmpyw_acc">;
+
+def int_hexagon_M4_vpmpyh_acc :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_M4_vpmpyh_acc">;
+
+def int_hexagon_A2_add :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_add">;
+
+def int_hexagon_A2_sub :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_sub">;
+
+def int_hexagon_A2_addsat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addsat">;
+
+def int_hexagon_A2_subsat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subsat">;
+
+def int_hexagon_A2_addi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_addh_l16_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_ll">;
+
+def int_hexagon_A2_addh_l16_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_hl">;
+
+def int_hexagon_A2_addh_l16_sat_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_sat_ll">;
+
+def int_hexagon_A2_addh_l16_sat_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_l16_sat_hl">;
+
+def int_hexagon_A2_subh_l16_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_ll">;
+
+def int_hexagon_A2_subh_l16_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_hl">;
+
+def int_hexagon_A2_subh_l16_sat_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_sat_ll">;
+
+def int_hexagon_A2_subh_l16_sat_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_l16_sat_hl">;
+
+def int_hexagon_A2_addh_h16_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_ll">;
+
+def int_hexagon_A2_addh_h16_lh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_lh">;
+
+def int_hexagon_A2_addh_h16_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_hl">;
+
+def int_hexagon_A2_addh_h16_hh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_hh">;
+
+def int_hexagon_A2_addh_h16_sat_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_ll">;
+
+def int_hexagon_A2_addh_h16_sat_lh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_lh">;
+
+def int_hexagon_A2_addh_h16_sat_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_hl">;
+
+def int_hexagon_A2_addh_h16_sat_hh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_addh_h16_sat_hh">;
+
+def int_hexagon_A2_subh_h16_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_ll">;
+
+def int_hexagon_A2_subh_h16_lh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_lh">;
+
+def int_hexagon_A2_subh_h16_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_hl">;
+
+def int_hexagon_A2_subh_h16_hh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_hh">;
+
+def int_hexagon_A2_subh_h16_sat_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_ll">;
+
+def int_hexagon_A2_subh_h16_sat_lh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_lh">;
+
+def int_hexagon_A2_subh_h16_sat_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_hl">;
+
+def int_hexagon_A2_subh_h16_sat_hh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subh_h16_sat_hh">;
+
+def int_hexagon_A2_aslh :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_aslh">;
+
+def int_hexagon_A2_asrh :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_asrh">;
+
+def int_hexagon_A2_addp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addp">;
+
+def int_hexagon_A2_addpsat :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_addpsat">;
+
+def int_hexagon_A2_addsp :
+Hexagon_i64_i32i64_Intrinsic<"HEXAGON_A2_addsp">;
+
+def int_hexagon_A2_subp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_subp">;
+
+def int_hexagon_A2_neg :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_neg">;
+
+def int_hexagon_A2_negsat :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_negsat">;
+
+def int_hexagon_A2_abs :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_abs">;
+
+def int_hexagon_A2_abssat :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_abssat">;
+
+def int_hexagon_A2_vconj :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vconj">;
+
+def int_hexagon_A2_negp :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_negp">;
+
+def int_hexagon_A2_absp :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_absp">;
+
+def int_hexagon_A2_max :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_max">;
+
+def int_hexagon_A2_maxu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_maxu">;
+
+def int_hexagon_A2_min :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_min">;
+
+def int_hexagon_A2_minu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_minu">;
+
+def int_hexagon_A2_maxp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxp">;
+
+def int_hexagon_A2_maxup :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_maxup">;
+
+def int_hexagon_A2_minp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_minp">;
+
+def int_hexagon_A2_minup :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_minup">;
+
+def int_hexagon_A2_tfr :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfr">;
+
+def int_hexagon_A2_tfrsi :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_tfrsi", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_A2_tfrp :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_tfrp">;
+
+def int_hexagon_A2_tfrpi :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_tfrpi", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_A2_zxtb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_zxtb">;
+
+def int_hexagon_A2_sxtb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sxtb">;
+
+def int_hexagon_A2_zxth :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_zxth">;
+
+def int_hexagon_A2_sxth :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sxth">;
+
+def int_hexagon_A2_combinew :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combinew">;
+
+def int_hexagon_A4_combineri :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_combineir :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_combineir", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_A2_combineii :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A2_combineii", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_combine_hh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_hh">;
+
+def int_hexagon_A2_combine_hl :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_hl">;
+
+def int_hexagon_A2_combine_lh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_lh">;
+
+def int_hexagon_A2_combine_ll :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_combine_ll">;
+
+def int_hexagon_A2_tfril :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfril", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_tfrih :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_tfrih", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_and :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_and">;
+
+def int_hexagon_A2_or :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_or">;
+
+def int_hexagon_A2_xor :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_xor">;
+
+def int_hexagon_A2_not :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_not">;
+
+def int_hexagon_M2_xor_xacc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_xor_xacc">;
+
+def int_hexagon_M4_xor_xacc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M4_xor_xacc">;
+
+def int_hexagon_A4_andn :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_andn">;
+
+def int_hexagon_A4_orn :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_orn">;
+
+def int_hexagon_A4_andnp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A4_andnp">;
+
+def int_hexagon_A4_ornp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A4_ornp">;
+
+def int_hexagon_S4_addaddi :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addaddi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_subaddi :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subaddi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_M4_and_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_and">;
+
+def int_hexagon_M4_and_andn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_andn">;
+
+def int_hexagon_M4_and_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_or">;
+
+def int_hexagon_M4_and_xor :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_and_xor">;
+
+def int_hexagon_M4_or_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_and">;
+
+def int_hexagon_M4_or_andn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_andn">;
+
+def int_hexagon_M4_or_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_or">;
+
+def int_hexagon_M4_or_xor :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_or_xor">;
+
+def int_hexagon_S4_or_andix :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andix", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_or_andi :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_andi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_or_ori :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_or_ori", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_M4_xor_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_and">;
+
+def int_hexagon_M4_xor_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_or">;
+
+def int_hexagon_M4_xor_andn :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M4_xor_andn">;
+
+def int_hexagon_A2_subri :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_subri", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_A2_andir :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_andir", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_orir :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_orir", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A2_andp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_andp">;
+
+def int_hexagon_A2_orp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_orp">;
+
+def int_hexagon_A2_xorp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_xorp">;
+
+def int_hexagon_A2_notp :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_notp">;
+
+def int_hexagon_A2_sxtw :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_A2_sxtw">;
+
+def int_hexagon_A2_sat :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_A2_sat">;
+
+def int_hexagon_A2_roundsat :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_A2_roundsat">;
+
+def int_hexagon_A2_sath :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_sath">;
+
+def int_hexagon_A2_satuh :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satuh">;
+
+def int_hexagon_A2_satub :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satub">;
+
+def int_hexagon_A2_satb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_satb">;
+
+def int_hexagon_A2_vaddub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddub">;
+
+def int_hexagon_A2_vaddb_map :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddb_map">;
+
+def int_hexagon_A2_vaddubs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddubs">;
+
+def int_hexagon_A2_vaddh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddh">;
+
+def int_hexagon_A2_vaddhs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddhs">;
+
+def int_hexagon_A2_vadduhs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vadduhs">;
+
+def int_hexagon_A5_vaddhubs :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A5_vaddhubs">;
+
+def int_hexagon_A2_vaddw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddw">;
+
+def int_hexagon_A2_vaddws :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vaddws">;
+
+def int_hexagon_S4_vxaddsubw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubw">;
+
+def int_hexagon_S4_vxsubaddw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddw">;
+
+def int_hexagon_S4_vxaddsubh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubh">;
+
+def int_hexagon_S4_vxsubaddh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddh">;
+
+def int_hexagon_S4_vxaddsubhr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxaddsubhr">;
+
+def int_hexagon_S4_vxsubaddhr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_vxsubaddhr">;
+
+def int_hexagon_A2_svavgh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svavgh">;
+
+def int_hexagon_A2_svavghs :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svavghs">;
+
+def int_hexagon_A2_svnavgh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svnavgh">;
+
+def int_hexagon_A2_svaddh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svaddh">;
+
+def int_hexagon_A2_svaddhs :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svaddhs">;
+
+def int_hexagon_A2_svadduhs :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svadduhs">;
+
+def int_hexagon_A2_svsubh :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubh">;
+
+def int_hexagon_A2_svsubhs :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubhs">;
+
+def int_hexagon_A2_svsubuhs :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A2_svsubuhs">;
+
+def int_hexagon_A2_vraddub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vraddub">;
+
+def int_hexagon_A2_vraddub_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_A2_vraddub_acc">;
+
+def int_hexagon_M2_vraddh :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vraddh">;
+
+def int_hexagon_M2_vradduh :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M2_vradduh">;
+
+def int_hexagon_A2_vsubub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubub">;
+
+def int_hexagon_A2_vsubb_map :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubb_map">;
+
+def int_hexagon_A2_vsububs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsububs">;
+
+def int_hexagon_A2_vsubh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubh">;
+
+def int_hexagon_A2_vsubhs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubhs">;
+
+def int_hexagon_A2_vsubuhs :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubuhs">;
+
+def int_hexagon_A2_vsubw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubw">;
+
+def int_hexagon_A2_vsubws :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vsubws">;
+
+def int_hexagon_A2_vabsh :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabsh">;
+
+def int_hexagon_A2_vabshsat :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabshsat">;
+
+def int_hexagon_A2_vabsw :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabsw">;
+
+def int_hexagon_A2_vabswsat :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_A2_vabswsat">;
+
+def int_hexagon_M2_vabsdiffw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vabsdiffw">;
+
+def int_hexagon_M2_vabsdiffh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M2_vabsdiffh">;
+
+def int_hexagon_A2_vrsadub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vrsadub">;
+
+def int_hexagon_A2_vrsadub_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_A2_vrsadub_acc">;
+
+def int_hexagon_A2_vavgub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgub">;
+
+def int_hexagon_A2_vavguh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguh">;
+
+def int_hexagon_A2_vavgh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgh">;
+
+def int_hexagon_A2_vnavgh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgh">;
+
+def int_hexagon_A2_vavgw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgw">;
+
+def int_hexagon_A2_vnavgw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgw">;
+
+def int_hexagon_A2_vavgwr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgwr">;
+
+def int_hexagon_A2_vnavgwr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgwr">;
+
+def int_hexagon_A2_vavgwcr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgwcr">;
+
+def int_hexagon_A2_vnavgwcr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavgwcr">;
+
+def int_hexagon_A2_vavghcr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavghcr">;
+
+def int_hexagon_A2_vnavghcr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavghcr">;
+
+def int_hexagon_A2_vavguw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguw">;
+
+def int_hexagon_A2_vavguwr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguwr">;
+
+def int_hexagon_A2_vavgubr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavgubr">;
+
+def int_hexagon_A2_vavguhr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavguhr">;
+
+def int_hexagon_A2_vavghr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vavghr">;
+
+def int_hexagon_A2_vnavghr :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vnavghr">;
+
+def int_hexagon_A4_round_ri :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_round_rr :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_rr">;
+
+def int_hexagon_A4_round_ri_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_ri_sat", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_round_rr_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_round_rr_sat">;
+
+def int_hexagon_A4_cround_ri :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_ri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_cround_rr :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_cround_rr">;
+
+def int_hexagon_A4_vrminh :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminh">;
+
+def int_hexagon_A4_vrmaxh :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxh">;
+
+def int_hexagon_A4_vrminuh :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminuh">;
+
+def int_hexagon_A4_vrmaxuh :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuh">;
+
+def int_hexagon_A4_vrminw :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminw">;
+
+def int_hexagon_A4_vrmaxw :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxw">;
+
+def int_hexagon_A4_vrminuw :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrminuw">;
+
+def int_hexagon_A4_vrmaxuw :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_A4_vrmaxuw">;
+
+def int_hexagon_A2_vminb :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminb">;
+
+def int_hexagon_A2_vmaxb :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxb">;
+
+def int_hexagon_A2_vminub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminub">;
+
+def int_hexagon_A2_vmaxub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxub">;
+
+def int_hexagon_A2_vminh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminh">;
+
+def int_hexagon_A2_vmaxh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxh">;
+
+def int_hexagon_A2_vminuh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminuh">;
+
+def int_hexagon_A2_vmaxuh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxuh">;
+
+def int_hexagon_A2_vminw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminw">;
+
+def int_hexagon_A2_vmaxw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxw">;
+
+def int_hexagon_A2_vminuw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vminuw">;
+
+def int_hexagon_A2_vmaxuw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_A2_vmaxuw">;
+
+def int_hexagon_A4_modwrapu :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A4_modwrapu">;
+
+def int_hexagon_F2_sfadd :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfadd", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfsub :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfsub", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfmpy :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmpy", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffma :
+Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffma", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffma_sc :
+Hexagon_float_floatfloatfloati32_Intrinsic<"HEXAGON_F2_sffma_sc", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffms :
+Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffma_lib :
+Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffma_lib", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffms_lib :
+Hexagon_float_floatfloatfloat_Intrinsic<"HEXAGON_F2_sffms_lib", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfcmpeq :
+Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpeq", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfcmpgt :
+Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpgt", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfcmpge :
+Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpge", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfcmpuo :
+Hexagon_i32_floatfloat_Intrinsic<"HEXAGON_F2_sfcmpuo", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfmax :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmax", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfmin :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sfmin", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sfclass :
+Hexagon_i32_floati32_Intrinsic<"HEXAGON_F2_sfclass", [IntrNoMem, Throws, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_F2_sfimm_p :
+Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_p", [IntrNoMem, Throws, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_F2_sfimm_n :
+Hexagon_float_i32_Intrinsic<"HEXAGON_F2_sfimm_n", [IntrNoMem, Throws, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_F2_sffixupn :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sffixupn", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffixupd :
+Hexagon_float_floatfloat_Intrinsic<"HEXAGON_F2_sffixupd", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_sffixupr :
+Hexagon_float_float_Intrinsic<"HEXAGON_F2_sffixupr", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfcmpeq :
+Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpeq", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfcmpgt :
+Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpgt", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfcmpge :
+Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpge", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfcmpuo :
+Hexagon_i32_doubledouble_Intrinsic<"HEXAGON_F2_dfcmpuo", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfclass :
+Hexagon_i32_doublei32_Intrinsic<"HEXAGON_F2_dfclass", [IntrNoMem, Throws, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_F2_dfimm_p :
+Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_p", [IntrNoMem, Throws, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_F2_dfimm_n :
+Hexagon_double_i32_Intrinsic<"HEXAGON_F2_dfimm_n", [IntrNoMem, Throws, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_F2_conv_sf2df :
+Hexagon_double_float_Intrinsic<"HEXAGON_F2_conv_sf2df">;
+
+def int_hexagon_F2_conv_df2sf :
+Hexagon_float_double_Intrinsic<"HEXAGON_F2_conv_df2sf">;
+
+def int_hexagon_F2_conv_uw2sf :
+Hexagon_float_i32_Intrinsic<"HEXAGON_F2_conv_uw2sf">;
+
+def int_hexagon_F2_conv_uw2df :
+Hexagon_double_i32_Intrinsic<"HEXAGON_F2_conv_uw2df">;
+
+def int_hexagon_F2_conv_w2sf :
+Hexagon_float_i32_Intrinsic<"HEXAGON_F2_conv_w2sf">;
+
+def int_hexagon_F2_conv_w2df :
+Hexagon_double_i32_Intrinsic<"HEXAGON_F2_conv_w2df">;
+
+def int_hexagon_F2_conv_ud2sf :
+Hexagon_float_i64_Intrinsic<"HEXAGON_F2_conv_ud2sf">;
+
+def int_hexagon_F2_conv_ud2df :
+Hexagon_double_i64_Intrinsic<"HEXAGON_F2_conv_ud2df">;
+
+def int_hexagon_F2_conv_d2sf :
+Hexagon_float_i64_Intrinsic<"HEXAGON_F2_conv_d2sf">;
+
+def int_hexagon_F2_conv_d2df :
+Hexagon_double_i64_Intrinsic<"HEXAGON_F2_conv_d2df">;
+
+def int_hexagon_F2_conv_sf2uw :
+Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2uw">;
+
+def int_hexagon_F2_conv_sf2w :
+Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2w">;
+
+def int_hexagon_F2_conv_sf2ud :
+Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2ud">;
+
+def int_hexagon_F2_conv_sf2d :
+Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2d">;
+
+def int_hexagon_F2_conv_df2uw :
+Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2uw">;
+
+def int_hexagon_F2_conv_df2w :
+Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2w">;
+
+def int_hexagon_F2_conv_df2ud :
+Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2ud">;
+
+def int_hexagon_F2_conv_df2d :
+Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2d">;
+
+def int_hexagon_F2_conv_sf2uw_chop :
+Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2uw_chop">;
+
+def int_hexagon_F2_conv_sf2w_chop :
+Hexagon_i32_float_Intrinsic<"HEXAGON_F2_conv_sf2w_chop">;
+
+def int_hexagon_F2_conv_sf2ud_chop :
+Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2ud_chop">;
+
+def int_hexagon_F2_conv_sf2d_chop :
+Hexagon_i64_float_Intrinsic<"HEXAGON_F2_conv_sf2d_chop">;
+
+def int_hexagon_F2_conv_df2uw_chop :
+Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2uw_chop">;
+
+def int_hexagon_F2_conv_df2w_chop :
+Hexagon_i32_double_Intrinsic<"HEXAGON_F2_conv_df2w_chop">;
+
+def int_hexagon_F2_conv_df2ud_chop :
+Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2ud_chop">;
+
+def int_hexagon_F2_conv_df2d_chop :
+Hexagon_i64_double_Intrinsic<"HEXAGON_F2_conv_df2d_chop">;
+
+def int_hexagon_S2_asr_r_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_r_r">;
+
+def int_hexagon_S2_asl_r_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_r_r">;
+
+def int_hexagon_S2_lsr_r_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r">;
+
+def int_hexagon_S2_lsl_r_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r">;
+
+def int_hexagon_S2_asr_r_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_p">;
+
+def int_hexagon_S2_asl_r_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_p">;
+
+def int_hexagon_S2_lsr_r_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p">;
+
+def int_hexagon_S2_lsl_r_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p">;
+
+def int_hexagon_S2_asr_r_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_acc">;
+
+def int_hexagon_S2_asl_r_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_acc">;
+
+def int_hexagon_S2_lsr_r_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_acc">;
+
+def int_hexagon_S2_lsl_r_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_acc">;
+
+def int_hexagon_S2_asr_r_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_acc">;
+
+def int_hexagon_S2_asl_r_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_acc">;
+
+def int_hexagon_S2_lsr_r_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_acc">;
+
+def int_hexagon_S2_lsl_r_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_acc">;
+
+def int_hexagon_S2_asr_r_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_nac">;
+
+def int_hexagon_S2_asl_r_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_nac">;
+
+def int_hexagon_S2_lsr_r_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_nac">;
+
+def int_hexagon_S2_lsl_r_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_nac">;
+
+def int_hexagon_S2_asr_r_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_nac">;
+
+def int_hexagon_S2_asl_r_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_nac">;
+
+def int_hexagon_S2_lsr_r_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_nac">;
+
+def int_hexagon_S2_lsl_r_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_nac">;
+
+def int_hexagon_S2_asr_r_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_and">;
+
+def int_hexagon_S2_asl_r_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_and">;
+
+def int_hexagon_S2_lsr_r_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_and">;
+
+def int_hexagon_S2_lsl_r_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_and">;
+
+def int_hexagon_S2_asr_r_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_or">;
+
+def int_hexagon_S2_asl_r_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_or">;
+
+def int_hexagon_S2_lsr_r_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_r_r_or">;
+
+def int_hexagon_S2_lsl_r_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsl_r_r_or">;
+
+def int_hexagon_S2_asr_r_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_and">;
+
+def int_hexagon_S2_asl_r_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_and">;
+
+def int_hexagon_S2_lsr_r_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_and">;
+
+def int_hexagon_S2_lsl_r_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_and">;
+
+def int_hexagon_S2_asr_r_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_or">;
+
+def int_hexagon_S2_asl_r_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_or">;
+
+def int_hexagon_S2_lsr_r_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_or">;
+
+def int_hexagon_S2_lsl_r_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_or">;
+
+def int_hexagon_S2_asr_r_p_xor :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_r_p_xor">;
+
+def int_hexagon_S2_asl_r_p_xor :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_r_p_xor">;
+
+def int_hexagon_S2_lsr_r_p_xor :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_r_p_xor">;
+
+def int_hexagon_S2_lsl_r_p_xor :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsl_r_p_xor">;
+
+def int_hexagon_S2_asr_r_r_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_r_r_sat">;
+
+def int_hexagon_S2_asl_r_r_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_r_r_sat">;
+
+def int_hexagon_S2_asr_i_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_lsr_i_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asl_i_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_lsr_i_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asl_i_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_p", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_r_xacc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_xacc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_p_xacc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_p_xacc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_lsr_i_r_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asr_i_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_lsr_i_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_lsr_i_p_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_asl_i_p_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_asl_i_r_sat :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asl_i_r_sat", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_r_rnd :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_r_rnd_goodsyntax :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_asr_i_r_rnd_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_p_rnd :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_p_rnd_goodsyntax :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_p_rnd_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S4_lsli :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_lsli", [IntrNoMem, ImmArg<ArgIndex<0>>]>;
+
+def int_hexagon_S2_addasl_rrri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_addasl_rrri", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_andi_asl_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_asl_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_ori_asl_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_asl_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_addi_asl_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_asl_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_subi_asl_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_asl_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_andi_lsr_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_andi_lsr_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_ori_lsr_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_ori_lsr_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_addi_lsr_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_addi_lsr_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S4_subi_lsr_ri :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_subi_lsr_ri", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_valignib :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignib", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_valignrb :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_valignrb">;
+
+def int_hexagon_S2_vspliceib :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vspliceib", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_vsplicerb :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S2_vsplicerb">;
+
+def int_hexagon_S2_vsplatrh :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsplatrh">;
+
+def int_hexagon_S2_vsplatrb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_vsplatrb">;
+
+def int_hexagon_S2_insert :
+Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_insert", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S2_tableidxb_goodsyntax :
+Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxb_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S2_tableidxh_goodsyntax :
+Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxh_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S2_tableidxw_goodsyntax :
+Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxw_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S2_tableidxd_goodsyntax :
+Hexagon_i32_i32i32i32i32_Intrinsic<"HEXAGON_S2_tableidxd_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_A4_bitspliti :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitspliti", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A4_bitsplit :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_A4_bitsplit">;
+
+def int_hexagon_S4_extract :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S4_extract", [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_extractu :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S2_extractu", [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_insertp :
+Hexagon_i64_i64i64i32i32_Intrinsic<"HEXAGON_S2_insertp", [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_S4_extractp :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S4_extractp", [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_extractup :
+Hexagon_i64_i64i32i32_Intrinsic<"HEXAGON_S2_extractup", [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S2_insert_rp :
+Hexagon_i32_i32i32i64_Intrinsic<"HEXAGON_S2_insert_rp">;
+
+def int_hexagon_S4_extract_rp :
+Hexagon_i32_i32i64_Intrinsic<"HEXAGON_S4_extract_rp">;
+
+def int_hexagon_S2_extractu_rp :
+Hexagon_i32_i32i64_Intrinsic<"HEXAGON_S2_extractu_rp">;
+
+def int_hexagon_S2_insertp_rp :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_S2_insertp_rp">;
+
+def int_hexagon_S4_extractp_rp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S4_extractp_rp">;
+
+def int_hexagon_S2_extractup_rp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_extractup_rp">;
+
+def int_hexagon_S2_tstbit_i :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_i", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S4_ntstbit_i :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_i", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_setbit_i :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_i", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_togglebit_i :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_i", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_clrbit_i :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_i", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_tstbit_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_tstbit_r">;
+
+def int_hexagon_S4_ntstbit_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_ntstbit_r">;
+
+def int_hexagon_S2_setbit_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_setbit_r">;
+
+def int_hexagon_S2_togglebit_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_togglebit_r">;
+
+def int_hexagon_S2_clrbit_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_clrbit_r">;
+
+def int_hexagon_S2_asr_i_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vh", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_lsr_i_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vh", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asl_i_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vh", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_r_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_vh">;
+
+def int_hexagon_S5_asrhub_rnd_sat_goodsyntax :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_rnd_sat_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S5_asrhub_sat :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S5_asrhub_sat", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S5_vasrhrnd_goodsyntax :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S5_vasrhrnd_goodsyntax", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asl_r_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_vh">;
+
+def int_hexagon_S2_lsr_r_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_vh">;
+
+def int_hexagon_S2_lsl_r_vh :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vh">;
+
+def int_hexagon_S2_asr_i_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_i_vw", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_i_svw_trun :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_i_svw_trun", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_r_svw_trun :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S2_asr_r_svw_trun">;
+
+def int_hexagon_S2_lsr_i_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_i_vw", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asl_i_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_i_vw", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_asr_r_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asr_r_vw">;
+
+def int_hexagon_S2_asl_r_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_asl_r_vw">;
+
+def int_hexagon_S2_lsr_r_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsr_r_vw">;
+
+def int_hexagon_S2_lsl_r_vw :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S2_lsl_r_vw">;
+
+def int_hexagon_S2_vrndpackwh :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vrndpackwh">;
+
+def int_hexagon_S2_vrndpackwhs :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vrndpackwhs">;
+
+def int_hexagon_S2_vsxtbh :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsxtbh">;
+
+def int_hexagon_S2_vzxtbh :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxtbh">;
+
+def int_hexagon_S2_vsathub :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsathub">;
+
+def int_hexagon_S2_svsathub :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_svsathub">;
+
+def int_hexagon_S2_svsathb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_svsathb">;
+
+def int_hexagon_S2_vsathb :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsathb">;
+
+def int_hexagon_S2_vtrunohb :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vtrunohb">;
+
+def int_hexagon_S2_vtrunewh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_vtrunewh">;
+
+def int_hexagon_S2_vtrunowh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_vtrunowh">;
+
+def int_hexagon_S2_vtrunehb :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vtrunehb">;
+
+def int_hexagon_S2_vsxthw :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vsxthw">;
+
+def int_hexagon_S2_vzxthw :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S2_vzxthw">;
+
+def int_hexagon_S2_vsatwh :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsatwh">;
+
+def int_hexagon_S2_vsatwuh :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_vsatwuh">;
+
+def int_hexagon_S2_packhl :
+Hexagon_i64_i32i32_Intrinsic<"HEXAGON_S2_packhl">;
+
+def int_hexagon_A2_swiz :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_A2_swiz">;
+
+def int_hexagon_S2_vsathub_nopack :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsathub_nopack">;
+
+def int_hexagon_S2_vsathb_nopack :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsathb_nopack">;
+
+def int_hexagon_S2_vsatwh_nopack :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsatwh_nopack">;
+
+def int_hexagon_S2_vsatwuh_nopack :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_vsatwuh_nopack">;
+
+def int_hexagon_S2_shuffob :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffob">;
+
+def int_hexagon_S2_shuffeb :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffeb">;
+
+def int_hexagon_S2_shuffoh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffoh">;
+
+def int_hexagon_S2_shuffeh :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_shuffeh">;
+
+def int_hexagon_S5_popcountp :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S5_popcountp">;
+
+def int_hexagon_S4_parity :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_parity">;
+
+def int_hexagon_S2_parityp :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_S2_parityp">;
+
+def int_hexagon_S2_lfsp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S2_lfsp">;
+
+def int_hexagon_S2_clbnorm :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_clbnorm">;
+
+def int_hexagon_S4_clbaddi :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S4_clbaddi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S4_clbpnorm :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S4_clbpnorm">;
+
+def int_hexagon_S4_clbpaddi :
+Hexagon_i32_i64i32_Intrinsic<"HEXAGON_S4_clbpaddi", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S2_clb :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_clb">;
+
+def int_hexagon_S2_cl0 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_cl0">;
+
+def int_hexagon_S2_cl1 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_cl1">;
+
+def int_hexagon_S2_clbp :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_clbp">;
+
+def int_hexagon_S2_cl0p :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_cl0p">;
+
+def int_hexagon_S2_cl1p :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_cl1p">;
+
+def int_hexagon_S2_brev :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_brev">;
+
+def int_hexagon_S2_brevp :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_brevp">;
+
+def int_hexagon_S2_ct0 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_ct0">;
+
+def int_hexagon_S2_ct1 :
+Hexagon_i32_i32_Intrinsic<"HEXAGON_S2_ct1">;
+
+def int_hexagon_S2_ct0p :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_ct0p">;
+
+def int_hexagon_S2_ct1p :
+Hexagon_i32_i64_Intrinsic<"HEXAGON_S2_ct1p">;
+
+def int_hexagon_S2_interleave :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_interleave">;
+
+def int_hexagon_S2_deinterleave :
+Hexagon_i64_i64_Intrinsic<"HEXAGON_S2_deinterleave">;
+
+def int_hexagon_Y2_dcfetch :
+Hexagon__ptr_Intrinsic<"HEXAGON_Y2_dcfetch", []>;
+
+def int_hexagon_Y2_dczeroa :
+Hexagon__ptr_Intrinsic<"HEXAGON_Y2_dczeroa", []>;
+
+def int_hexagon_Y2_dccleana :
+Hexagon__ptr_Intrinsic<"HEXAGON_Y2_dccleana", []>;
+
+def int_hexagon_Y2_dccleaninva :
+Hexagon__ptr_Intrinsic<"HEXAGON_Y2_dccleaninva", []>;
+
+def int_hexagon_Y2_dcinva :
+Hexagon__ptr_Intrinsic<"HEXAGON_Y2_dcinva", []>;
+
+def int_hexagon_Y4_l2fetch :
+Hexagon__ptri32_Intrinsic<"HEXAGON_Y4_l2fetch", []>;
+
+def int_hexagon_Y5_l2fetch :
+Hexagon__ptri64_Intrinsic<"HEXAGON_Y5_l2fetch", []>;
+
+// V60 Scalar Instructions.
+
+def int_hexagon_S6_rol_i_r :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S6_rol_i_r", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S6_rol_i_p :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_S6_rol_i_p", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_S6_rol_i_r_acc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_p_acc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_acc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_r_nac :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_p_nac :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_nac", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_r_xacc :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_p_xacc :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_xacc", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_r_and :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_r_or :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_S6_rol_i_r_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_p_and :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_and", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_S6_rol_i_p_or :
+Hexagon_i64_i64i64i32_Intrinsic<"HEXAGON_S6_rol_i_p_or", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+// V62 Scalar Instructions.
+
+def int_hexagon_M6_vabsdiffb :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M6_vabsdiffb">;
+
+def int_hexagon_M6_vabsdiffub :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M6_vabsdiffub">;
+
+def int_hexagon_S6_vsplatrbp :
+Hexagon_i64_i32_Intrinsic<"HEXAGON_S6_vsplatrbp">;
+
+def int_hexagon_S6_vtrunehb_ppp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S6_vtrunehb_ppp">;
+
+def int_hexagon_S6_vtrunohb_ppp :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_S6_vtrunohb_ppp">;
+
+// V65 Scalar Instructions.
+
+def int_hexagon_A6_vcmpbeq_notany :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_A6_vcmpbeq_notany">;
+
+// V66 Scalar Instructions.
+
+def int_hexagon_M2_mnaci :
+Hexagon_i32_i32i32i32_Intrinsic<"HEXAGON_M2_mnaci">;
+
+def int_hexagon_F2_dfadd :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfadd", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfsub :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfsub", [IntrNoMem, Throws]>;
+
+def int_hexagon_S2_mask :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_S2_mask", [IntrNoMem, ImmArg<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
+
+// V67 Scalar Instructions.
+
+def int_hexagon_M7_dcmpyrw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M7_dcmpyrw">;
+
+def int_hexagon_M7_dcmpyrw_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M7_dcmpyrw_acc">;
+
+def int_hexagon_M7_dcmpyrwc :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M7_dcmpyrwc">;
+
+def int_hexagon_M7_dcmpyrwc_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M7_dcmpyrwc_acc">;
+
+def int_hexagon_M7_dcmpyiw :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M7_dcmpyiw">;
+
+def int_hexagon_M7_dcmpyiw_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M7_dcmpyiw_acc">;
+
+def int_hexagon_M7_dcmpyiwc :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M7_dcmpyiwc">;
+
+def int_hexagon_M7_dcmpyiwc_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M7_dcmpyiwc_acc">;
+
+def int_hexagon_M7_vdmpy :
+Hexagon_i64_i64i64_Intrinsic<"HEXAGON_M7_vdmpy">;
+
+def int_hexagon_M7_vdmpy_acc :
+Hexagon_i64_i64i64i64_Intrinsic<"HEXAGON_M7_vdmpy_acc">;
+
+def int_hexagon_M7_wcmpyrw :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyrw">;
+
+def int_hexagon_M7_wcmpyrwc :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyrwc">;
+
+def int_hexagon_M7_wcmpyiw :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyiw">;
+
+def int_hexagon_M7_wcmpyiwc :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyiwc">;
+
+def int_hexagon_M7_wcmpyrw_rnd :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyrw_rnd">;
+
+def int_hexagon_M7_wcmpyrwc_rnd :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyrwc_rnd">;
+
+def int_hexagon_M7_wcmpyiw_rnd :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyiw_rnd">;
+
+def int_hexagon_M7_wcmpyiwc_rnd :
+Hexagon_i32_i64i64_Intrinsic<"HEXAGON_M7_wcmpyiwc_rnd">;
+
+def int_hexagon_A7_croundd_ri :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_A7_croundd_ri", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A7_croundd_rr :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_A7_croundd_rr">;
+
+def int_hexagon_A7_clip :
+Hexagon_i32_i32i32_Intrinsic<"HEXAGON_A7_clip", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_A7_vclip :
+Hexagon_i64_i64i32_Intrinsic<"HEXAGON_A7_vclip", [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+def int_hexagon_F2_dfmax :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfmax", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfmin :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfmin", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfmpyfix :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfmpyfix", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfmpyll :
+Hexagon_double_doubledouble_Intrinsic<"HEXAGON_F2_dfmpyll", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfmpylh :
+Hexagon_double_doubledoubledouble_Intrinsic<"HEXAGON_F2_dfmpylh", [IntrNoMem, Throws]>;
+
+def int_hexagon_F2_dfmpyhh :
+Hexagon_double_doubledoubledouble_Intrinsic<"HEXAGON_F2_dfmpyhh", [IntrNoMem, Throws]>;
+
+// V60 HVX Instructions.
+
+def int_hexagon_V6_vS32b_qpred_ai :
+Hexagon_custom__v64i1ptrv16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_qpred_ai_128B :
+Hexagon_custom__v128i1ptrv32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nqpred_ai :
+Hexagon_custom__v64i1ptrv16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nqpred_ai_128B :
+Hexagon_custom__v128i1ptrv32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nt_qpred_ai :
+Hexagon_custom__v64i1ptrv16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nt_qpred_ai_128B :
+Hexagon_custom__v128i1ptrv32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nt_nqpred_ai :
+Hexagon_custom__v64i1ptrv16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vS32b_nt_nqpred_ai_128B :
+Hexagon_custom__v128i1ptrv32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_valignb :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignb">;
+
+def int_hexagon_V6_valignb_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignb_128B">;
+
+def int_hexagon_V6_vlalignb :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignb">;
+
+def int_hexagon_V6_vlalignb_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignb_128B">;
+
+def int_hexagon_V6_valignbi :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_valignbi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_valignbi_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_valignbi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlalignbi :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlalignbi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlalignbi_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlalignbi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vror :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vror">;
+
+def int_hexagon_V6_vror_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vror_128B">;
+
+def int_hexagon_V6_vunpackub :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackub">;
+
+def int_hexagon_V6_vunpackub_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackub_128B">;
+
+def int_hexagon_V6_vunpackb :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackb">;
+
+def int_hexagon_V6_vunpackb_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackb_128B">;
+
+def int_hexagon_V6_vunpackuh :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackuh">;
+
+def int_hexagon_V6_vunpackuh_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackuh_128B">;
+
+def int_hexagon_V6_vunpackh :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vunpackh">;
+
+def int_hexagon_V6_vunpackh_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vunpackh_128B">;
+
+def int_hexagon_V6_vunpackob :
+Hexagon_v32i32_v32i32v16i32_Intrinsic<"HEXAGON_V6_vunpackob">;
+
+def int_hexagon_V6_vunpackob_128B :
+Hexagon_v64i32_v64i32v32i32_Intrinsic<"HEXAGON_V6_vunpackob_128B">;
+
+def int_hexagon_V6_vunpackoh :
+Hexagon_v32i32_v32i32v16i32_Intrinsic<"HEXAGON_V6_vunpackoh">;
+
+def int_hexagon_V6_vunpackoh_128B :
+Hexagon_v64i32_v64i32v32i32_Intrinsic<"HEXAGON_V6_vunpackoh_128B">;
+
+def int_hexagon_V6_vpackeb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackeb">;
+
+def int_hexagon_V6_vpackeb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackeb_128B">;
+
+def int_hexagon_V6_vpackeh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackeh">;
+
+def int_hexagon_V6_vpackeh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackeh_128B">;
+
+def int_hexagon_V6_vpackob :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackob">;
+
+def int_hexagon_V6_vpackob_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackob_128B">;
+
+def int_hexagon_V6_vpackoh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackoh">;
+
+def int_hexagon_V6_vpackoh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackoh_128B">;
+
+def int_hexagon_V6_vpackhub_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackhub_sat">;
+
+def int_hexagon_V6_vpackhub_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackhub_sat_128B">;
+
+def int_hexagon_V6_vpackhb_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackhb_sat">;
+
+def int_hexagon_V6_vpackhb_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackhb_sat_128B">;
+
+def int_hexagon_V6_vpackwuh_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackwuh_sat">;
+
+def int_hexagon_V6_vpackwuh_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackwuh_sat_128B">;
+
+def int_hexagon_V6_vpackwh_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vpackwh_sat">;
+
+def int_hexagon_V6_vpackwh_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vpackwh_sat_128B">;
+
+def int_hexagon_V6_vzb :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vzb">;
+
+def int_hexagon_V6_vzb_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vzb_128B">;
+
+def int_hexagon_V6_vsb :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vsb">;
+
+def int_hexagon_V6_vsb_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vsb_128B">;
+
+def int_hexagon_V6_vzh :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vzh">;
+
+def int_hexagon_V6_vzh_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vzh_128B">;
+
+def int_hexagon_V6_vsh :
+Hexagon_v32i32_v16i32_Intrinsic<"HEXAGON_V6_vsh">;
+
+def int_hexagon_V6_vsh_128B :
+Hexagon_v64i32_v32i32_Intrinsic<"HEXAGON_V6_vsh_128B">;
+
+def int_hexagon_V6_vdmpybus :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpybus">;
+
+def int_hexagon_V6_vdmpybus_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_128B">;
+
+def int_hexagon_V6_vdmpybus_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_acc">;
+
+def int_hexagon_V6_vdmpybus_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_acc_128B">;
+
+def int_hexagon_V6_vdmpybus_dv :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv">;
+
+def int_hexagon_V6_vdmpybus_dv_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_128B">;
+
+def int_hexagon_V6_vdmpybus_dv_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc">;
+
+def int_hexagon_V6_vdmpybus_dv_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpybus_dv_acc_128B">;
+
+def int_hexagon_V6_vdmpyhb :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb">;
+
+def int_hexagon_V6_vdmpyhb_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_128B">;
+
+def int_hexagon_V6_vdmpyhb_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_acc">;
+
+def int_hexagon_V6_vdmpyhb_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_acc_128B">;
+
+def int_hexagon_V6_vdmpyhb_dv :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv">;
+
+def int_hexagon_V6_vdmpyhb_dv_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_128B">;
+
+def int_hexagon_V6_vdmpyhb_dv_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc">;
+
+def int_hexagon_V6_vdmpyhb_dv_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhb_dv_acc_128B">;
+
+def int_hexagon_V6_vdmpyhvsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat">;
+
+def int_hexagon_V6_vdmpyhvsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_128B">;
+
+def int_hexagon_V6_vdmpyhvsat_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc">;
+
+def int_hexagon_V6_vdmpyhvsat_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vdmpyhvsat_acc_128B">;
+
+def int_hexagon_V6_vdmpyhsat :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat">;
+
+def int_hexagon_V6_vdmpyhsat_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_128B">;
+
+def int_hexagon_V6_vdmpyhsat_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc">;
+
+def int_hexagon_V6_vdmpyhsat_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsat_acc_128B">;
+
+def int_hexagon_V6_vdmpyhisat :
+Hexagon_v16i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat">;
+
+def int_hexagon_V6_vdmpyhisat_128B :
+Hexagon_v32i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_128B">;
+
+def int_hexagon_V6_vdmpyhisat_acc :
+Hexagon_v16i32_v16i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc">;
+
+def int_hexagon_V6_vdmpyhisat_acc_128B :
+Hexagon_v32i32_v32i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhisat_acc_128B">;
+
+def int_hexagon_V6_vdmpyhsusat :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat">;
+
+def int_hexagon_V6_vdmpyhsusat_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_128B">;
+
+def int_hexagon_V6_vdmpyhsusat_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc">;
+
+def int_hexagon_V6_vdmpyhsusat_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsusat_acc_128B">;
+
+def int_hexagon_V6_vdmpyhsuisat :
+Hexagon_v16i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat">;
+
+def int_hexagon_V6_vdmpyhsuisat_128B :
+Hexagon_v32i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_128B">;
+
+def int_hexagon_V6_vdmpyhsuisat_acc :
+Hexagon_v16i32_v16i32v32i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc">;
+
+def int_hexagon_V6_vdmpyhsuisat_acc_128B :
+Hexagon_v32i32_v32i32v64i32i32_Intrinsic<"HEXAGON_V6_vdmpyhsuisat_acc_128B">;
+
+def int_hexagon_V6_vtmpyb :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyb">;
+
+def int_hexagon_V6_vtmpyb_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_128B">;
+
+def int_hexagon_V6_vtmpyb_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_acc">;
+
+def int_hexagon_V6_vtmpyb_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyb_acc_128B">;
+
+def int_hexagon_V6_vtmpybus :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpybus">;
+
+def int_hexagon_V6_vtmpybus_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_128B">;
+
+def int_hexagon_V6_vtmpybus_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_acc">;
+
+def int_hexagon_V6_vtmpybus_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpybus_acc_128B">;
+
+def int_hexagon_V6_vtmpyhb :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb">;
+
+def int_hexagon_V6_vtmpyhb_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_128B">;
+
+def int_hexagon_V6_vtmpyhb_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_acc">;
+
+def int_hexagon_V6_vtmpyhb_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vtmpyhb_acc_128B">;
+
+def int_hexagon_V6_vrmpyub :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vrmpyub">;
+
+def int_hexagon_V6_vrmpyub_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_128B">;
+
+def int_hexagon_V6_vrmpyub_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_acc">;
+
+def int_hexagon_V6_vrmpyub_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vrmpyub_acc_128B">;
+
+def int_hexagon_V6_vrmpyubv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpyubv">;
+
+def int_hexagon_V6_vrmpyubv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpyubv_128B">;
+
+def int_hexagon_V6_vrmpyubv_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpyubv_acc">;
+
+def int_hexagon_V6_vrmpyubv_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpyubv_acc_128B">;
+
+def int_hexagon_V6_vrmpybv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybv">;
+
+def int_hexagon_V6_vrmpybv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybv_128B">;
+
+def int_hexagon_V6_vrmpybv_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybv_acc">;
+
+def int_hexagon_V6_vrmpybv_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybv_acc_128B">;
+
+def int_hexagon_V6_vrmpyubi :
+Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrmpyubi_128B :
+Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrmpyubi_acc :
+Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vrmpyubi_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpyubi_acc_128B", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vrmpybus :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vrmpybus">;
+
+def int_hexagon_V6_vrmpybus_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_128B">;
+
+def int_hexagon_V6_vrmpybus_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_acc">;
+
+def int_hexagon_V6_vrmpybus_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vrmpybus_acc_128B">;
+
+def int_hexagon_V6_vrmpybusi :
+Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrmpybusi_128B :
+Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrmpybusi_acc :
+Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vrmpybusi_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrmpybusi_acc_128B", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vrmpybusv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybusv">;
+
+def int_hexagon_V6_vrmpybusv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybusv_128B">;
+
+def int_hexagon_V6_vrmpybusv_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vrmpybusv_acc">;
+
+def int_hexagon_V6_vrmpybusv_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vrmpybusv_acc_128B">;
+
+def int_hexagon_V6_vdsaduh :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vdsaduh">;
+
+def int_hexagon_V6_vdsaduh_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_128B">;
+
+def int_hexagon_V6_vdsaduh_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_acc">;
+
+def int_hexagon_V6_vdsaduh_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vdsaduh_acc_128B">;
+
+def int_hexagon_V6_vrsadubi :
+Hexagon_v32i32_v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrsadubi_128B :
+Hexagon_v64i32_v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vrsadubi_acc :
+Hexagon_v32i32_v32i32v32i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vrsadubi_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32i32_Intrinsic<"HEXAGON_V6_vrsadubi_acc_128B", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vasrw :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vasrw">;
+
+def int_hexagon_V6_vasrw_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vasrw_128B">;
+
+def int_hexagon_V6_vaslw :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vaslw">;
+
+def int_hexagon_V6_vaslw_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vaslw_128B">;
+
+def int_hexagon_V6_vlsrw :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrw">;
+
+def int_hexagon_V6_vlsrw_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrw_128B">;
+
+def int_hexagon_V6_vasrwv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vasrwv">;
+
+def int_hexagon_V6_vasrwv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vasrwv_128B">;
+
+def int_hexagon_V6_vaslwv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaslwv">;
+
+def int_hexagon_V6_vaslwv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaslwv_128B">;
+
+def int_hexagon_V6_vlsrwv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vlsrwv">;
+
+def int_hexagon_V6_vlsrwv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vlsrwv_128B">;
+
+def int_hexagon_V6_vasrh :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vasrh">;
+
+def int_hexagon_V6_vasrh_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vasrh_128B">;
+
+def int_hexagon_V6_vaslh :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vaslh">;
+
+def int_hexagon_V6_vaslh_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vaslh_128B">;
+
+def int_hexagon_V6_vlsrh :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrh">;
+
+def int_hexagon_V6_vlsrh_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrh_128B">;
+
+def int_hexagon_V6_vasrhv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vasrhv">;
+
+def int_hexagon_V6_vasrhv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vasrhv_128B">;
+
+def int_hexagon_V6_vaslhv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaslhv">;
+
+def int_hexagon_V6_vaslhv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaslhv_128B">;
+
+def int_hexagon_V6_vlsrhv :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vlsrhv">;
+
+def int_hexagon_V6_vlsrhv_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vlsrhv_128B">;
+
+def int_hexagon_V6_vasrwh :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwh">;
+
+def int_hexagon_V6_vasrwh_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwh_128B">;
+
+def int_hexagon_V6_vasrwhsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwhsat">;
+
+def int_hexagon_V6_vasrwhsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwhsat_128B">;
+
+def int_hexagon_V6_vasrwhrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwhrndsat">;
+
+def int_hexagon_V6_vasrwhrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwhrndsat_128B">;
+
+def int_hexagon_V6_vasrwuhsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwuhsat">;
+
+def int_hexagon_V6_vasrwuhsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwuhsat_128B">;
+
+def int_hexagon_V6_vroundwh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundwh">;
+
+def int_hexagon_V6_vroundwh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundwh_128B">;
+
+def int_hexagon_V6_vroundwuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundwuh">;
+
+def int_hexagon_V6_vroundwuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundwuh_128B">;
+
+def int_hexagon_V6_vasrhubsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhubsat">;
+
+def int_hexagon_V6_vasrhubsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhubsat_128B">;
+
+def int_hexagon_V6_vasrhubrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhubrndsat">;
+
+def int_hexagon_V6_vasrhubrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhubrndsat_128B">;
+
+def int_hexagon_V6_vasrhbrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhbrndsat">;
+
+def int_hexagon_V6_vasrhbrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhbrndsat_128B">;
+
+def int_hexagon_V6_vroundhb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundhb">;
+
+def int_hexagon_V6_vroundhb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundhb_128B">;
+
+def int_hexagon_V6_vroundhub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vroundhub">;
+
+def int_hexagon_V6_vroundhub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vroundhub_128B">;
+
+def int_hexagon_V6_vaslw_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vaslw_acc">;
+
+def int_hexagon_V6_vaslw_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vaslw_acc_128B">;
+
+def int_hexagon_V6_vasrw_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrw_acc">;
+
+def int_hexagon_V6_vasrw_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrw_acc_128B">;
+
+def int_hexagon_V6_vaddb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddb">;
+
+def int_hexagon_V6_vaddb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddb_128B">;
+
+def int_hexagon_V6_vsubb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubb">;
+
+def int_hexagon_V6_vsubb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubb_128B">;
+
+def int_hexagon_V6_vaddb_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddb_dv">;
+
+def int_hexagon_V6_vaddb_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddb_dv_128B">;
+
+def int_hexagon_V6_vsubb_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubb_dv">;
+
+def int_hexagon_V6_vsubb_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubb_dv_128B">;
+
+def int_hexagon_V6_vaddh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddh">;
+
+def int_hexagon_V6_vaddh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddh_128B">;
+
+def int_hexagon_V6_vsubh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubh">;
+
+def int_hexagon_V6_vsubh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubh_128B">;
+
+def int_hexagon_V6_vaddh_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddh_dv">;
+
+def int_hexagon_V6_vaddh_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddh_dv_128B">;
+
+def int_hexagon_V6_vsubh_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubh_dv">;
+
+def int_hexagon_V6_vsubh_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubh_dv_128B">;
+
+def int_hexagon_V6_vaddw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddw">;
+
+def int_hexagon_V6_vaddw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddw_128B">;
+
+def int_hexagon_V6_vsubw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubw">;
+
+def int_hexagon_V6_vsubw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubw_128B">;
+
+def int_hexagon_V6_vaddw_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddw_dv">;
+
+def int_hexagon_V6_vaddw_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddw_dv_128B">;
+
+def int_hexagon_V6_vsubw_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubw_dv">;
+
+def int_hexagon_V6_vsubw_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubw_dv_128B">;
+
+def int_hexagon_V6_vaddubsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubsat">;
+
+def int_hexagon_V6_vaddubsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubsat_128B">;
+
+def int_hexagon_V6_vaddubsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubsat_dv">;
+
+def int_hexagon_V6_vaddubsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddubsat_dv_128B">;
+
+def int_hexagon_V6_vsububsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsububsat">;
+
+def int_hexagon_V6_vsububsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububsat_128B">;
+
+def int_hexagon_V6_vsububsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububsat_dv">;
+
+def int_hexagon_V6_vsububsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsububsat_dv_128B">;
+
+def int_hexagon_V6_vadduhsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhsat">;
+
+def int_hexagon_V6_vadduhsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhsat_128B">;
+
+def int_hexagon_V6_vadduhsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhsat_dv">;
+
+def int_hexagon_V6_vadduhsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vadduhsat_dv_128B">;
+
+def int_hexagon_V6_vsubuhsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuhsat">;
+
+def int_hexagon_V6_vsubuhsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhsat_128B">;
+
+def int_hexagon_V6_vsubuhsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhsat_dv">;
+
+def int_hexagon_V6_vsubuhsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubuhsat_dv_128B">;
+
+def int_hexagon_V6_vaddhsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhsat">;
+
+def int_hexagon_V6_vaddhsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhsat_128B">;
+
+def int_hexagon_V6_vaddhsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhsat_dv">;
+
+def int_hexagon_V6_vaddhsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddhsat_dv_128B">;
+
+def int_hexagon_V6_vsubhsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhsat">;
+
+def int_hexagon_V6_vsubhsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhsat_128B">;
+
+def int_hexagon_V6_vsubhsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhsat_dv">;
+
+def int_hexagon_V6_vsubhsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubhsat_dv_128B">;
+
+def int_hexagon_V6_vaddwsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddwsat">;
+
+def int_hexagon_V6_vaddwsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwsat_128B">;
+
+def int_hexagon_V6_vaddwsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddwsat_dv">;
+
+def int_hexagon_V6_vaddwsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddwsat_dv_128B">;
+
+def int_hexagon_V6_vsubwsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubwsat">;
+
+def int_hexagon_V6_vsubwsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwsat_128B">;
+
+def int_hexagon_V6_vsubwsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubwsat_dv">;
+
+def int_hexagon_V6_vsubwsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubwsat_dv_128B">;
+
+def int_hexagon_V6_vavgub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgub">;
+
+def int_hexagon_V6_vavgub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgub_128B">;
+
+def int_hexagon_V6_vavgubrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgubrnd">;
+
+def int_hexagon_V6_vavgubrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgubrnd_128B">;
+
+def int_hexagon_V6_vavguh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguh">;
+
+def int_hexagon_V6_vavguh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguh_128B">;
+
+def int_hexagon_V6_vavguhrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguhrnd">;
+
+def int_hexagon_V6_vavguhrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguhrnd_128B">;
+
+def int_hexagon_V6_vavgh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgh">;
+
+def int_hexagon_V6_vavgh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgh_128B">;
+
+def int_hexagon_V6_vavghrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavghrnd">;
+
+def int_hexagon_V6_vavghrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavghrnd_128B">;
+
+def int_hexagon_V6_vnavgh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgh">;
+
+def int_hexagon_V6_vnavgh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgh_128B">;
+
+def int_hexagon_V6_vavgw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgw">;
+
+def int_hexagon_V6_vavgw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgw_128B">;
+
+def int_hexagon_V6_vavgwrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgwrnd">;
+
+def int_hexagon_V6_vavgwrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgwrnd_128B">;
+
+def int_hexagon_V6_vnavgw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgw">;
+
+def int_hexagon_V6_vnavgw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgw_128B">;
+
+def int_hexagon_V6_vabsdiffub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffub">;
+
+def int_hexagon_V6_vabsdiffub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffub_128B">;
+
+def int_hexagon_V6_vabsdiffuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffuh">;
+
+def int_hexagon_V6_vabsdiffuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffuh_128B">;
+
+def int_hexagon_V6_vabsdiffh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffh">;
+
+def int_hexagon_V6_vabsdiffh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffh_128B">;
+
+def int_hexagon_V6_vabsdiffw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vabsdiffw">;
+
+def int_hexagon_V6_vabsdiffw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vabsdiffw_128B">;
+
+def int_hexagon_V6_vnavgub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgub">;
+
+def int_hexagon_V6_vnavgub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgub_128B">;
+
+def int_hexagon_V6_vaddubh :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubh">;
+
+def int_hexagon_V6_vaddubh_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubh_128B">;
+
+def int_hexagon_V6_vsububh :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsububh">;
+
+def int_hexagon_V6_vsububh_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsububh_128B">;
+
+def int_hexagon_V6_vaddhw :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhw">;
+
+def int_hexagon_V6_vaddhw_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhw_128B">;
+
+def int_hexagon_V6_vsubhw :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubhw">;
+
+def int_hexagon_V6_vsubhw_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubhw_128B">;
+
+def int_hexagon_V6_vadduhw :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhw">;
+
+def int_hexagon_V6_vadduhw_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhw_128B">;
+
+def int_hexagon_V6_vsubuhw :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuhw">;
+
+def int_hexagon_V6_vsubuhw_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuhw_128B">;
+
+def int_hexagon_V6_vd0 :
+Hexagon_v16i32__Intrinsic<"HEXAGON_V6_vd0">;
+
+def int_hexagon_V6_vd0_128B :
+Hexagon_v32i32__Intrinsic<"HEXAGON_V6_vd0_128B">;
+
+def int_hexagon_V6_vaddbq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddbq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubbq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubbq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vaddbnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddbnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubbnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubbnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vaddhq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddhq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubhq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubhq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vaddhnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddhnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubhnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubhnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vaddwq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddwq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubwq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubwq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vaddwnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vaddwnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vsubwnq :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vsubwnq_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vabsh :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsh">;
+
+def int_hexagon_V6_vabsh_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsh_128B">;
+
+def int_hexagon_V6_vabsh_sat :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsh_sat">;
+
+def int_hexagon_V6_vabsh_sat_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsh_sat_128B">;
+
+def int_hexagon_V6_vabsw :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsw">;
+
+def int_hexagon_V6_vabsw_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsw_128B">;
+
+def int_hexagon_V6_vabsw_sat :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsw_sat">;
+
+def int_hexagon_V6_vabsw_sat_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsw_sat_128B">;
+
+def int_hexagon_V6_vmpybv :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybv">;
+
+def int_hexagon_V6_vmpybv_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybv_128B">;
+
+def int_hexagon_V6_vmpybv_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybv_acc">;
+
+def int_hexagon_V6_vmpybv_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybv_acc_128B">;
+
+def int_hexagon_V6_vmpyubv :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyubv">;
+
+def int_hexagon_V6_vmpyubv_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyubv_128B">;
+
+def int_hexagon_V6_vmpyubv_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyubv_acc">;
+
+def int_hexagon_V6_vmpyubv_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyubv_acc_128B">;
+
+def int_hexagon_V6_vmpybusv :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybusv">;
+
+def int_hexagon_V6_vmpybusv_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybusv_128B">;
+
+def int_hexagon_V6_vmpybusv_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpybusv_acc">;
+
+def int_hexagon_V6_vmpybusv_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpybusv_acc_128B">;
+
+def int_hexagon_V6_vmpabusv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpabusv">;
+
+def int_hexagon_V6_vmpabusv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vmpabusv_128B">;
+
+def int_hexagon_V6_vmpabuuv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpabuuv">;
+
+def int_hexagon_V6_vmpabuuv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vmpabuuv_128B">;
+
+def int_hexagon_V6_vmpyhv :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhv">;
+
+def int_hexagon_V6_vmpyhv_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhv_128B">;
+
+def int_hexagon_V6_vmpyhv_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhv_acc">;
+
+def int_hexagon_V6_vmpyhv_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhv_acc_128B">;
+
+def int_hexagon_V6_vmpyuhv :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyuhv">;
+
+def int_hexagon_V6_vmpyuhv_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyuhv_128B">;
+
+def int_hexagon_V6_vmpyuhv_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyuhv_acc">;
+
+def int_hexagon_V6_vmpyuhv_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyuhv_acc_128B">;
+
+def int_hexagon_V6_vmpyhvsrs :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhvsrs">;
+
+def int_hexagon_V6_vmpyhvsrs_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhvsrs_128B">;
+
+def int_hexagon_V6_vmpyhus :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhus">;
+
+def int_hexagon_V6_vmpyhus_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhus_128B">;
+
+def int_hexagon_V6_vmpyhus_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyhus_acc">;
+
+def int_hexagon_V6_vmpyhus_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyhus_acc_128B">;
+
+def int_hexagon_V6_vmpyih :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyih">;
+
+def int_hexagon_V6_vmpyih_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyih_128B">;
+
+def int_hexagon_V6_vmpyih_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyih_acc">;
+
+def int_hexagon_V6_vmpyih_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyih_acc_128B">;
+
+def int_hexagon_V6_vmpyewuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyewuh">;
+
+def int_hexagon_V6_vmpyewuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyewuh_128B">;
+
+def int_hexagon_V6_vmpyowh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh">;
+
+def int_hexagon_V6_vmpyowh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_128B">;
+
+def int_hexagon_V6_vmpyowh_rnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd">;
+
+def int_hexagon_V6_vmpyowh_rnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_128B">;
+
+def int_hexagon_V6_vmpyowh_sacc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_sacc">;
+
+def int_hexagon_V6_vmpyowh_sacc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_sacc_128B">;
+
+def int_hexagon_V6_vmpyowh_rnd_sacc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc">;
+
+def int_hexagon_V6_vmpyowh_rnd_sacc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_rnd_sacc_128B">;
+
+def int_hexagon_V6_vmpyieoh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyieoh">;
+
+def int_hexagon_V6_vmpyieoh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyieoh_128B">;
+
+def int_hexagon_V6_vmpyiewuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewuh">;
+
+def int_hexagon_V6_vmpyiewuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_128B">;
+
+def int_hexagon_V6_vmpyiowh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiowh">;
+
+def int_hexagon_V6_vmpyiowh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiowh_128B">;
+
+def int_hexagon_V6_vmpyiewh_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewh_acc">;
+
+def int_hexagon_V6_vmpyiewh_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewh_acc_128B">;
+
+def int_hexagon_V6_vmpyiewuh_acc :
+Hexagon_v16i32_v16i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc">;
+
+def int_hexagon_V6_vmpyiewuh_acc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyiewuh_acc_128B">;
+
+def int_hexagon_V6_vmpyub :
+Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyub">;
+
+def int_hexagon_V6_vmpyub_128B :
+Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyub_128B">;
+
+def int_hexagon_V6_vmpyub_acc :
+Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyub_acc">;
+
+def int_hexagon_V6_vmpyub_acc_128B :
+Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyub_acc_128B">;
+
+def int_hexagon_V6_vmpybus :
+Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpybus">;
+
+def int_hexagon_V6_vmpybus_128B :
+Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpybus_128B">;
+
+def int_hexagon_V6_vmpybus_acc :
+Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpybus_acc">;
+
+def int_hexagon_V6_vmpybus_acc_128B :
+Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpybus_acc_128B">;
+
+def int_hexagon_V6_vmpabus :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpabus">;
+
+def int_hexagon_V6_vmpabus_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpabus_128B">;
+
+def int_hexagon_V6_vmpabus_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpabus_acc">;
+
+def int_hexagon_V6_vmpabus_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpabus_acc_128B">;
+
+def int_hexagon_V6_vmpahb :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpahb">;
+
+def int_hexagon_V6_vmpahb_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpahb_128B">;
+
+def int_hexagon_V6_vmpahb_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpahb_acc">;
+
+def int_hexagon_V6_vmpahb_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpahb_acc_128B">;
+
+def int_hexagon_V6_vmpyh :
+Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyh">;
+
+def int_hexagon_V6_vmpyh_128B :
+Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyh_128B">;
+
+def int_hexagon_V6_vmpyhsat_acc :
+Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhsat_acc">;
+
+def int_hexagon_V6_vmpyhsat_acc_128B :
+Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhsat_acc_128B">;
+
+def int_hexagon_V6_vmpyhss :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhss">;
+
+def int_hexagon_V6_vmpyhss_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhss_128B">;
+
+def int_hexagon_V6_vmpyhsrs :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyhsrs">;
+
+def int_hexagon_V6_vmpyhsrs_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyhsrs_128B">;
+
+def int_hexagon_V6_vmpyuh :
+Hexagon_v32i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuh">;
+
+def int_hexagon_V6_vmpyuh_128B :
+Hexagon_v64i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_128B">;
+
+def int_hexagon_V6_vmpyuh_acc :
+Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_acc">;
+
+def int_hexagon_V6_vmpyuh_acc_128B :
+Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuh_acc_128B">;
+
+def int_hexagon_V6_vmpyihb :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyihb">;
+
+def int_hexagon_V6_vmpyihb_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_128B">;
+
+def int_hexagon_V6_vmpyihb_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_acc">;
+
+def int_hexagon_V6_vmpyihb_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyihb_acc_128B">;
+
+def int_hexagon_V6_vmpyiwb :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb">;
+
+def int_hexagon_V6_vmpyiwb_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_128B">;
+
+def int_hexagon_V6_vmpyiwb_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_acc">;
+
+def int_hexagon_V6_vmpyiwb_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwb_acc_128B">;
+
+def int_hexagon_V6_vmpyiwh :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh">;
+
+def int_hexagon_V6_vmpyiwh_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_128B">;
+
+def int_hexagon_V6_vmpyiwh_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_acc">;
+
+def int_hexagon_V6_vmpyiwh_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwh_acc_128B">;
+
+def int_hexagon_V6_vand :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vand">;
+
+def int_hexagon_V6_vand_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vand_128B">;
+
+def int_hexagon_V6_vor :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vor">;
+
+def int_hexagon_V6_vor_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vor_128B">;
+
+def int_hexagon_V6_vxor :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vxor">;
+
+def int_hexagon_V6_vxor_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vxor_128B">;
+
+def int_hexagon_V6_vnot :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnot">;
+
+def int_hexagon_V6_vnot_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnot_128B">;
+
+def int_hexagon_V6_vandqrt :
+Hexagon_custom_v16i32_v64i1i32_Intrinsic;
+
+def int_hexagon_V6_vandqrt_128B :
+Hexagon_custom_v32i32_v128i1i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandqrt_acc :
+Hexagon_custom_v16i32_v16i32v64i1i32_Intrinsic;
+
+def int_hexagon_V6_vandqrt_acc_128B :
+Hexagon_custom_v32i32_v32i32v128i1i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandvrt :
+Hexagon_custom_v64i1_v16i32i32_Intrinsic;
+
+def int_hexagon_V6_vandvrt_128B :
+Hexagon_custom_v128i1_v32i32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandvrt_acc :
+Hexagon_custom_v64i1_v64i1v16i32i32_Intrinsic;
+
+def int_hexagon_V6_vandvrt_acc_128B :
+Hexagon_custom_v128i1_v128i1v32i32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtw :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtw_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtw_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtw_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtw_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtw_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtw_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtw_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqw :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqw_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqw_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqw_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqw_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqw_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqw_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqw_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgth :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgth_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgth_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgth_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgth_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgth_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgth_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgth_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqh :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqh_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqh_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqh_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqh_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqh_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqh_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqh_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtb :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtb_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtb_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtb_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtb_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtb_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtb_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtb_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqb :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqb_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqb_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqb_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqb_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqb_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_veqb_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_veqb_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuw :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuw_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuw_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuw_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuw_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuw_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuw_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuw_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuh :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuh_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuh_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuh_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuh_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuh_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtuh_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtuh_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtub :
+Hexagon_custom_v64i1_v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtub_128B :
+Hexagon_custom_v128i1_v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtub_and :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtub_and_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtub_or :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtub_or_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vgtub_xor :
+Hexagon_custom_v64i1_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vgtub_xor_128B :
+Hexagon_custom_v128i1_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_pred_or :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_or_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_and :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_and_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_not :
+Hexagon_custom_v64i1_v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_not_128B :
+Hexagon_custom_v128i1_v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_xor :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_xor_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_and_n :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_and_n_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_or_n :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_pred_or_n_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_pred_scalar2 :
+Hexagon_custom_v64i1_i32_Intrinsic;
+
+def int_hexagon_V6_pred_scalar2_128B :
+Hexagon_custom_v128i1_i32_Intrinsic_128B;
+
+def int_hexagon_V6_vmux :
+Hexagon_custom_v16i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vmux_128B :
+Hexagon_custom_v32i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vswap :
+Hexagon_custom_v32i32_v64i1v16i32v16i32_Intrinsic;
+
+def int_hexagon_V6_vswap_128B :
+Hexagon_custom_v64i32_v128i1v32i32v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vmaxub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxub">;
+
+def int_hexagon_V6_vmaxub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxub_128B">;
+
+def int_hexagon_V6_vminub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminub">;
+
+def int_hexagon_V6_vminub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminub_128B">;
+
+def int_hexagon_V6_vmaxuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxuh">;
+
+def int_hexagon_V6_vmaxuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxuh_128B">;
+
+def int_hexagon_V6_vminuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminuh">;
+
+def int_hexagon_V6_vminuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminuh_128B">;
+
+def int_hexagon_V6_vmaxh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxh">;
+
+def int_hexagon_V6_vmaxh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxh_128B">;
+
+def int_hexagon_V6_vminh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminh">;
+
+def int_hexagon_V6_vminh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminh_128B">;
+
+def int_hexagon_V6_vmaxw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxw">;
+
+def int_hexagon_V6_vmaxw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxw_128B">;
+
+def int_hexagon_V6_vminw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminw">;
+
+def int_hexagon_V6_vminw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminw_128B">;
+
+def int_hexagon_V6_vsathub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsathub">;
+
+def int_hexagon_V6_vsathub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsathub_128B">;
+
+def int_hexagon_V6_vsatwh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatwh">;
+
+def int_hexagon_V6_vsatwh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatwh_128B">;
+
+def int_hexagon_V6_vshuffeb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshuffeb">;
+
+def int_hexagon_V6_vshuffeb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshuffeb_128B">;
+
+def int_hexagon_V6_vshuffob :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshuffob">;
+
+def int_hexagon_V6_vshuffob_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshuffob_128B">;
+
+def int_hexagon_V6_vshufeh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufeh">;
+
+def int_hexagon_V6_vshufeh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufeh_128B">;
+
+def int_hexagon_V6_vshufoh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoh">;
+
+def int_hexagon_V6_vshufoh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoh_128B">;
+
+def int_hexagon_V6_vshuffvdd :
+Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vshuffvdd">;
+
+def int_hexagon_V6_vshuffvdd_128B :
+Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vshuffvdd_128B">;
+
+def int_hexagon_V6_vdealvdd :
+Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vdealvdd">;
+
+def int_hexagon_V6_vdealvdd_128B :
+Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vdealvdd_128B">;
+
+def int_hexagon_V6_vshufoeh :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoeh">;
+
+def int_hexagon_V6_vshufoeh_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoeh_128B">;
+
+def int_hexagon_V6_vshufoeb :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vshufoeb">;
+
+def int_hexagon_V6_vshufoeb_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vshufoeb_128B">;
+
+def int_hexagon_V6_vdealh :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vdealh">;
+
+def int_hexagon_V6_vdealh_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vdealh_128B">;
+
+def int_hexagon_V6_vdealb :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vdealb">;
+
+def int_hexagon_V6_vdealb_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vdealb_128B">;
+
+def int_hexagon_V6_vdealb4w :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdealb4w">;
+
+def int_hexagon_V6_vdealb4w_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdealb4w_128B">;
+
+def int_hexagon_V6_vshuffh :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vshuffh">;
+
+def int_hexagon_V6_vshuffh_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vshuffh_128B">;
+
+def int_hexagon_V6_vshuffb :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vshuffb">;
+
+def int_hexagon_V6_vshuffb_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vshuffb_128B">;
+
+def int_hexagon_V6_extractw :
+Hexagon_i32_v16i32i32_Intrinsic<"HEXAGON_V6_extractw">;
+
+def int_hexagon_V6_extractw_128B :
+Hexagon_i32_v32i32i32_Intrinsic<"HEXAGON_V6_extractw_128B">;
+
+def int_hexagon_V6_vinsertwr :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vinsertwr">;
+
+def int_hexagon_V6_vinsertwr_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vinsertwr_128B">;
+
+def int_hexagon_V6_lvsplatw :
+Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplatw">;
+
+def int_hexagon_V6_lvsplatw_128B :
+Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplatw_128B">;
+
+def int_hexagon_V6_vassignp :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vassignp">;
+
+def int_hexagon_V6_vassignp_128B :
+Hexagon_v64i32_v64i32_Intrinsic<"HEXAGON_V6_vassignp_128B">;
+
+def int_hexagon_V6_vassign :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vassign">;
+
+def int_hexagon_V6_vassign_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vassign_128B">;
+
+def int_hexagon_V6_vcombine :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vcombine">;
+
+def int_hexagon_V6_vcombine_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vcombine_128B">;
+
+def int_hexagon_V6_vdelta :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vdelta">;
+
+def int_hexagon_V6_vdelta_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vdelta_128B">;
+
+def int_hexagon_V6_vrdelta :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrdelta">;
+
+def int_hexagon_V6_vrdelta_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrdelta_128B">;
+
+def int_hexagon_V6_vcl0w :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vcl0w">;
+
+def int_hexagon_V6_vcl0w_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vcl0w_128B">;
+
+def int_hexagon_V6_vcl0h :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vcl0h">;
+
+def int_hexagon_V6_vcl0h_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vcl0h_128B">;
+
+def int_hexagon_V6_vnormamtw :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnormamtw">;
+
+def int_hexagon_V6_vnormamtw_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnormamtw_128B">;
+
+def int_hexagon_V6_vnormamth :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vnormamth">;
+
+def int_hexagon_V6_vnormamth_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vnormamth_128B">;
+
+def int_hexagon_V6_vpopcounth :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vpopcounth">;
+
+def int_hexagon_V6_vpopcounth_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vpopcounth_128B">;
+
+def int_hexagon_V6_vlutvvb :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb">;
+
+def int_hexagon_V6_vlutvvb_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_128B">;
+
+def int_hexagon_V6_vlutvvb_oracc :
+Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracc">;
+
+def int_hexagon_V6_vlutvvb_oracc_128B :
+Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracc_128B">;
+
+def int_hexagon_V6_vlutvwh :
+Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh">;
+
+def int_hexagon_V6_vlutvwh_128B :
+Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_128B">;
+
+def int_hexagon_V6_vlutvwh_oracc :
+Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracc">;
+
+def int_hexagon_V6_vlutvwh_oracc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracc_128B">;
+
+def int_hexagon_V6_hi :
+Hexagon_v16i32_v32i32_Intrinsic<"HEXAGON_V6_hi">;
+
+def int_hexagon_V6_hi_128B :
+Hexagon_v32i32_v64i32_Intrinsic<"HEXAGON_V6_hi_128B">;
+
+def int_hexagon_V6_lo :
+Hexagon_v16i32_v32i32_Intrinsic<"HEXAGON_V6_lo">;
+
+def int_hexagon_V6_lo_128B :
+Hexagon_v32i32_v64i32_Intrinsic<"HEXAGON_V6_lo_128B">;
+
+// V62 HVX Instructions.
+
+def int_hexagon_V6_vlsrb :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vlsrb">;
+
+def int_hexagon_V6_vlsrb_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vlsrb_128B">;
+
+def int_hexagon_V6_vasrwuhrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrwuhrndsat">;
+
+def int_hexagon_V6_vasrwuhrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrwuhrndsat_128B">;
+
+def int_hexagon_V6_vasruwuhrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruwuhrndsat">;
+
+def int_hexagon_V6_vasruwuhrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruwuhrndsat_128B">;
+
+def int_hexagon_V6_vasrhbsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrhbsat">;
+
+def int_hexagon_V6_vasrhbsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrhbsat_128B">;
+
+def int_hexagon_V6_vrounduwuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrounduwuh">;
+
+def int_hexagon_V6_vrounduwuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrounduwuh_128B">;
+
+def int_hexagon_V6_vrounduhub :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrounduhub">;
+
+def int_hexagon_V6_vrounduhub_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrounduhub_128B">;
+
+def int_hexagon_V6_vadduwsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduwsat">;
+
+def int_hexagon_V6_vadduwsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduwsat_128B">;
+
+def int_hexagon_V6_vadduwsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduwsat_dv">;
+
+def int_hexagon_V6_vadduwsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vadduwsat_dv_128B">;
+
+def int_hexagon_V6_vsubuwsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubuwsat">;
+
+def int_hexagon_V6_vsubuwsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuwsat_128B">;
+
+def int_hexagon_V6_vsubuwsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubuwsat_dv">;
+
+def int_hexagon_V6_vsubuwsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubuwsat_dv_128B">;
+
+def int_hexagon_V6_vaddbsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddbsat">;
+
+def int_hexagon_V6_vaddbsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbsat_128B">;
+
+def int_hexagon_V6_vaddbsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddbsat_dv">;
+
+def int_hexagon_V6_vaddbsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vaddbsat_dv_128B">;
+
+def int_hexagon_V6_vsubbsat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubbsat">;
+
+def int_hexagon_V6_vsubbsat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbsat_128B">;
+
+def int_hexagon_V6_vsubbsat_dv :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubbsat_dv">;
+
+def int_hexagon_V6_vsubbsat_dv_128B :
+Hexagon_v64i32_v64i32v64i32_Intrinsic<"HEXAGON_V6_vsubbsat_dv_128B">;
+
+def int_hexagon_V6_vaddcarry :
+Hexagon_custom_v16i32v64i1_v16i32v16i32v64i1_Intrinsic;
+
+def int_hexagon_V6_vaddcarry_128B :
+Hexagon_custom_v32i32v128i1_v32i32v32i32v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vsubcarry :
+Hexagon_custom_v16i32v64i1_v16i32v16i32v64i1_Intrinsic;
+
+def int_hexagon_V6_vsubcarry_128B :
+Hexagon_custom_v32i32v128i1_v32i32v32i32v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vaddububb_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddububb_sat">;
+
+def int_hexagon_V6_vaddububb_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddububb_sat_128B">;
+
+def int_hexagon_V6_vsubububb_sat :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsubububb_sat">;
+
+def int_hexagon_V6_vsubububb_sat_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsubububb_sat_128B">;
+
+def int_hexagon_V6_vaddhw_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddhw_acc">;
+
+def int_hexagon_V6_vaddhw_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddhw_acc_128B">;
+
+def int_hexagon_V6_vadduhw_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vadduhw_acc">;
+
+def int_hexagon_V6_vadduhw_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vadduhw_acc_128B">;
+
+def int_hexagon_V6_vaddubh_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddubh_acc">;
+
+def int_hexagon_V6_vaddubh_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddubh_acc_128B">;
+
+def int_hexagon_V6_vmpyewuh_64 :
+Hexagon_v32i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyewuh_64">;
+
+def int_hexagon_V6_vmpyewuh_64_128B :
+Hexagon_v64i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyewuh_64_128B">;
+
+def int_hexagon_V6_vmpyowh_64_acc :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc">;
+
+def int_hexagon_V6_vmpyowh_64_acc_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vmpyowh_64_acc_128B">;
+
+def int_hexagon_V6_vmpauhb :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpauhb">;
+
+def int_hexagon_V6_vmpauhb_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_128B">;
+
+def int_hexagon_V6_vmpauhb_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_acc">;
+
+def int_hexagon_V6_vmpauhb_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpauhb_acc_128B">;
+
+def int_hexagon_V6_vmpyiwub :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub">;
+
+def int_hexagon_V6_vmpyiwub_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_128B">;
+
+def int_hexagon_V6_vmpyiwub_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_acc">;
+
+def int_hexagon_V6_vmpyiwub_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyiwub_acc_128B">;
+
+def int_hexagon_V6_vandnqrt :
+Hexagon_custom_v16i32_v64i1i32_Intrinsic;
+
+def int_hexagon_V6_vandnqrt_128B :
+Hexagon_custom_v32i32_v128i1i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandnqrt_acc :
+Hexagon_custom_v16i32_v16i32v64i1i32_Intrinsic;
+
+def int_hexagon_V6_vandnqrt_acc_128B :
+Hexagon_custom_v32i32_v32i32v128i1i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandvqv :
+Hexagon_custom_v16i32_v64i1v16i32_Intrinsic;
+
+def int_hexagon_V6_vandvqv_128B :
+Hexagon_custom_v32i32_v128i1v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_vandvnqv :
+Hexagon_custom_v16i32_v64i1v16i32_Intrinsic;
+
+def int_hexagon_V6_vandvnqv_128B :
+Hexagon_custom_v32i32_v128i1v32i32_Intrinsic_128B;
+
+def int_hexagon_V6_pred_scalar2v2 :
+Hexagon_custom_v64i1_i32_Intrinsic;
+
+def int_hexagon_V6_pred_scalar2v2_128B :
+Hexagon_custom_v128i1_i32_Intrinsic_128B;
+
+def int_hexagon_V6_shuffeqw :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_shuffeqw_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_shuffeqh :
+Hexagon_custom_v64i1_v64i1v64i1_Intrinsic;
+
+def int_hexagon_V6_shuffeqh_128B :
+Hexagon_custom_v128i1_v128i1v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vmaxb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vmaxb">;
+
+def int_hexagon_V6_vmaxb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vmaxb_128B">;
+
+def int_hexagon_V6_vminb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vminb">;
+
+def int_hexagon_V6_vminb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vminb_128B">;
+
+def int_hexagon_V6_vsatuwuh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatuwuh">;
+
+def int_hexagon_V6_vsatuwuh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatuwuh_128B">;
+
+def int_hexagon_V6_lvsplath :
+Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplath">;
+
+def int_hexagon_V6_lvsplath_128B :
+Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplath_128B">;
+
+def int_hexagon_V6_lvsplatb :
+Hexagon_v16i32_i32_Intrinsic<"HEXAGON_V6_lvsplatb">;
+
+def int_hexagon_V6_lvsplatb_128B :
+Hexagon_v32i32_i32_Intrinsic<"HEXAGON_V6_lvsplatb_128B">;
+
+def int_hexagon_V6_vaddclbw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddclbw">;
+
+def int_hexagon_V6_vaddclbw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddclbw_128B">;
+
+def int_hexagon_V6_vaddclbh :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vaddclbh">;
+
+def int_hexagon_V6_vaddclbh_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vaddclbh_128B">;
+
+def int_hexagon_V6_vlutvvbi :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlutvvbi_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvbi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlutvvb_oracci :
+Hexagon_v16i32_v16i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vlutvvb_oracci_128B :
+Hexagon_v32i32_v32i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_oracci_128B", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vlutvwhi :
+Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlutvwhi_128B :
+Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwhi_128B", [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+def int_hexagon_V6_vlutvwh_oracci :
+Hexagon_v32i32_v32i32v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vlutvwh_oracci_128B :
+Hexagon_v64i32_v64i32v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_oracci_128B", [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+
+def int_hexagon_V6_vlutvvb_nm :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_nm">;
+
+def int_hexagon_V6_vlutvvb_nm_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvvb_nm_128B">;
+
+def int_hexagon_V6_vlutvwh_nm :
+Hexagon_v32i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_nm">;
+
+def int_hexagon_V6_vlutvwh_nm_128B :
+Hexagon_v64i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vlutvwh_nm_128B">;
+
+// V65 HVX Instructions.
+
+def int_hexagon_V6_vasruwuhsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruwuhsat">;
+
+def int_hexagon_V6_vasruwuhsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruwuhsat_128B">;
+
+def int_hexagon_V6_vasruhubsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruhubsat">;
+
+def int_hexagon_V6_vasruhubsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruhubsat_128B">;
+
+def int_hexagon_V6_vasruhubrndsat :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasruhubrndsat">;
+
+def int_hexagon_V6_vasruhubrndsat_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasruhubrndsat_128B">;
+
+def int_hexagon_V6_vaslh_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vaslh_acc">;
+
+def int_hexagon_V6_vaslh_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vaslh_acc_128B">;
+
+def int_hexagon_V6_vasrh_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vasrh_acc">;
+
+def int_hexagon_V6_vasrh_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vasrh_acc_128B">;
+
+def int_hexagon_V6_vavguw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguw">;
+
+def int_hexagon_V6_vavguw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguw_128B">;
+
+def int_hexagon_V6_vavguwrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavguwrnd">;
+
+def int_hexagon_V6_vavguwrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavguwrnd_128B">;
+
+def int_hexagon_V6_vavgb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgb">;
+
+def int_hexagon_V6_vavgb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgb_128B">;
+
+def int_hexagon_V6_vavgbrnd :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vavgbrnd">;
+
+def int_hexagon_V6_vavgbrnd_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vavgbrnd_128B">;
+
+def int_hexagon_V6_vnavgb :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vnavgb">;
+
+def int_hexagon_V6_vnavgb_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vnavgb_128B">;
+
+def int_hexagon_V6_vdd0 :
+Hexagon_v32i32__Intrinsic<"HEXAGON_V6_vdd0">;
+
+def int_hexagon_V6_vdd0_128B :
+Hexagon_v64i32__Intrinsic<"HEXAGON_V6_vdd0_128B">;
+
+def int_hexagon_V6_vabsb :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsb">;
+
+def int_hexagon_V6_vabsb_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsb_128B">;
+
+def int_hexagon_V6_vabsb_sat :
+Hexagon_v16i32_v16i32_Intrinsic<"HEXAGON_V6_vabsb_sat">;
+
+def int_hexagon_V6_vabsb_sat_128B :
+Hexagon_v32i32_v32i32_Intrinsic<"HEXAGON_V6_vabsb_sat_128B">;
+
+def int_hexagon_V6_vmpabuu :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpabuu">;
+
+def int_hexagon_V6_vmpabuu_128B :
+Hexagon_v64i32_v64i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_128B">;
+
+def int_hexagon_V6_vmpabuu_acc :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_acc">;
+
+def int_hexagon_V6_vmpabuu_acc_128B :
+Hexagon_v64i32_v64i32v64i32i32_Intrinsic<"HEXAGON_V6_vmpabuu_acc_128B">;
+
+def int_hexagon_V6_vmpyh_acc :
+Hexagon_v32i32_v32i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyh_acc">;
+
+def int_hexagon_V6_vmpyh_acc_128B :
+Hexagon_v64i32_v64i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyh_acc_128B">;
+
+def int_hexagon_V6_vmpahhsat :
+Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpahhsat">;
+
+def int_hexagon_V6_vmpahhsat_128B :
+Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpahhsat_128B">;
+
+def int_hexagon_V6_vmpauhuhsat :
+Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpauhuhsat">;
+
+def int_hexagon_V6_vmpauhuhsat_128B :
+Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpauhuhsat_128B">;
+
+def int_hexagon_V6_vmpsuhuhsat :
+Hexagon_v16i32_v16i32v16i32i64_Intrinsic<"HEXAGON_V6_vmpsuhuhsat">;
+
+def int_hexagon_V6_vmpsuhuhsat_128B :
+Hexagon_v32i32_v32i32v32i32i64_Intrinsic<"HEXAGON_V6_vmpsuhuhsat_128B">;
+
+def int_hexagon_V6_vlut4 :
+Hexagon_v16i32_v16i32i64_Intrinsic<"HEXAGON_V6_vlut4">;
+
+def int_hexagon_V6_vlut4_128B :
+Hexagon_v32i32_v32i32i64_Intrinsic<"HEXAGON_V6_vlut4_128B">;
+
+def int_hexagon_V6_vmpyuhe :
+Hexagon_v16i32_v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe">;
+
+def int_hexagon_V6_vmpyuhe_128B :
+Hexagon_v32i32_v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_128B">;
+
+def int_hexagon_V6_vmpyuhe_acc :
+Hexagon_v16i32_v16i32v16i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_acc">;
+
+def int_hexagon_V6_vmpyuhe_acc_128B :
+Hexagon_v32i32_v32i32v32i32i32_Intrinsic<"HEXAGON_V6_vmpyuhe_acc_128B">;
+
+def int_hexagon_V6_vgathermw :
+Hexagon__ptri32i32v16i32_Intrinsic<"HEXAGON_V6_vgathermw", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermw_128B :
+Hexagon__ptri32i32v32i32_Intrinsic<"HEXAGON_V6_vgathermw_128B", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermh :
+Hexagon__ptri32i32v16i32_Intrinsic<"HEXAGON_V6_vgathermh", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermh_128B :
+Hexagon__ptri32i32v32i32_Intrinsic<"HEXAGON_V6_vgathermh_128B", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhw :
+Hexagon__ptri32i32v32i32_Intrinsic<"HEXAGON_V6_vgathermhw", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhw_128B :
+Hexagon__ptri32i32v64i32_Intrinsic<"HEXAGON_V6_vgathermhw_128B", [IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermwq :
+Hexagon_custom__ptrv64i1i32i32v16i32_Intrinsic<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermwq_128B :
+Hexagon_custom__ptrv128i1i32i32v32i32_Intrinsic_128B<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhq :
+Hexagon_custom__ptrv64i1i32i32v16i32_Intrinsic<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhq_128B :
+Hexagon_custom__ptrv128i1i32i32v32i32_Intrinsic_128B<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhwq :
+Hexagon_custom__ptrv64i1i32i32v32i32_Intrinsic<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vgathermhwq_128B :
+Hexagon_custom__ptrv128i1i32i32v64i32_Intrinsic_128B<[IntrArgMemOnly]>;
+
+def int_hexagon_V6_vscattermw :
+Hexagon__i32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vscattermw", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermw_128B :
+Hexagon__i32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vscattermw_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermh :
+Hexagon__i32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vscattermh", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermh_128B :
+Hexagon__i32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vscattermh_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermw_add :
+Hexagon__i32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vscattermw_add", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermw_add_128B :
+Hexagon__i32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vscattermw_add_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermh_add :
+Hexagon__i32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vscattermh_add", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermh_add_128B :
+Hexagon__i32i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vscattermh_add_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermwq :
+Hexagon_custom__v64i1i32i32v16i32v16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermwq_128B :
+Hexagon_custom__v128i1i32i32v32i32v32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhq :
+Hexagon_custom__v64i1i32i32v16i32v16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhq_128B :
+Hexagon_custom__v128i1i32i32v32i32v32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhw :
+Hexagon__i32i32v32i32v16i32_Intrinsic<"HEXAGON_V6_vscattermhw", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhw_128B :
+Hexagon__i32i32v64i32v32i32_Intrinsic<"HEXAGON_V6_vscattermhw_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhwq :
+Hexagon_custom__v64i1i32i32v32i32v16i32_Intrinsic<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhwq_128B :
+Hexagon_custom__v128i1i32i32v64i32v32i32_Intrinsic_128B<[IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhw_add :
+Hexagon__i32i32v32i32v16i32_Intrinsic<"HEXAGON_V6_vscattermhw_add", [IntrWriteMem]>;
+
+def int_hexagon_V6_vscattermhw_add_128B :
+Hexagon__i32i32v64i32v32i32_Intrinsic<"HEXAGON_V6_vscattermhw_add_128B", [IntrWriteMem]>;
+
+def int_hexagon_V6_vprefixqb :
+Hexagon_custom_v16i32_v64i1_Intrinsic;
+
+def int_hexagon_V6_vprefixqb_128B :
+Hexagon_custom_v32i32_v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vprefixqh :
+Hexagon_custom_v16i32_v64i1_Intrinsic;
+
+def int_hexagon_V6_vprefixqh_128B :
+Hexagon_custom_v32i32_v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vprefixqw :
+Hexagon_custom_v16i32_v64i1_Intrinsic;
+
+def int_hexagon_V6_vprefixqw_128B :
+Hexagon_custom_v32i32_v128i1_Intrinsic_128B;
+
+// V66 HVX Instructions.
+
+def int_hexagon_V6_vrotr :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vrotr">;
+
+def int_hexagon_V6_vrotr_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vrotr_128B">;
+
+def int_hexagon_V6_vasr_into :
+Hexagon_v32i32_v32i32v16i32v16i32_Intrinsic<"HEXAGON_V6_vasr_into">;
+
+def int_hexagon_V6_vasr_into_128B :
+Hexagon_v64i32_v64i32v32i32v32i32_Intrinsic<"HEXAGON_V6_vasr_into_128B">;
+
+def int_hexagon_V6_vaddcarrysat :
+Hexagon_custom_v16i32_v16i32v16i32v64i1_Intrinsic;
+
+def int_hexagon_V6_vaddcarrysat_128B :
+Hexagon_custom_v32i32_v32i32v32i32v128i1_Intrinsic_128B;
+
+def int_hexagon_V6_vsatdw :
+Hexagon_v16i32_v16i32v16i32_Intrinsic<"HEXAGON_V6_vsatdw">;
+
+def int_hexagon_V6_vsatdw_128B :
+Hexagon_v32i32_v32i32v32i32_Intrinsic<"HEXAGON_V6_vsatdw_128B">;
+
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsMips.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsMips.td
index bfcdd80a52d5..271142ca7788 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsMips.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsMips.td
@@ -234,9 +234,9 @@ def int_mips_extpdp: GCCBuiltin<"__builtin_mips_extpdp">,
// Misc
def int_mips_wrdsp: GCCBuiltin<"__builtin_mips_wrdsp">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<1>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<1>>]>;
def int_mips_rddsp: GCCBuiltin<"__builtin_mips_rddsp">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem, ImmArg<0>]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrReadMem, ImmArg<ArgIndex<0>>]>;
def int_mips_insv: GCCBuiltin<"__builtin_mips_insv">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty], [IntrReadMem]>;
@@ -302,10 +302,10 @@ def int_mips_adduh_r_qb: GCCBuiltin<"__builtin_mips_adduh_r_qb">,
def int_mips_append: GCCBuiltin<"__builtin_mips_append">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_balign: GCCBuiltin<"__builtin_mips_balign">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_cmpgdu_eq_qb: GCCBuiltin<"__builtin_mips_cmpgdu_eq_qb">,
Intrinsic<[llvm_i32_ty], [llvm_v4i8_ty, llvm_v4i8_ty], [Commutative]>;
@@ -355,14 +355,14 @@ def int_mips_precr_qb_ph: GCCBuiltin<"__builtin_mips_precr_qb_ph">,
Intrinsic<[llvm_v4i8_ty], [llvm_v2i16_ty, llvm_v2i16_ty], []>;
def int_mips_precr_sra_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_ph_w">,
Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_precr_sra_r_ph_w: GCCBuiltin<"__builtin_mips_precr_sra_r_ph_w">,
Intrinsic<[llvm_v2i16_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_prepend: GCCBuiltin<"__builtin_mips_prepend">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_shra_qb: GCCBuiltin<"__builtin_mips_shra_qb">,
Intrinsic<[llvm_v4i8_ty], [llvm_v4i8_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -463,22 +463,22 @@ def int_mips_addv_d : GCCBuiltin<"__builtin_msa_addv_d">,
def int_mips_addvi_b : GCCBuiltin<"__builtin_msa_addvi_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty],
- [Commutative, IntrNoMem, ImmArg<1>]>;
+ [Commutative, IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_addvi_h : GCCBuiltin<"__builtin_msa_addvi_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty],
- [Commutative, IntrNoMem, ImmArg<1>]>;
+ [Commutative, IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_addvi_w : GCCBuiltin<"__builtin_msa_addvi_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty],
- [Commutative, IntrNoMem, ImmArg<1>]>;
+ [Commutative, IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_addvi_d : GCCBuiltin<"__builtin_msa_addvi_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty],
- [Commutative, IntrNoMem, ImmArg<1>]>;
+ [Commutative, IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_and_v : GCCBuiltin<"__builtin_msa_and_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_andi_b : GCCBuiltin<"__builtin_msa_andi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_asub_s_b : GCCBuiltin<"__builtin_msa_asub_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -560,13 +560,13 @@ def int_mips_bclr_d : GCCBuiltin<"__builtin_msa_bclr_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_bclri_b : GCCBuiltin<"__builtin_msa_bclri_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bclri_h : GCCBuiltin<"__builtin_msa_bclri_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bclri_w : GCCBuiltin<"__builtin_msa_bclri_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bclri_d : GCCBuiltin<"__builtin_msa_bclri_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_binsl_b : GCCBuiltin<"__builtin_msa_binsl_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
@@ -583,16 +583,16 @@ def int_mips_binsl_d : GCCBuiltin<"__builtin_msa_binsl_d">,
def int_mips_binsli_b : GCCBuiltin<"__builtin_msa_binsli_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsli_h : GCCBuiltin<"__builtin_msa_binsli_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsli_w : GCCBuiltin<"__builtin_msa_binsli_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsli_d : GCCBuiltin<"__builtin_msa_binsli_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsr_b : GCCBuiltin<"__builtin_msa_binsr_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
@@ -609,16 +609,16 @@ def int_mips_binsr_d : GCCBuiltin<"__builtin_msa_binsr_d">,
def int_mips_binsri_b : GCCBuiltin<"__builtin_msa_binsri_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsri_h : GCCBuiltin<"__builtin_msa_binsri_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsri_w : GCCBuiltin<"__builtin_msa_binsri_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_binsri_d : GCCBuiltin<"__builtin_msa_binsri_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_bmnz_v : GCCBuiltin<"__builtin_msa_bmnz_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
@@ -626,7 +626,7 @@ def int_mips_bmnz_v : GCCBuiltin<"__builtin_msa_bmnz_v">,
def int_mips_bmnzi_b : GCCBuiltin<"__builtin_msa_bmnzi_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_bmz_v : GCCBuiltin<"__builtin_msa_bmz_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
@@ -634,7 +634,7 @@ def int_mips_bmz_v : GCCBuiltin<"__builtin_msa_bmz_v">,
def int_mips_bmzi_b : GCCBuiltin<"__builtin_msa_bmzi_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_bneg_b : GCCBuiltin<"__builtin_msa_bneg_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -646,13 +646,13 @@ def int_mips_bneg_d : GCCBuiltin<"__builtin_msa_bneg_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_bnegi_b : GCCBuiltin<"__builtin_msa_bnegi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bnegi_h : GCCBuiltin<"__builtin_msa_bnegi_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bnegi_w : GCCBuiltin<"__builtin_msa_bnegi_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bnegi_d : GCCBuiltin<"__builtin_msa_bnegi_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bnz_b : GCCBuiltin<"__builtin_msa_bnz_b">,
Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
@@ -672,7 +672,7 @@ def int_mips_bsel_v : GCCBuiltin<"__builtin_msa_bsel_v">,
def int_mips_bseli_b : GCCBuiltin<"__builtin_msa_bseli_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_bset_b : GCCBuiltin<"__builtin_msa_bset_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -684,13 +684,13 @@ def int_mips_bset_d : GCCBuiltin<"__builtin_msa_bset_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_bseti_b : GCCBuiltin<"__builtin_msa_bseti_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bseti_h : GCCBuiltin<"__builtin_msa_bseti_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bseti_w : GCCBuiltin<"__builtin_msa_bseti_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bseti_d : GCCBuiltin<"__builtin_msa_bseti_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_bz_b : GCCBuiltin<"__builtin_msa_bz_b">,
Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty], [IntrNoMem]>;
@@ -714,16 +714,16 @@ def int_mips_ceq_d : GCCBuiltin<"__builtin_msa_ceq_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_ceqi_b : GCCBuiltin<"__builtin_msa_ceqi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_ceqi_h : GCCBuiltin<"__builtin_msa_ceqi_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_ceqi_w : GCCBuiltin<"__builtin_msa_ceqi_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_ceqi_d : GCCBuiltin<"__builtin_msa_ceqi_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_cfcmsa : GCCBuiltin<"__builtin_msa_cfcmsa">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
def int_mips_cle_s_b : GCCBuiltin<"__builtin_msa_cle_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -744,22 +744,22 @@ def int_mips_cle_u_d : GCCBuiltin<"__builtin_msa_cle_u_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_clei_s_b : GCCBuiltin<"__builtin_msa_clei_s_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_s_h : GCCBuiltin<"__builtin_msa_clei_s_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_s_w : GCCBuiltin<"__builtin_msa_clei_s_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_s_d : GCCBuiltin<"__builtin_msa_clei_s_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_u_b : GCCBuiltin<"__builtin_msa_clei_u_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_u_h : GCCBuiltin<"__builtin_msa_clei_u_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_u_w : GCCBuiltin<"__builtin_msa_clei_u_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clei_u_d : GCCBuiltin<"__builtin_msa_clei_u_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clt_s_b : GCCBuiltin<"__builtin_msa_clt_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -780,22 +780,22 @@ def int_mips_clt_u_d : GCCBuiltin<"__builtin_msa_clt_u_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_clti_s_b : GCCBuiltin<"__builtin_msa_clti_s_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_s_h : GCCBuiltin<"__builtin_msa_clti_s_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_s_w : GCCBuiltin<"__builtin_msa_clti_s_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_s_d : GCCBuiltin<"__builtin_msa_clti_s_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_u_b : GCCBuiltin<"__builtin_msa_clti_u_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_u_h : GCCBuiltin<"__builtin_msa_clti_u_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_u_w : GCCBuiltin<"__builtin_msa_clti_u_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_clti_u_d : GCCBuiltin<"__builtin_msa_clti_u_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_copy_s_b : GCCBuiltin<"__builtin_msa_copy_s_b">,
Intrinsic<[llvm_i32_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -816,7 +816,7 @@ def int_mips_copy_u_d : GCCBuiltin<"__builtin_msa_copy_u_d">,
Intrinsic<[llvm_i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_ctcmsa : GCCBuiltin<"__builtin_msa_ctcmsa">,
- Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<0>]>;
+ Intrinsic<[], [llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
def int_mips_div_s_b : GCCBuiltin<"__builtin_msa_div_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1244,19 +1244,19 @@ def int_mips_insert_d : GCCBuiltin<"__builtin_msa_insert_d">,
def int_mips_insve_b : GCCBuiltin<"__builtin_msa_insve_b">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_insve_h : GCCBuiltin<"__builtin_msa_insve_h">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v8i16_ty, llvm_i32_ty, llvm_v8i16_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_insve_w : GCCBuiltin<"__builtin_msa_insve_w">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_i32_ty, llvm_v4i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_insve_d : GCCBuiltin<"__builtin_msa_insve_d">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_i32_ty, llvm_v2i64_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_ld_b : GCCBuiltin<"__builtin_msa_ld_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty],
@@ -1271,14 +1271,21 @@ def int_mips_ld_d : GCCBuiltin<"__builtin_msa_ld_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty],
[IntrReadMem, IntrArgMemOnly]>;
+def int_mips_ldr_d : GCCBuiltin<"__builtin_msa_ldr_d">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly]>;
+def int_mips_ldr_w : GCCBuiltin<"__builtin_msa_ldr_w">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrReadMem, IntrArgMemOnly]>;
+
def int_mips_ldi_b : GCCBuiltin<"__builtin_msa_ldi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_mips_ldi_h : GCCBuiltin<"__builtin_msa_ldi_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_mips_ldi_w : GCCBuiltin<"__builtin_msa_ldi_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<0>>]>;
def int_mips_ldi_d : GCCBuiltin<"__builtin_msa_ldi_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<0>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<0>>]>;
// This instruction is part of the MSA spec but it does not share the
// __builtin_msa prefix because it operates on the GPR registers.
@@ -1341,22 +1348,22 @@ def int_mips_max_u_d : GCCBuiltin<"__builtin_msa_max_u_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_maxi_s_b : GCCBuiltin<"__builtin_msa_maxi_s_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_s_h : GCCBuiltin<"__builtin_msa_maxi_s_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_s_w : GCCBuiltin<"__builtin_msa_maxi_s_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_s_d : GCCBuiltin<"__builtin_msa_maxi_s_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_u_b : GCCBuiltin<"__builtin_msa_maxi_u_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_u_h : GCCBuiltin<"__builtin_msa_maxi_u_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_u_w : GCCBuiltin<"__builtin_msa_maxi_u_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_maxi_u_d : GCCBuiltin<"__builtin_msa_maxi_u_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_min_a_b : GCCBuiltin<"__builtin_msa_min_a_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1386,22 +1393,22 @@ def int_mips_min_u_d : GCCBuiltin<"__builtin_msa_min_u_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_mini_s_b : GCCBuiltin<"__builtin_msa_mini_s_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_s_h : GCCBuiltin<"__builtin_msa_mini_s_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_s_w : GCCBuiltin<"__builtin_msa_mini_s_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_s_d : GCCBuiltin<"__builtin_msa_mini_s_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_u_b : GCCBuiltin<"__builtin_msa_mini_u_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_u_h : GCCBuiltin<"__builtin_msa_mini_u_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_u_w : GCCBuiltin<"__builtin_msa_mini_u_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mini_u_d : GCCBuiltin<"__builtin_msa_mini_u_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_mod_s_b : GCCBuiltin<"__builtin_msa_mod_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1492,13 +1499,13 @@ def int_mips_nor_v : GCCBuiltin<"__builtin_msa_nor_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_nori_b : GCCBuiltin<"__builtin_msa_nori_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_or_v : GCCBuiltin<"__builtin_msa_or_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_ori_b : GCCBuiltin<"__builtin_msa_ori_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_pckev_b : GCCBuiltin<"__builtin_msa_pckev_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1528,29 +1535,29 @@ def int_mips_pcnt_d : GCCBuiltin<"__builtin_msa_pcnt_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_sat_s_b : GCCBuiltin<"__builtin_msa_sat_s_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_s_h : GCCBuiltin<"__builtin_msa_sat_s_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_s_w : GCCBuiltin<"__builtin_msa_sat_s_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_s_d : GCCBuiltin<"__builtin_msa_sat_s_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_u_b : GCCBuiltin<"__builtin_msa_sat_u_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_u_h : GCCBuiltin<"__builtin_msa_sat_u_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_u_w : GCCBuiltin<"__builtin_msa_sat_u_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sat_u_d : GCCBuiltin<"__builtin_msa_sat_u_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_shf_b : GCCBuiltin<"__builtin_msa_shf_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_shf_h : GCCBuiltin<"__builtin_msa_shf_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_shf_w : GCCBuiltin<"__builtin_msa_shf_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sld_b : GCCBuiltin<"__builtin_msa_sld_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -1563,16 +1570,16 @@ def int_mips_sld_d : GCCBuiltin<"__builtin_msa_sld_d">,
def int_mips_sldi_b : GCCBuiltin<"__builtin_msa_sldi_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_sldi_h : GCCBuiltin<"__builtin_msa_sldi_h">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_sldi_w : GCCBuiltin<"__builtin_msa_sldi_w">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_sldi_d : GCCBuiltin<"__builtin_msa_sldi_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_mips_sll_b : GCCBuiltin<"__builtin_msa_sll_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1584,13 +1591,13 @@ def int_mips_sll_d : GCCBuiltin<"__builtin_msa_sll_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_slli_b : GCCBuiltin<"__builtin_msa_slli_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_slli_h : GCCBuiltin<"__builtin_msa_slli_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_slli_w : GCCBuiltin<"__builtin_msa_slli_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_slli_d : GCCBuiltin<"__builtin_msa_slli_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_splat_b : GCCBuiltin<"__builtin_msa_splat_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
@@ -1602,13 +1609,13 @@ def int_mips_splat_d : GCCBuiltin<"__builtin_msa_splat_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
def int_mips_splati_b : GCCBuiltin<"__builtin_msa_splati_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_splati_h : GCCBuiltin<"__builtin_msa_splati_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_splati_w : GCCBuiltin<"__builtin_msa_splati_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_splati_d : GCCBuiltin<"__builtin_msa_splati_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_sra_b : GCCBuiltin<"__builtin_msa_sra_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1620,13 +1627,13 @@ def int_mips_sra_d : GCCBuiltin<"__builtin_msa_sra_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_srai_b : GCCBuiltin<"__builtin_msa_srai_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srai_h : GCCBuiltin<"__builtin_msa_srai_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srai_w : GCCBuiltin<"__builtin_msa_srai_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srai_d : GCCBuiltin<"__builtin_msa_srai_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srar_b : GCCBuiltin<"__builtin_msa_srar_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1638,13 +1645,13 @@ def int_mips_srar_d : GCCBuiltin<"__builtin_msa_srar_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_srari_b : GCCBuiltin<"__builtin_msa_srari_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srari_h : GCCBuiltin<"__builtin_msa_srari_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srari_w : GCCBuiltin<"__builtin_msa_srari_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srari_d : GCCBuiltin<"__builtin_msa_srari_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srl_b : GCCBuiltin<"__builtin_msa_srl_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1656,13 +1663,13 @@ def int_mips_srl_d : GCCBuiltin<"__builtin_msa_srl_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_srli_b : GCCBuiltin<"__builtin_msa_srli_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srli_h : GCCBuiltin<"__builtin_msa_srli_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srli_w : GCCBuiltin<"__builtin_msa_srli_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srli_d : GCCBuiltin<"__builtin_msa_srli_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srlr_b : GCCBuiltin<"__builtin_msa_srlr_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
@@ -1674,13 +1681,13 @@ def int_mips_srlr_d : GCCBuiltin<"__builtin_msa_srlr_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_srlri_b : GCCBuiltin<"__builtin_msa_srlri_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srlri_h : GCCBuiltin<"__builtin_msa_srlri_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srlri_w : GCCBuiltin<"__builtin_msa_srlri_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_srlri_d : GCCBuiltin<"__builtin_msa_srlri_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_st_b : GCCBuiltin<"__builtin_msa_st_b">,
Intrinsic<[], [llvm_v16i8_ty, llvm_ptr_ty, llvm_i32_ty],
@@ -1695,6 +1702,13 @@ def int_mips_st_d : GCCBuiltin<"__builtin_msa_st_d">,
Intrinsic<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty],
[IntrArgMemOnly]>;
+def int_mips_str_d : GCCBuiltin<"__builtin_msa_str_d">,
+ Intrinsic<[], [llvm_v2i64_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrArgMemOnly]>;
+def int_mips_str_w : GCCBuiltin<"__builtin_msa_str_w">,
+ Intrinsic<[], [llvm_v4i32_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrArgMemOnly]>;
+
def int_mips_subs_s_b : GCCBuiltin<"__builtin_msa_subs_s_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_subs_s_h : GCCBuiltin<"__builtin_msa_subs_s_h">,
@@ -1741,13 +1755,13 @@ def int_mips_subv_d : GCCBuiltin<"__builtin_msa_subv_d">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
def int_mips_subvi_b : GCCBuiltin<"__builtin_msa_subvi_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_subvi_h : GCCBuiltin<"__builtin_msa_subvi_h">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_subvi_w : GCCBuiltin<"__builtin_msa_subvi_w">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_subvi_d : GCCBuiltin<"__builtin_msa_subvi_d">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_mips_vshf_b : GCCBuiltin<"__builtin_msa_vshf_b">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
@@ -1766,5 +1780,5 @@ def int_mips_xor_v : GCCBuiltin<"__builtin_msa_xor_v">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_mips_xori_b : GCCBuiltin<"__builtin_msa_xori_b">,
- Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsNVVM.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsNVVM.td
index ec328d69a8dd..61293418ec41 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsNVVM.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsNVVM.td
@@ -978,20 +978,20 @@ let TargetPrefix = "nvvm" in {
// Atomics not available as llvm intrinsics.
def int_nvvm_atomic_load_inc_32 : Intrinsic<[llvm_i32_ty],
[LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_nvvm_atomic_load_dec_32 : Intrinsic<[llvm_i32_ty],
[LLVMAnyPointerType<llvm_i32_ty>, llvm_i32_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
class SCOPED_ATOMIC2_impl<LLVMType elty>
: Intrinsic<[elty],
[LLVMAnyPointerType<LLVMMatchType<0>>, LLVMMatchType<0>],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
class SCOPED_ATOMIC3_impl<LLVMType elty>
: Intrinsic<[elty],
[LLVMAnyPointerType<LLVMMatchType<0>>, LLVMMatchType<0>,
LLVMMatchType<0>],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
multiclass PTXAtomicWithScope2<LLVMType elty> {
def _cta : SCOPED_ATOMIC2_impl<elty>;
@@ -1063,30 +1063,30 @@ let TargetPrefix = "nvvm" in {
// pointer's alignment.
def int_nvvm_ldu_global_i : Intrinsic<[llvm_anyint_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldu.global.i">;
def int_nvvm_ldu_global_f : Intrinsic<[llvm_anyfloat_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldu.global.f">;
def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldu.global.p">;
// Generated within nvvm. Use for ldg on sm_35 or later. Second arg is the
// pointer's alignment.
def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldg.global.i">;
def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldg.global.f">;
def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty],
[LLVMAnyPointerType<LLVMMatchType<0>>, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, NoCapture<ArgIndex<0>>],
"llvm.nvvm.ldg.global.p">;
// Use for generic pointers
@@ -1143,7 +1143,7 @@ def int_nvvm_move_float : Intrinsic<[llvm_float_ty], [llvm_float_ty],
def int_nvvm_move_double : Intrinsic<[llvm_double_ty], [llvm_double_ty],
[IntrNoMem], "llvm.nvvm.move.double">;
def int_nvvm_move_ptr : Intrinsic<[llvm_anyptr_ty], [llvm_anyptr_ty],
- [IntrNoMem, NoCapture<0>], "llvm.nvvm.move.ptr">;
+ [IntrNoMem, NoCapture<ArgIndex<0>>], "llvm.nvvm.move.ptr">;
// For getting the handle from a texture or surface variable
@@ -4110,7 +4110,7 @@ def int_nvvm_match_all_sync_i64p :
class NVVM_WMMA_LD<WMMA_REGS Frag, string Layout, int WithStride>
: Intrinsic<Frag.regs,
!if(WithStride, [llvm_anyptr_ty, llvm_i32_ty], [llvm_anyptr_ty]),
- [IntrReadMem, IntrArgMemOnly, ReadOnly<0>, NoCapture<0>],
+ [IntrReadMem, IntrArgMemOnly, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
WMMA_NAME_LDST<"load", Frag, Layout, WithStride>.intr>;
// WMMA.STORE.D
@@ -4120,7 +4120,7 @@ class NVVM_WMMA_ST<WMMA_REGS Frag, string Layout, int WithStride>
[llvm_anyptr_ty],
Frag.regs,
!if(WithStride, [llvm_i32_ty], [])),
- [IntrWriteMem, IntrArgMemOnly, WriteOnly<0>, NoCapture<0>],
+ [IntrWriteMem, IntrArgMemOnly, WriteOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
WMMA_NAME_LDST<"store", Frag, Layout, WithStride>.intr>;
// Create all load/store variants
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index fc9fa2153aea..614a29049686 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -20,28 +20,32 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_dcba : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbf : GCCBuiltin<"__builtin_dcbf">,
Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbfl : Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_ppc_dcbflp: Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbi : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbst : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbt : Intrinsic<[], [llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
def int_ppc_dcbtst: Intrinsic<[], [llvm_ptr_ty],
- [IntrArgMemOnly, NoCapture<0>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>]>;
+ def int_ppc_dcbt_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
+ def int_ppc_dcbtst_with_hint: Intrinsic<[], [llvm_ptr_ty, llvm_i32_ty],
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<1>>]>;
def int_ppc_dcbz : Intrinsic<[], [llvm_ptr_ty], []>;
def int_ppc_dcbzl : Intrinsic<[], [llvm_ptr_ty], []>;
+ // Population Count in each Byte.
+ def int_ppc_popcntb : Intrinsic<[llvm_i64_ty], [llvm_i64_ty], [IntrNoMem]>;
+
// sync instruction (i.e. sync 0, a.k.a hwsync)
def int_ppc_sync : Intrinsic<[], [], []>;
+ // isync instruction
+ def int_ppc_isync : Intrinsic<[], [], []>;
// lwsync is sync 1
def int_ppc_lwsync : Intrinsic<[], [], []>;
-
- // Intrinsics used to generate ctr-based loops. These should only be
- // generated by the PowerPC backend!
- // The branch intrinsic is marked as NoDuplicate because loop rotation will
- // attempt to duplicate it forming loops where a block reachable from one
- // instance of it can contain another.
- def int_ppc_mtctr : Intrinsic<[], [llvm_anyint_ty], []>;
- def int_ppc_is_decremented_ctr_nonzero :
- Intrinsic<[llvm_i1_ty], [], [IntrNoDuplicate]>;
+ // eieio instruction
+ def int_ppc_eieio : Intrinsic<[],[],[]>;
// Intrinsics for [double]word extended forms of divide instructions
def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
@@ -62,6 +66,27 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
[IntrNoMem]>;
+ // Parallel Bits Deposit/Extract Doubleword Builtins.
+ def int_ppc_pdepd
+ : GCCBuiltin<"__builtin_pdepd">,
+ Intrinsic <[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_pextd
+ : GCCBuiltin<"__builtin_pextd">,
+ Intrinsic <[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
+ // Centrifuge Doubleword Builtin.
+ def int_ppc_cfuged
+ : GCCBuiltin<"__builtin_cfuged">,
+ Intrinsic <[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
+ // Count Leading / Trailing Zeroes under bit Mask Builtins.
+ def int_ppc_cntlzdm
+ : GCCBuiltin<"__builtin_cntlzdm">,
+ Intrinsic <[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+ def int_ppc_cnttzdm
+ : GCCBuiltin<"__builtin_cnttzdm">,
+ Intrinsic <[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty], [IntrNoMem]>;
+
def int_ppc_truncf128_round_to_odd
: GCCBuiltin<"__builtin_truncf128_round_to_odd">,
Intrinsic <[llvm_double_ty], [llvm_f128_ty], [IntrNoMem]>;
@@ -404,6 +429,108 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vprtybq : GCCBuiltin<"__builtin_altivec_vprtybq">,
Intrinsic<[llvm_v1i128_ty],[llvm_v1i128_ty],[IntrNoMem]>;
+ // P10 Vector Parallel Bits Deposit/Extract Doubleword Builtins.
+ def int_ppc_altivec_vpdepd : GCCBuiltin<"__builtin_altivec_vpdepd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpextd : GCCBuiltin<"__builtin_altivec_vpextd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
+ // P10 Vector Centrifuge Builtin.
+ def int_ppc_altivec_vcfuged : GCCBuiltin<"__builtin_altivec_vcfuged">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
+ // P10 Vector Gather Every Nth Bit Builtin.
+ def int_ppc_altivec_vgnb : GCCBuiltin<"__builtin_altivec_vgnb">,
+ Intrinsic<[llvm_i64_ty], [llvm_v1i128_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+
+ // P10 Vector Clear Bytes
+ def int_ppc_altivec_vclrlb : GCCBuiltin<"__builtin_altivec_vclrlb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vclrrb : GCCBuiltin<"__builtin_altivec_vclrrb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ // P10 Vector Shift Double Bit Immediate.
+ def int_ppc_altivec_vsldbi : GCCBuiltin<"__builtin_altivec_vsldbi">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ def int_ppc_altivec_vsrdbi : GCCBuiltin<"__builtin_altivec_vsrdbi">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+
+ // P10 Vector Insert.
+ def int_ppc_altivec_vinsblx : GCCBuiltin<"__builtin_altivec_vinsblx">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinsbrx : GCCBuiltin<"__builtin_altivec_vinsbrx">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinshlx : GCCBuiltin<"__builtin_altivec_vinshlx">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinshrx : GCCBuiltin<"__builtin_altivec_vinshrx">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinswlx : GCCBuiltin<"__builtin_altivec_vinswlx">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinswrx : GCCBuiltin<"__builtin_altivec_vinswrx">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinsdlx : GCCBuiltin<"__builtin_altivec_vinsdlx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinsdrx : GCCBuiltin<"__builtin_altivec_vinsdrx">,
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_i64_ty, llvm_i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinsbvlx : GCCBuiltin<"__builtin_altivec_vinsbvlx">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i64_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinsbvrx : GCCBuiltin<"__builtin_altivec_vinsbvrx">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i64_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinshvlx : GCCBuiltin<"__builtin_altivec_vinshvlx">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i64_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinshvrx : GCCBuiltin<"__builtin_altivec_vinshvrx">,
+ Intrinsic<[llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i64_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinswvlx : GCCBuiltin<"__builtin_altivec_vinswvlx">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i64_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vinswvrx : GCCBuiltin<"__builtin_altivec_vinswvrx">,
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i64_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ // P10 Vector Insert with immediate.
+ def int_ppc_altivec_vinsw :
+ Intrinsic<[llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
+ def int_ppc_altivec_vinsd :
+ Intrinsic<[llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_i64_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Vector average.
@@ -472,7 +599,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
- // Vector Multiply Sum Intructions.
+ // Vector Multiply Sum Instructions.
def int_ppc_altivec_vmsummbm : GCCBuiltin<"__builtin_altivec_vmsummbm">,
Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_v16i8_ty,
llvm_v4i32_ty], [IntrNoMem]>;
@@ -495,7 +622,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty,
llvm_v4i32_ty], [IntrNoMem]>;
- // Vector Multiply Intructions.
+ // Vector Multiply Instructions.
def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
@@ -534,7 +661,7 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
- // Vector Sum Intructions.
+ // Vector Sum Instructions.
def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
@@ -613,16 +740,16 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
// FP <-> integer conversion.
def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
@@ -652,6 +779,14 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
Intrinsic<[llvm_v1i128_ty],
[llvm_v1i128_ty, llvm_v1i128_ty, llvm_v1i128_ty],
[IntrNoMem]>;
+
+ // P10 Vector Count Leading / Trailing Zeroes under bit Mask Builtins.
+ def int_ppc_altivec_vclzdm : GCCBuiltin<"__builtin_altivec_vclzdm">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vctzdm : GCCBuiltin<"__builtin_altivec_vctzdm">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
}
def int_ppc_altivec_vsl : PowerPC_Vec_WWW_Intrinsic<"vsl">;
@@ -719,11 +854,11 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_crypto_vshasigmad :
GCCBuiltin<"__builtin_altivec_crypto_vshasigmad">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
def int_ppc_altivec_crypto_vshasigmaw :
GCCBuiltin<"__builtin_altivec_crypto_vshasigmaw">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
}
def int_ppc_altivec_crypto_vcipher :
PowerPC_Vec_DDD_Intrinsic<"crypto_vcipher">;
@@ -918,10 +1053,10 @@ def int_ppc_vsx_xvxsigsp :
[llvm_v4f32_ty], [IntrNoMem]>;
def int_ppc_vsx_xvtstdcdp :
PowerPC_VSX_Intrinsic<"xvtstdcdp", [llvm_v2i64_ty],
- [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ [llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_vsx_xvtstdcsp :
PowerPC_VSX_Intrinsic<"xvtstdcsp", [llvm_v4i32_ty],
- [llvm_v4f32_ty,llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ [llvm_v4f32_ty,llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_ppc_vsx_xvcvhpsp :
PowerPC_VSX_Intrinsic<"xvcvhpsp", [llvm_v4f32_ty],
[llvm_v8i16_ty],[IntrNoMem]>;
@@ -932,6 +1067,46 @@ def int_ppc_vsx_xxinsertw :
PowerPC_VSX_Intrinsic<"xxinsertw",[llvm_v4i32_ty],
[llvm_v4i32_ty,llvm_v2i64_ty,llvm_i32_ty],
[IntrNoMem]>;
+def int_ppc_vsx_xvtlsbb :
+ PowerPC_VSX_Intrinsic<"xvtlsbb", [llvm_i32_ty],
+ [llvm_v16i8_ty, llvm_i1_ty], [IntrNoMem]>;
+def int_ppc_vsx_xxeval :
+ PowerPC_VSX_Intrinsic<"xxeval", [llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty, llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+def int_ppc_vsx_xxgenpcvbm :
+ PowerPC_VSX_Intrinsic<"xxgenpcvbm", [llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xxgenpcvhm :
+ PowerPC_VSX_Intrinsic<"xxgenpcvhm", [llvm_v8i16_ty],
+ [llvm_v8i16_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xxgenpcvwm :
+ PowerPC_VSX_Intrinsic<"xxgenpcvwm", [llvm_v4i32_ty],
+ [llvm_v4i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_vsx_xxgenpcvdm :
+ PowerPC_VSX_Intrinsic<"xxgenpcvdm", [llvm_v2i64_ty],
+ [llvm_v2i64_ty, llvm_i32_ty], [IntrNoMem]>;
+
+// P10 VSX Vector permute extended.
+def int_ppc_vsx_xxpermx :
+ GCCBuiltin<"__builtin_vsx_xxpermx">,
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty,llvm_v16i8_ty,llvm_v16i8_ty,llvm_i32_ty],
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
+// P10 VSX Vector Blend Variable.
+def int_ppc_vsx_xxblendvb: GCCBuiltin<"__builtin_vsx_xxblendvb">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+def int_ppc_vsx_xxblendvh: GCCBuiltin<"__builtin_vsx_xxblendvh">,
+ Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+def int_ppc_vsx_xxblendvw: GCCBuiltin<"__builtin_vsx_xxblendvw">,
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+def int_ppc_vsx_xxblendvd: GCCBuiltin<"__builtin_vsx_xxblendvd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
}
//===----------------------------------------------------------------------===//
@@ -1116,9 +1291,9 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_tbegin : GCCBuiltin<"__builtin_tbegin">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
def int_ppc_tend : GCCBuiltin<"__builtin_tend">,
- Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<0>]>;
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], [ImmArg<ArgIndex<0>>]>;
def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td
index 2039ad1a26b8..7590b568c367 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsRISCV.td
@@ -28,11 +28,11 @@ let TargetPrefix = "riscv" in {
// T @llvm.<name>.T.<p>(any*, T, T, T imm);
class MaskedAtomicRMWFourArg<LLVMType itype>
: Intrinsic<[itype], [llvm_anyptr_ty, itype, itype, itype],
- [IntrArgMemOnly, NoCapture<0>, ImmArg<3>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<3>>]>;
// T @llvm.<name>.T.<p>(any*, T, T, T, T imm);
class MaskedAtomicRMWFiveArg<LLVMType itype>
: Intrinsic<[itype], [llvm_anyptr_ty, itype, itype, itype, itype],
- [IntrArgMemOnly, NoCapture<0>, ImmArg<4>]>;
+ [IntrArgMemOnly, NoCapture<ArgIndex<0>>, ImmArg<ArgIndex<4>>]>;
// We define 32-bit and 64-bit variants of the above, where T stands for i32
// or i64 respectively:
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsSystemZ.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsSystemZ.td
index 40d6ba17eaf1..b0c5cf0148fe 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsSystemZ.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsSystemZ.td
@@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
class SystemZUnaryConv<string name, LLVMType result, LLVMType arg>
- : GCCBuiltin<"__builtin_s390_" ## name>,
+ : GCCBuiltin<"__builtin_s390_" # name>,
Intrinsic<[result], [arg], [IntrNoMem]>;
class SystemZUnary<string name, LLVMType type>
@@ -24,14 +24,14 @@ class SystemZUnaryCC<LLVMType type>
: SystemZUnaryConvCC<type, type>;
class SystemZBinaryConv<string name, LLVMType result, LLVMType arg>
- : GCCBuiltin<"__builtin_s390_" ## name>,
+ : GCCBuiltin<"__builtin_s390_" # name>,
Intrinsic<[result], [arg, arg], [IntrNoMem]>;
class SystemZBinary<string name, LLVMType type>
: SystemZBinaryConv<name, type, type>;
class SystemZBinaryInt<string name, LLVMType type>
- : GCCBuiltin<"__builtin_s390_" ## name>,
+ : GCCBuiltin<"__builtin_s390_" # name>,
Intrinsic<[type], [type, llvm_i32_ty], [IntrNoMem]>;
class SystemZBinaryConvCC<LLVMType result, LLVMType arg>
@@ -39,13 +39,13 @@ class SystemZBinaryConvCC<LLVMType result, LLVMType arg>
class SystemZBinaryConvIntCC<LLVMType result, LLVMType arg>
: Intrinsic<[result, llvm_i32_ty], [arg, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
class SystemZBinaryCC<LLVMType type>
: SystemZBinaryConvCC<type, type>;
class SystemZTernaryConv<string name, LLVMType result, LLVMType arg>
- : GCCBuiltin<"__builtin_s390_" ## name>,
+ : GCCBuiltin<"__builtin_s390_" # name>,
Intrinsic<[result], [arg, arg, result], [IntrNoMem]>;
class SystemZTernaryConvCC<LLVMType result, LLVMType arg>
@@ -55,42 +55,42 @@ class SystemZTernary<string name, LLVMType type>
: SystemZTernaryConv<name, type, type>;
class SystemZTernaryInt<string name, LLVMType type>
- : GCCBuiltin<"__builtin_s390_" ## name>,
- Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ : GCCBuiltin<"__builtin_s390_" # name>,
+ Intrinsic<[type], [type, type, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
class SystemZTernaryIntCC<LLVMType type>
: Intrinsic<[type, llvm_i32_ty], [type, type, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
class SystemZQuaternaryInt<string name, LLVMType type>
- : GCCBuiltin<"__builtin_s390_" ## name>,
+ : GCCBuiltin<"__builtin_s390_" # name>,
Intrinsic<[type], [type, type, type, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
class SystemZQuaternaryIntCC<LLVMType type>
: Intrinsic<[type, llvm_i32_ty], [type, type, type, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
multiclass SystemZUnaryExtBHF<string name> {
- def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
- def h : SystemZUnaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
- def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+ def b : SystemZUnaryConv<name#"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZUnaryConv<name#"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZUnaryConv<name#"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZUnaryExtBHWF<string name> {
- def b : SystemZUnaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
- def hw : SystemZUnaryConv<name##"hw", llvm_v4i32_ty, llvm_v8i16_ty>;
- def f : SystemZUnaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+ def b : SystemZUnaryConv<name#"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def hw : SystemZUnaryConv<name#"hw", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZUnaryConv<name#"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZUnaryBHF<string name> {
- def b : SystemZUnary<name##"b", llvm_v16i8_ty>;
- def h : SystemZUnary<name##"h", llvm_v8i16_ty>;
- def f : SystemZUnary<name##"f", llvm_v4i32_ty>;
+ def b : SystemZUnary<name#"b", llvm_v16i8_ty>;
+ def h : SystemZUnary<name#"h", llvm_v8i16_ty>;
+ def f : SystemZUnary<name#"f", llvm_v4i32_ty>;
}
multiclass SystemZUnaryBHFG<string name> : SystemZUnaryBHF<name> {
- def g : SystemZUnary<name##"g", llvm_v2i64_ty>;
+ def g : SystemZUnary<name#"g", llvm_v2i64_ty>;
}
multiclass SystemZUnaryCCBHF {
@@ -100,9 +100,9 @@ multiclass SystemZUnaryCCBHF {
}
multiclass SystemZBinaryTruncHFG<string name> {
- def h : SystemZBinaryConv<name##"h", llvm_v16i8_ty, llvm_v8i16_ty>;
- def f : SystemZBinaryConv<name##"f", llvm_v8i16_ty, llvm_v4i32_ty>;
- def g : SystemZBinaryConv<name##"g", llvm_v4i32_ty, llvm_v2i64_ty>;
+ def h : SystemZBinaryConv<name#"h", llvm_v16i8_ty, llvm_v8i16_ty>;
+ def f : SystemZBinaryConv<name#"f", llvm_v8i16_ty, llvm_v4i32_ty>;
+ def g : SystemZBinaryConv<name#"g", llvm_v4i32_ty, llvm_v2i64_ty>;
}
multiclass SystemZBinaryTruncCCHFG {
@@ -112,30 +112,30 @@ multiclass SystemZBinaryTruncCCHFG {
}
multiclass SystemZBinaryExtBHF<string name> {
- def b : SystemZBinaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
- def h : SystemZBinaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
- def f : SystemZBinaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+ def b : SystemZBinaryConv<name#"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZBinaryConv<name#"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZBinaryConv<name#"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZBinaryExtBHFG<string name> : SystemZBinaryExtBHF<name> {
- def g : SystemZBinaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
+ def g : SystemZBinaryConv<name#"g", llvm_v16i8_ty, llvm_v2i64_ty>;
}
multiclass SystemZBinaryBHF<string name> {
- def b : SystemZBinary<name##"b", llvm_v16i8_ty>;
- def h : SystemZBinary<name##"h", llvm_v8i16_ty>;
- def f : SystemZBinary<name##"f", llvm_v4i32_ty>;
+ def b : SystemZBinary<name#"b", llvm_v16i8_ty>;
+ def h : SystemZBinary<name#"h", llvm_v8i16_ty>;
+ def f : SystemZBinary<name#"f", llvm_v4i32_ty>;
}
multiclass SystemZBinaryBHFG<string name> : SystemZBinaryBHF<name> {
- def g : SystemZBinary<name##"g", llvm_v2i64_ty>;
+ def g : SystemZBinary<name#"g", llvm_v2i64_ty>;
}
multiclass SystemZBinaryIntBHFG<string name> {
- def b : SystemZBinaryInt<name##"b", llvm_v16i8_ty>;
- def h : SystemZBinaryInt<name##"h", llvm_v8i16_ty>;
- def f : SystemZBinaryInt<name##"f", llvm_v4i32_ty>;
- def g : SystemZBinaryInt<name##"g", llvm_v2i64_ty>;
+ def b : SystemZBinaryInt<name#"b", llvm_v16i8_ty>;
+ def h : SystemZBinaryInt<name#"h", llvm_v8i16_ty>;
+ def f : SystemZBinaryInt<name#"f", llvm_v4i32_ty>;
+ def g : SystemZBinaryInt<name#"g", llvm_v2i64_ty>;
}
multiclass SystemZBinaryCCBHF {
@@ -152,25 +152,25 @@ multiclass SystemZCompareBHFG<string name> {
}
multiclass SystemZTernaryExtBHF<string name> {
- def b : SystemZTernaryConv<name##"b", llvm_v8i16_ty, llvm_v16i8_ty>;
- def h : SystemZTernaryConv<name##"h", llvm_v4i32_ty, llvm_v8i16_ty>;
- def f : SystemZTernaryConv<name##"f", llvm_v2i64_ty, llvm_v4i32_ty>;
+ def b : SystemZTernaryConv<name#"b", llvm_v8i16_ty, llvm_v16i8_ty>;
+ def h : SystemZTernaryConv<name#"h", llvm_v4i32_ty, llvm_v8i16_ty>;
+ def f : SystemZTernaryConv<name#"f", llvm_v2i64_ty, llvm_v4i32_ty>;
}
multiclass SystemZTernaryExtBHFG<string name> : SystemZTernaryExtBHF<name> {
- def g : SystemZTernaryConv<name##"g", llvm_v16i8_ty, llvm_v2i64_ty>;
+ def g : SystemZTernaryConv<name#"g", llvm_v16i8_ty, llvm_v2i64_ty>;
}
multiclass SystemZTernaryBHF<string name> {
- def b : SystemZTernary<name##"b", llvm_v16i8_ty>;
- def h : SystemZTernary<name##"h", llvm_v8i16_ty>;
- def f : SystemZTernary<name##"f", llvm_v4i32_ty>;
+ def b : SystemZTernary<name#"b", llvm_v16i8_ty>;
+ def h : SystemZTernary<name#"h", llvm_v8i16_ty>;
+ def f : SystemZTernary<name#"f", llvm_v4i32_ty>;
}
multiclass SystemZTernaryIntBHF<string name> {
- def b : SystemZTernaryInt<name##"b", llvm_v16i8_ty>;
- def h : SystemZTernaryInt<name##"h", llvm_v8i16_ty>;
- def f : SystemZTernaryInt<name##"f", llvm_v4i32_ty>;
+ def b : SystemZTernaryInt<name#"b", llvm_v16i8_ty>;
+ def h : SystemZTernaryInt<name#"h", llvm_v8i16_ty>;
+ def f : SystemZTernaryInt<name#"f", llvm_v4i32_ty>;
}
multiclass SystemZTernaryIntCCBHF {
@@ -180,14 +180,14 @@ multiclass SystemZTernaryIntCCBHF {
}
multiclass SystemZQuaternaryIntBHF<string name> {
- def b : SystemZQuaternaryInt<name##"b", llvm_v16i8_ty>;
- def h : SystemZQuaternaryInt<name##"h", llvm_v8i16_ty>;
- def f : SystemZQuaternaryInt<name##"f", llvm_v4i32_ty>;
+ def b : SystemZQuaternaryInt<name#"b", llvm_v16i8_ty>;
+ def h : SystemZQuaternaryInt<name#"h", llvm_v8i16_ty>;
+ def f : SystemZQuaternaryInt<name#"f", llvm_v4i32_ty>;
}
multiclass SystemZQuaternaryIntBHFG<string name> :
SystemZQuaternaryIntBHF<name> {
- def g : SystemZQuaternaryInt<name##"g", llvm_v2i64_ty>;
+ def g : SystemZQuaternaryInt<name#"g", llvm_v2i64_ty>;
}
multiclass SystemZQuaternaryIntCCBHF {
@@ -238,11 +238,11 @@ let TargetPrefix = "s390" in {
let TargetPrefix = "s390" in {
def int_s390_lcbb : GCCBuiltin<"__builtin_s390_lcbb">,
Intrinsic<[llvm_i32_ty], [llvm_ptr_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_s390_vlbb : GCCBuiltin<"__builtin_s390_vlbb">,
Intrinsic<[llvm_v16i8_ty], [llvm_ptr_ty, llvm_i32_ty],
- [IntrReadMem, IntrArgMemOnly, ImmArg<1>]>;
+ [IntrReadMem, IntrArgMemOnly, ImmArg<ArgIndex<1>>]>;
def int_s390_vll : GCCBuiltin<"__builtin_s390_vll">,
Intrinsic<[llvm_v16i8_ty], [llvm_i32_ty, llvm_ptr_ty],
@@ -251,7 +251,7 @@ let TargetPrefix = "s390" in {
def int_s390_vpdi : GCCBuiltin<"__builtin_s390_vpdi">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vperm : GCCBuiltin<"__builtin_s390_vperm">,
Intrinsic<[llvm_v16i8_ty],
@@ -317,7 +317,7 @@ let TargetPrefix = "s390" in {
def int_s390_vsldb : GCCBuiltin<"__builtin_s390_vsldb">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
defm int_s390_vscbi : SystemZBinaryBHFG<"vscbi">;
@@ -376,7 +376,7 @@ let TargetPrefix = "s390" in {
def int_s390_vfidb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
// Instructions from the Vector Enhancements Facility 1
def int_s390_vbperm : SystemZBinaryConv<"vbperm", llvm_v2i64_ty,
@@ -385,20 +385,20 @@ let TargetPrefix = "s390" in {
def int_s390_vmslg : GCCBuiltin<"__builtin_s390_vmslg">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_v16i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_s390_vfmaxdb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vfmindb : Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vfmaxsb : Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vfminsb : Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vfcesbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>;
def int_s390_vfchsbs : SystemZBinaryConvCC<llvm_v4i32_ty, llvm_v4f32_ty>;
@@ -408,7 +408,7 @@ let TargetPrefix = "s390" in {
def int_s390_vfisb : Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
// Instructions from the Vector Packed Decimal Facility
def int_s390_vlrl : GCCBuiltin<"__builtin_s390_vlrl">,
@@ -423,12 +423,12 @@ let TargetPrefix = "s390" in {
def int_s390_vsld : GCCBuiltin<"__builtin_s390_vsld">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vsrd : GCCBuiltin<"__builtin_s390_vsrd">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_s390_vstrsb : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v16i8_ty>;
def int_s390_vstrsh : SystemZTernaryConvCC<llvm_v16i8_ty, llvm_v8i16_ty>;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index e97700ad724a..7c9ceb148a47 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -51,7 +51,7 @@ def int_wasm_trunc_saturate_unsigned : Intrinsic<[llvm_anyint_ty],
// throw / rethrow
def int_wasm_throw : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty],
- [Throws, IntrNoReturn, ImmArg<0>]>;
+ [Throws, IntrNoReturn, ImmArg<ArgIndex<0>>]>;
def int_wasm_rethrow_in_catch : Intrinsic<[], [], [Throws, IntrNoReturn]>;
// Since wasm does not use landingpad instructions, these instructions return
@@ -69,7 +69,7 @@ def int_wasm_extract_exception : Intrinsic<[llvm_ptr_ty], [],
// by WasmEHPrepare pass to generate landingpad table in EHStreamer. This is
// used in order to give them the indices in WasmEHPrepare.
def int_wasm_landingpad_index: Intrinsic<[], [llvm_token_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
// Returns LSDA address of the current function.
def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
@@ -82,18 +82,18 @@ def int_wasm_lsda : Intrinsic<[llvm_ptr_ty], [], [IntrNoMem]>;
def int_wasm_atomic_wait_i32 :
Intrinsic<[llvm_i32_ty],
[LLVMPointerType<llvm_i32_ty>, llvm_i32_ty, llvm_i64_ty],
- [IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0>,
+ [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
IntrHasSideEffects],
"", [SDNPMemOperand]>;
def int_wasm_atomic_wait_i64 :
Intrinsic<[llvm_i32_ty],
[LLVMPointerType<llvm_i64_ty>, llvm_i64_ty, llvm_i64_ty],
- [IntrInaccessibleMemOrArgMemOnly, ReadOnly<0>, NoCapture<0>,
+ [IntrInaccessibleMemOrArgMemOnly, ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>,
IntrHasSideEffects],
"", [SDNPMemOperand]>;
def int_wasm_atomic_notify:
Intrinsic<[llvm_i32_ty], [LLVMPointerType<llvm_i32_ty>, llvm_i32_ty],
- [IntrInaccessibleMemOnly, NoCapture<0>, IntrHasSideEffects], "",
+ [IntrInaccessibleMemOnly, NoCapture<ArgIndex<0>>, IntrHasSideEffects], "",
[SDNPMemOperand]>;
//===----------------------------------------------------------------------===//
@@ -104,6 +104,13 @@ def int_wasm_swizzle :
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem, IntrSpeculatable]>;
+def int_wasm_shuffle :
+ Intrinsic<[llvm_v16i8_ty],
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
def int_wasm_sub_saturate_signed :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
@@ -116,7 +123,6 @@ def int_wasm_avgr_unsigned :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>],
[IntrNoMem, IntrSpeculatable]>;
-
def int_wasm_bitselect :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
@@ -129,6 +135,10 @@ def int_wasm_alltrue :
Intrinsic<[llvm_i32_ty],
[llvm_anyvector_ty],
[IntrNoMem, IntrSpeculatable]>;
+def int_wasm_bitmask :
+ Intrinsic<[llvm_i32_ty],
+ [llvm_anyvector_ty],
+ [IntrNoMem, IntrSpeculatable]>;
def int_wasm_qfma :
Intrinsic<[llvm_anyvector_ty],
[LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>],
@@ -166,20 +176,35 @@ def int_wasm_widen_high_unsigned :
[llvm_anyvector_ty],
[IntrNoMem, IntrSpeculatable]>;
+// TODO: Replace these intrinsics with normal ISel patterns
+def int_wasm_pmin :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_pmax :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>, LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
-//===----------------------------------------------------------------------===//
-// Bulk memory intrinsics
-//===----------------------------------------------------------------------===//
-
-def int_wasm_memory_init :
- Intrinsic<[],
- [llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrWriteMem, IntrInaccessibleMemOrArgMemOnly, WriteOnly<2>,
- IntrHasSideEffects, ImmArg<0>, ImmArg<1>]>;
-def int_wasm_data_drop :
- Intrinsic<[],
- [llvm_i32_ty],
- [IntrNoDuplicate, IntrHasSideEffects, ImmArg<0>]>;
+// TODO: Replace these instrinsics with normal ISel patterns once the
+// rounding instructions are merged to the proposal
+// (https://github.com/WebAssembly/simd/pull/232).
+def int_wasm_ceil :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_floor :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_trunc :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_nearest :
+ Intrinsic<[llvm_anyvector_ty],
+ [LLVMMatchType<0>],
+ [IntrNoMem, IntrSpeculatable]>;
//===----------------------------------------------------------------------===//
// Thread-local storage intrinsics
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td
index 5796686dd79f..3f86fd075d3a 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsX86.td
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
// Interrupt traps
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_int : Intrinsic<[], [llvm_i8_ty], [ImmArg<0>]>;
+ def int_x86_int : Intrinsic<[], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
}
//===----------------------------------------------------------------------===//
@@ -203,12 +203,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse_cmp_ss : GCCBuiltin<"__builtin_ia32_cmpss">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
// NOTE: This comparison intrinsic is not used by clang as long as the
// distinction in signaling behaviour is not implemented.
def int_x86_sse_cmp_ps :
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse_comieq_ss : GCCBuiltin<"__builtin_ia32_comieq">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
llvm_v4f32_ty], [IntrNoMem]>;
@@ -284,7 +284,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse_ldmxcsr :
Intrinsic<[], [llvm_ptr_ty],
[IntrReadMem, IntrArgMemOnly, IntrHasSideEffects,
- // FIXME: LDMXCSR does not actualy write to memory,
+ // FIXME: LDMXCSR does not actually write to memory,
// but Fast and DAG Isel both use writing to memory
// as a proxy for having side effects.
IntrWriteMem]>;
@@ -319,12 +319,12 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse2_cmp_sd : GCCBuiltin<"__builtin_ia32_cmpsd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
// NOTE: This comparison intrinsic is not used by clang as long as the
// distinction in signaling behaviour is not implemented.
def int_x86_sse2_cmp_pd :
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse2_comieq_sd : GCCBuiltin<"__builtin_ia32_comisdeq">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
llvm_v2f64_ty], [IntrNoMem]>;
@@ -618,7 +618,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v16i8_ty], [IntrNoMem]>;
def int_x86_sse_pshuf_w : GCCBuiltin<"__builtin_ia32_pshufw">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
// Sign ops
@@ -664,16 +664,16 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_round_ss : GCCBuiltin<"__builtin_ia32_roundss">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse41_round_ps : GCCBuiltin<"__builtin_ia32_roundps">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_sse41_round_sd : GCCBuiltin<"__builtin_ia32_roundsd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse41_round_pd : GCCBuiltin<"__builtin_ia32_roundpd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
// Vector min element
@@ -736,20 +736,20 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_aesni_aeskeygenassist :
GCCBuiltin<"__builtin_ia32_aeskeygenassist128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
// PCLMUL instructions
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_pclmulqdq : GCCBuiltin<"__builtin_ia32_pclmulqdq128">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_pclmulqdq_256 : GCCBuiltin<"__builtin_ia32_pclmulqdq256">,
Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_pclmulqdq_512 : GCCBuiltin<"__builtin_ia32_pclmulqdq512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_v8i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Vector pack
@@ -763,7 +763,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_insertps : GCCBuiltin<"__builtin_ia32_insertps128">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Vector blend
@@ -783,17 +783,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_dppd : GCCBuiltin<"__builtin_ia32_dppd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem, Commutative, ImmArg<2>]>;
+ [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>]>;
def int_x86_sse41_dpps : GCCBuiltin<"__builtin_ia32_dpps">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, Commutative, ImmArg<2>]>;
+ [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>]>;
}
// Vector sum of absolute differences
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw128">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_i8_ty],
- [IntrNoMem, Commutative, ImmArg<2>]>;
+ [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>]>;
}
// Test instruction with bitwise comparison.
@@ -834,66 +834,66 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse42_pcmpistrm128 : GCCBuiltin<"__builtin_ia32_pcmpistrm128">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistri128 : GCCBuiltin<"__builtin_ia32_pcmpistri128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistria128 : GCCBuiltin<"__builtin_ia32_pcmpistria128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistric128 : GCCBuiltin<"__builtin_ia32_pcmpistric128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistrio128 : GCCBuiltin<"__builtin_ia32_pcmpistrio128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistris128 : GCCBuiltin<"__builtin_ia32_pcmpistris128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpistriz128 : GCCBuiltin<"__builtin_ia32_pcmpistriz128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sse42_pcmpestrm128 : GCCBuiltin<"__builtin_ia32_pcmpestrm128">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestri128 : GCCBuiltin<"__builtin_ia32_pcmpestri128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestria128 : GCCBuiltin<"__builtin_ia32_pcmpestria128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestric128 : GCCBuiltin<"__builtin_ia32_pcmpestric128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestrio128 : GCCBuiltin<"__builtin_ia32_pcmpestrio128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestris128 : GCCBuiltin<"__builtin_ia32_pcmpestris128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_sse42_pcmpestriz128 : GCCBuiltin<"__builtin_ia32_pcmpestriz128">,
Intrinsic<[llvm_i32_ty],
[llvm_v16i8_ty, llvm_i32_ty, llvm_v16i8_ty, llvm_i32_ty,
llvm_i8_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
}
//===----------------------------------------------------------------------===//
@@ -902,14 +902,14 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse4a_extrqi : GCCBuiltin<"__builtin_ia32_extrqi">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<2>>]>;
def int_x86_sse4a_extrq : GCCBuiltin<"__builtin_ia32_extrq">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v16i8_ty], [IntrNoMem]>;
def int_x86_sse4a_insertqi : GCCBuiltin<"__builtin_ia32_insertqi">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty,
llvm_i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
def int_x86_sse4a_insertq : GCCBuiltin<"__builtin_ia32_insertq">,
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty], [IntrNoMem]>;
}
@@ -946,10 +946,10 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_round_pd_256 : GCCBuiltin<"__builtin_ia32_roundpd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx_round_ps_256 : GCCBuiltin<"__builtin_ia32_roundps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<1>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
// Horizontal ops
@@ -1101,33 +1101,33 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v16qi">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8affineinvqb_256 :
GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v32qi">,
Intrinsic<[llvm_v32i8_ty],
[llvm_v32i8_ty, llvm_v32i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8affineinvqb_512 :
GCCBuiltin<"__builtin_ia32_vgf2p8affineinvqb_v64qi">,
Intrinsic<[llvm_v64i8_ty],
[llvm_v64i8_ty, llvm_v64i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8affineqb_128 :
GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v16qi">,
Intrinsic<[llvm_v16i8_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8affineqb_256 :
GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v32qi">,
Intrinsic<[llvm_v32i8_ty],
[llvm_v32i8_ty, llvm_v32i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8affineqb_512 :
GCCBuiltin<"__builtin_ia32_vgf2p8affineqb_v64qi">,
Intrinsic<[llvm_v64i8_ty],
[llvm_v64i8_ty, llvm_v64i8_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_vgf2p8mulb_128 :
GCCBuiltin<"__builtin_ia32_vgf2p8mulb_v16qi">,
@@ -1161,17 +1161,17 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_dp_ps_256 : GCCBuiltin<"__builtin_ia32_dpps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem, Commutative, ImmArg<2>]>;
+ [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>]>;
}
// Vector compare
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_cmp_pd_256 :
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx_cmp_ps_256 :
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Vector convert
@@ -1238,30 +1238,30 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_fpclass_pd_128 :
Intrinsic<[llvm_v2i1_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_fpclass_pd_256 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_fpclass_pd_512 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_fpclass_ps_128 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_fpclass_ps_256 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_fpclass_ps_512 :
Intrinsic<[llvm_v16i1_ty], [llvm_v16f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_fpclass_sd :
GCCBuiltin<"__builtin_ia32_fpclasssd_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_fpclass_ss :
GCCBuiltin<"__builtin_ia32_fpclassss_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
// Vector extract sign mask
@@ -1275,9 +1275,9 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector zero
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_vzeroall : GCCBuiltin<"__builtin_ia32_vzeroall">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects]>;
def int_x86_avx_vzeroupper : GCCBuiltin<"__builtin_ia32_vzeroupper">,
- Intrinsic<[], [], []>;
+ Intrinsic<[], [], [IntrNoMem, IntrHasSideEffects]>;
}
// SIMD load ops
@@ -1707,68 +1707,68 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_gather_d_pd : GCCBuiltin<"__builtin_ia32_gatherd_pd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_pd_256 : GCCBuiltin<"__builtin_ia32_gatherd_pd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_pd : GCCBuiltin<"__builtin_ia32_gatherq_pd">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_pd_256 : GCCBuiltin<"__builtin_ia32_gatherq_pd256">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_ps : GCCBuiltin<"__builtin_ia32_gatherd_ps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_ps_256 : GCCBuiltin<"__builtin_ia32_gatherd_ps256">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_ps : GCCBuiltin<"__builtin_ia32_gatherq_ps">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_ps_256 : GCCBuiltin<"__builtin_ia32_gatherq_ps256">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_q : GCCBuiltin<"__builtin_ia32_gatherd_q">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_q_256 : GCCBuiltin<"__builtin_ia32_gatherd_q256">,
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_q : GCCBuiltin<"__builtin_ia32_gatherq_q">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_q_256 : GCCBuiltin<"__builtin_ia32_gatherq_q256">,
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_d : GCCBuiltin<"__builtin_ia32_gatherd_d">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_d_d_256 : GCCBuiltin<"__builtin_ia32_gatherd_d256">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_d : GCCBuiltin<"__builtin_ia32_gatherq_d">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx2_gather_q_d_256 : GCCBuiltin<"__builtin_ia32_gatherq_d256">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
}
// Misc.
@@ -1780,42 +1780,60 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v32i8_ty], [IntrNoMem]>;
def int_x86_avx2_mpsadbw : GCCBuiltin<"__builtin_ia32_mpsadbw256">,
Intrinsic<[llvm_v16i16_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
- llvm_i8_ty], [IntrNoMem, Commutative, ImmArg<2>]>;
+ llvm_i8_ty], [IntrNoMem, Commutative, ImmArg<ArgIndex<2>>]>;
}
//===----------------------------------------------------------------------===//
// FMA3 and FMA4
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_fma_vfmaddsub_ps : GCCBuiltin<"__builtin_ia32_vfmaddsubps">,
+ Intrinsic<[llvm_v4f32_ty],
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma_vfmaddsub_pd : GCCBuiltin<"__builtin_ia32_vfmaddsubpd">,
+ Intrinsic<[llvm_v2f64_ty],
+ [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_fma_vfmaddsub_ps_256 :
+ GCCBuiltin<"__builtin_ia32_vfmaddsubps256">,
+ Intrinsic<[llvm_v8f32_ty],
+ [llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8f32_ty],
+ [IntrNoMem]>;
+ def int_x86_fma_vfmaddsub_pd_256 :
+ GCCBuiltin<"__builtin_ia32_vfmaddsubpd256">,
+ Intrinsic<[llvm_v4f64_ty],
+ [llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4f64_ty],
+ [IntrNoMem]>;
+
def int_x86_avx512_vfmadd_pd_512 :
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vfmadd_ps_512 :
Intrinsic<[llvm_v16f32_ty],
[llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
- // TODO: Can we use 2 vfmadds+shufflevector?
def int_x86_avx512_vfmaddsub_pd_512 :
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vfmaddsub_ps_512 :
Intrinsic<[llvm_v16f32_ty],
[llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vfmadd_f64 :
Intrinsic<[llvm_double_ty],
[llvm_double_ty, llvm_double_ty, llvm_double_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vfmadd_f32 :
Intrinsic<[llvm_float_ty],
[llvm_float_ty, llvm_float_ty, llvm_float_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vpmadd52h_uq_128 :
GCCBuiltin<"__builtin_ia32_vpmadd52huq128">,
@@ -1905,23 +1923,23 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_xop_vpermil2pd : GCCBuiltin<"__builtin_ia32_vpermil2pd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_v2i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_xop_vpermil2pd_256 :
GCCBuiltin<"__builtin_ia32_vpermil2pd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
llvm_v4i64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_xop_vpermil2ps : GCCBuiltin<"__builtin_ia32_vpermil2ps">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_v4i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_xop_vpermil2ps_256 :
GCCBuiltin<"__builtin_ia32_vpermil2ps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
llvm_v8i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_xop_vfrcz_pd : GCCBuiltin<"__builtin_ia32_vfrczpd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty], [IntrNoMem]>;
@@ -2092,19 +2110,19 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_lwpins32 :
GCCBuiltin<"__builtin_ia32_lwpins32">,
Intrinsic<[llvm_i8_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [ImmArg<2>]>;
+ [ImmArg<ArgIndex<2>>]>;
def int_x86_lwpins64 :
GCCBuiltin<"__builtin_ia32_lwpins64">,
Intrinsic<[llvm_i8_ty], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
- [ImmArg<2>]>;
+ [ImmArg<ArgIndex<2>>]>;
def int_x86_lwpval32 :
GCCBuiltin<"__builtin_ia32_lwpval32">,
Intrinsic<[], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
- [ImmArg<2>]>;
+ [ImmArg<ArgIndex<2>>]>;
def int_x86_lwpval64 :
GCCBuiltin<"__builtin_ia32_lwpval64">,
Intrinsic<[], [llvm_i64_ty, llvm_i32_ty, llvm_i32_ty],
- [ImmArg<2>]>;
+ [ImmArg<ArgIndex<2>>]>;
}
//===----------------------------------------------------------------------===//
@@ -2405,15 +2423,15 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_mmx_palignr_b : GCCBuiltin<"__builtin_ia32_palignr">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
- llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_x86mmx_ty, llvm_i8_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_mmx_pextr_w : GCCBuiltin<"__builtin_ia32_vec_ext_v4hi">,
Intrinsic<[llvm_i32_ty], [llvm_x86mmx_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_mmx_pinsr_w : GCCBuiltin<"__builtin_ia32_vec_set_v4hi">,
Intrinsic<[llvm_x86mmx_ty], [llvm_x86mmx_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
//===----------------------------------------------------------------------===//
@@ -2528,38 +2546,28 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Half float conversion
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_vcvtph2ps_128 : GCCBuiltin<"__builtin_ia32_vcvtph2ps">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
- def int_x86_vcvtph2ps_256 : GCCBuiltin<"__builtin_ia32_vcvtph2ps256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty], [IntrNoMem]>;
def int_x86_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
- def int_x86_avx512_mask_vcvtph2ps_512 : GCCBuiltin<"__builtin_ia32_vcvtph2ps512_mask">,
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
+ def int_x86_avx512_mask_vcvtph2ps_512 :
Intrinsic<[llvm_v16f32_ty], [llvm_v16i16_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
- def int_x86_avx512_mask_vcvtph2ps_256 : GCCBuiltin<"__builtin_ia32_vcvtph2ps256_mask">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8i16_ty, llvm_v8f32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx512_mask_vcvtph2ps_128 : GCCBuiltin<"__builtin_ia32_vcvtph2ps_mask">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v8i16_ty, llvm_v4f32_ty,
- llvm_i8_ty], [IntrNoMem]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_vcvtps2ph_512 : GCCBuiltin<"__builtin_ia32_vcvtps2ph512_mask">,
Intrinsic<[llvm_v16i16_ty], [llvm_v16f32_ty, llvm_i32_ty,
llvm_v16i16_ty, llvm_i16_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_vcvtps2ph_256 : GCCBuiltin<"__builtin_ia32_vcvtps2ph256_mask">,
Intrinsic<[llvm_v8i16_ty], [llvm_v8f32_ty, llvm_i32_ty,
llvm_v8i16_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_vcvtps2ph_128 : GCCBuiltin<"__builtin_ia32_vcvtps2ph_mask">,
Intrinsic<[llvm_v8i16_ty], [llvm_v4f32_ty, llvm_i32_ty,
llvm_v8i16_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
//===----------------------------------------------------------------------===//
@@ -2568,10 +2576,10 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_tbm_bextri_u32 : GCCBuiltin<"__builtin_ia32_bextri_u32">,
Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_tbm_bextri_u64 : GCCBuiltin<"__builtin_ia32_bextri_u64">,
Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
}
//===----------------------------------------------------------------------===//
@@ -2617,7 +2625,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_xend : GCCBuiltin<"__builtin_ia32_xend">,
Intrinsic<[], [], []>;
def int_x86_xabort : GCCBuiltin<"__builtin_ia32_xabort">,
- Intrinsic<[], [llvm_i8_ty], [ImmArg<0>]>;
+ Intrinsic<[], [llvm_i8_ty], [ImmArg<ArgIndex<0>>]>;
def int_x86_xtest : GCCBuiltin<"__builtin_ia32_xtest">,
Intrinsic<[llvm_i32_ty], [], []>;
}
@@ -2659,70 +2667,70 @@ let TargetPrefix = "x86" in {
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_cvttss2si : GCCBuiltin<"__builtin_ia32_vcvttss2si32">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttss2si64 : GCCBuiltin<"__builtin_ia32_vcvttss2si64">,
Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttss2usi : GCCBuiltin<"__builtin_ia32_vcvttss2usi32">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttss2usi64 : GCCBuiltin<"__builtin_ia32_vcvttss2usi64">,
Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvtusi2ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss32">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cvtusi642ss : GCCBuiltin<"__builtin_ia32_cvtusi2ss64">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cvttsd2si : GCCBuiltin<"__builtin_ia32_vcvttsd2si32">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttsd2si64 : GCCBuiltin<"__builtin_ia32_vcvttsd2si64">,
Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttsd2usi : GCCBuiltin<"__builtin_ia32_vcvttsd2usi32">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvttsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvttsd2usi64">,
Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvtusi642sd : GCCBuiltin<"__builtin_ia32_cvtusi2sd64">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
- llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_vcvtss2usi32 : GCCBuiltin<"__builtin_ia32_vcvtss2usi32">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtss2usi64 : GCCBuiltin<"__builtin_ia32_vcvtss2usi64">,
Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtss2si32 : GCCBuiltin<"__builtin_ia32_vcvtss2si32">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtss2si64 : GCCBuiltin<"__builtin_ia32_vcvtss2si64">,
Intrinsic<[llvm_i64_ty], [llvm_v4f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtsd2usi32 : GCCBuiltin<"__builtin_ia32_vcvtsd2usi32">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtsd2usi64 : GCCBuiltin<"__builtin_ia32_vcvtsd2usi64">,
Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtsd2si32 : GCCBuiltin<"__builtin_ia32_vcvtsd2si32">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_vcvtsd2si64 : GCCBuiltin<"__builtin_ia32_vcvtsd2si64">,
Intrinsic<[llvm_i64_ty], [llvm_v2f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_cvtsi2ss32 : GCCBuiltin<"__builtin_ia32_cvtsi2ss32">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cvtsi2ss64 : GCCBuiltin<"__builtin_ia32_cvtsi2ss64">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty,
- llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cvtsi2sd64 : GCCBuiltin<"__builtin_ia32_cvtsi2sd64">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty,
- llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i64_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Pack ops.
@@ -2745,11 +2753,11 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_sitofp_round :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_uitofp_round :
Intrinsic<[llvm_anyfloat_ty], [llvm_anyint_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_cvtpd2dq_128 :
GCCBuiltin<"__builtin_ia32_cvtpd2dq128_mask">,
@@ -2761,25 +2769,25 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtpd2dq512_mask">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtpd2ps_512 :
GCCBuiltin<"__builtin_ia32_cvtpd2ps512_mask">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f64_ty, llvm_v8f32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtsd2ss_round :
GCCBuiltin<"__builtin_ia32_cvtsd2ss_round_mask">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v2f64_ty, llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_cvtss2sd_round :
GCCBuiltin<"__builtin_ia32_cvtss2sd_round_mask">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v4f32_ty, llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_cvtpd2ps :
GCCBuiltin<"__builtin_ia32_cvtpd2ps_mask">,
@@ -2803,7 +2811,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtpd2qq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtpd2udq_128 :
GCCBuiltin<"__builtin_ia32_cvtpd2udq128_mask">,
@@ -2821,7 +2829,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtpd2udq512_mask">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtpd2uqq_128 :
GCCBuiltin<"__builtin_ia32_cvtpd2uqq128_mask">,
@@ -2839,7 +2847,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtpd2uqq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtps2dq_128 :
GCCBuiltin<"__builtin_ia32_cvtps2dq128_mask">,
@@ -2857,13 +2865,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtps2dq512_mask">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtps2pd_512 :
GCCBuiltin<"__builtin_ia32_cvtps2pd512_mask">,
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f32_ty, llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtps2qq_128 :
GCCBuiltin<"__builtin_ia32_cvtps2qq128_mask">,
@@ -2881,7 +2889,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtps2qq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtps2udq_128 :
GCCBuiltin<"__builtin_ia32_cvtps2udq128_mask">,
@@ -2899,7 +2907,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtps2udq512_mask">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtps2uqq_128 :
GCCBuiltin<"__builtin_ia32_cvtps2uqq128_mask">,
@@ -2917,7 +2925,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvtps2uqq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtqq2ps_128 :
GCCBuiltin<"__builtin_ia32_cvtqq2ps128_mask">,
@@ -2935,7 +2943,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttpd2dq512_mask">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttpd2qq_128 :
GCCBuiltin<"__builtin_ia32_cvttpd2qq128_mask">,
@@ -2953,7 +2961,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttpd2qq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttpd2udq_128 :
GCCBuiltin<"__builtin_ia32_cvttpd2udq128_mask">,
@@ -2971,7 +2979,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttpd2udq512_mask">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8f64_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttpd2uqq_128 :
GCCBuiltin<"__builtin_ia32_cvttpd2uqq128_mask">,
@@ -2989,13 +2997,13 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttpd2uqq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f64_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttps2dq_512 :
GCCBuiltin<"__builtin_ia32_cvttps2dq512_mask">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttps2qq_128 :
GCCBuiltin<"__builtin_ia32_cvttps2qq128_mask">,
@@ -3013,7 +3021,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttps2qq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttps2udq_128 :
GCCBuiltin<"__builtin_ia32_cvttps2udq128_mask">,
@@ -3031,7 +3039,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttps2udq512_mask">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16f32_ty, llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvttps2uqq_128 :
GCCBuiltin<"__builtin_ia32_cvttps2uqq128_mask">,
@@ -3049,7 +3057,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
GCCBuiltin<"__builtin_ia32_cvttps2uqq512_mask">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8f32_ty, llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_cvtuqq2ps_128 :
GCCBuiltin<"__builtin_ia32_cvtuqq2ps128_mask">,
@@ -3060,75 +3068,75 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_rndscale_pd_128 : GCCBuiltin<"__builtin_ia32_rndscalepd_128_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty,
llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_rndscale_pd_256 : GCCBuiltin<"__builtin_ia32_rndscalepd_256_mask">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty,
llvm_v4f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_rndscale_pd_512 : GCCBuiltin<"__builtin_ia32_rndscalepd_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_rndscale_ps_128 : GCCBuiltin<"__builtin_ia32_rndscaleps_128_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty,
llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_rndscale_ps_256 : GCCBuiltin<"__builtin_ia32_rndscaleps_256_mask">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty,
llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_rndscale_ps_512 : GCCBuiltin<"__builtin_ia32_rndscaleps_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_reduce_pd_128 : GCCBuiltin<"__builtin_ia32_reducepd128_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i32_ty,
llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_reduce_pd_256 : GCCBuiltin<"__builtin_ia32_reducepd256_mask">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i32_ty,
llvm_v4f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_reduce_pd_512 : GCCBuiltin<"__builtin_ia32_reducepd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_reduce_ps_128 : GCCBuiltin<"__builtin_ia32_reduceps128_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i32_ty,
llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_reduce_ps_256 : GCCBuiltin<"__builtin_ia32_reduceps256_mask">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i32_ty,
llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_reduce_ps_512 : GCCBuiltin<"__builtin_ia32_reduceps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_range_pd_128 : GCCBuiltin<"__builtin_ia32_rangepd128_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty,
llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_range_pd_256 : GCCBuiltin<"__builtin_ia32_rangepd256_mask">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_v4f64_ty, llvm_i32_ty,
llvm_v4f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_range_pd_512 : GCCBuiltin<"__builtin_ia32_rangepd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty, llvm_i32_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_range_ps_128 : GCCBuiltin<"__builtin_ia32_rangeps128_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty,
llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_range_ps_256 : GCCBuiltin<"__builtin_ia32_rangeps256_mask">,
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_v8f32_ty, llvm_i32_ty,
llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_range_ps_512 : GCCBuiltin<"__builtin_ia32_rangeps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty, llvm_i32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<5>>]>;
}
// Vector load with broadcast
@@ -3158,111 +3166,111 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_add_ps_512 : GCCBuiltin<"__builtin_ia32_addps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_add_pd_512 : GCCBuiltin<"__builtin_ia32_addpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_sub_ps_512 : GCCBuiltin<"__builtin_ia32_subps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_sub_pd_512 : GCCBuiltin<"__builtin_ia32_subpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mul_ps_512 : GCCBuiltin<"__builtin_ia32_mulps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mul_pd_512 : GCCBuiltin<"__builtin_ia32_mulpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_div_ps_512 : GCCBuiltin<"__builtin_ia32_divps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_div_pd_512 : GCCBuiltin<"__builtin_ia32_divpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_max_ps_512 : GCCBuiltin<"__builtin_ia32_maxps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_max_pd_512 : GCCBuiltin<"__builtin_ia32_maxpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_min_ps_512 : GCCBuiltin<"__builtin_ia32_minps512">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_min_pd_512 : GCCBuiltin<"__builtin_ia32_minpd512">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_add_ss_round : GCCBuiltin<"__builtin_ia32_addss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_div_ss_round : GCCBuiltin<"__builtin_ia32_divss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_mul_ss_round : GCCBuiltin<"__builtin_ia32_mulss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_sub_ss_round : GCCBuiltin<"__builtin_ia32_subss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_max_ss_round : GCCBuiltin<"__builtin_ia32_maxss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_min_ss_round : GCCBuiltin<"__builtin_ia32_minss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_add_sd_round : GCCBuiltin<"__builtin_ia32_addsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_div_sd_round : GCCBuiltin<"__builtin_ia32_divsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_mul_sd_round : GCCBuiltin<"__builtin_ia32_mulsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_sub_sd_round : GCCBuiltin<"__builtin_ia32_subsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_max_sd_round : GCCBuiltin<"__builtin_ia32_maxsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_min_sd_round : GCCBuiltin<"__builtin_ia32_minsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<4>]>;
+ llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_rndscale_ss : GCCBuiltin<"__builtin_ia32_rndscaless_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_rndscale_sd : GCCBuiltin<"__builtin_ia32_rndscalesd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_range_ss : GCCBuiltin<"__builtin_ia32_rangess128_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_range_sd : GCCBuiltin<"__builtin_ia32_rangesd128_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_reduce_ss : GCCBuiltin<"__builtin_ia32_reducess_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_reduce_sd : GCCBuiltin<"__builtin_ia32_reducesd_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>, ImmArg<5>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_scalef_sd : GCCBuiltin<"__builtin_ia32_scalefsd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scalef_ss : GCCBuiltin<"__builtin_ia32_scalefss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scalef_pd_128 : GCCBuiltin<"__builtin_ia32_scalefpd128_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
@@ -3272,7 +3280,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_scalef_pd_512 : GCCBuiltin<"__builtin_ia32_scalefpd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_v8f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scalef_ps_128 : GCCBuiltin<"__builtin_ia32_scalefps128_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
@@ -3282,103 +3290,103 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_scalef_ps_512 : GCCBuiltin<"__builtin_ia32_scalefps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_v16f32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_sqrt_ss :
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_sqrt_sd :
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_sqrt_pd_512 :
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_sqrt_ps_512 :
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_fixupimm_pd_128 :
GCCBuiltin<"__builtin_ia32_fixupimmpd128_mask">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_maskz_fixupimm_pd_128 :
GCCBuiltin<"__builtin_ia32_fixupimmpd128_maskz">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_fixupimm_pd_256 :
GCCBuiltin<"__builtin_ia32_fixupimmpd256_mask">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_maskz_fixupimm_pd_256 :
GCCBuiltin<"__builtin_ia32_fixupimmpd256_maskz">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_v4f64_ty, llvm_v4i64_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_fixupimm_pd_512 :
GCCBuiltin<"__builtin_ia32_fixupimmpd512_mask">,
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_maskz_fixupimm_pd_512 :
GCCBuiltin<"__builtin_ia32_fixupimmpd512_maskz">,
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f64_ty, llvm_v8f64_ty, llvm_v8i64_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_fixupimm_ps_128 :
GCCBuiltin<"__builtin_ia32_fixupimmps128_mask">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_maskz_fixupimm_ps_128 :
GCCBuiltin<"__builtin_ia32_fixupimmps128_maskz">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_fixupimm_ps_256 :
GCCBuiltin<"__builtin_ia32_fixupimmps256_mask">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_maskz_fixupimm_ps_256 :
GCCBuiltin<"__builtin_ia32_fixupimmps256_maskz">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_v8f32_ty, llvm_v8i32_ty, llvm_i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_fixupimm_ps_512 :
GCCBuiltin<"__builtin_ia32_fixupimmps512_mask">,
Intrinsic<[llvm_v16f32_ty],
[llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16i32_ty, llvm_i32_ty,
- llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_maskz_fixupimm_ps_512 :
GCCBuiltin<"__builtin_ia32_fixupimmps512_maskz">,
Intrinsic<[llvm_v16f32_ty],
[llvm_v16f32_ty, llvm_v16f32_ty, llvm_v16i32_ty, llvm_i32_ty,
- llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_fixupimm_sd :
GCCBuiltin<"__builtin_ia32_fixupimmsd_mask">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_maskz_fixupimm_sd :
GCCBuiltin<"__builtin_ia32_fixupimmsd_maskz">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2i64_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_fixupimm_ss :
GCCBuiltin<"__builtin_ia32_fixupimmss_mask">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_maskz_fixupimm_ss :
GCCBuiltin<"__builtin_ia32_fixupimmss_maskz">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty, llvm_i8_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>, ImmArg<5>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_getexp_pd_128 : GCCBuiltin<"__builtin_ia32_getexppd128_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty], [IntrNoMem]>;
@@ -3388,7 +3396,7 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_getexp_pd_512 : GCCBuiltin<"__builtin_ia32_getexppd512_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_getexp_ps_128 : GCCBuiltin<"__builtin_ia32_getexpps128_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty], [IntrNoMem]>;
@@ -3398,64 +3406,64 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_mask_getexp_ps_512 : GCCBuiltin<"__builtin_ia32_getexpps512_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_mask_getexp_ss : GCCBuiltin<"__builtin_ia32_getexpss128_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_getexp_sd : GCCBuiltin<"__builtin_ia32_getexpsd128_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_getmant_pd_128 :
GCCBuiltin<"__builtin_ia32_getmantpd128_mask">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty,llvm_i32_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_getmant_pd_256 :
GCCBuiltin<"__builtin_ia32_getmantpd256_mask">,
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty,llvm_i32_ty, llvm_v4f64_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_getmant_pd_512 :
GCCBuiltin<"__builtin_ia32_getmantpd512_mask">,
Intrinsic<[llvm_v8f64_ty],
[llvm_v8f64_ty,llvm_i32_ty, llvm_v8f64_ty, llvm_i8_ty,llvm_i32_ty ],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_getmant_ps_128 :
GCCBuiltin<"__builtin_ia32_getmantps128_mask">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_getmant_ps_256 :
GCCBuiltin<"__builtin_ia32_getmantps256_mask">,
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_i32_ty, llvm_v8f32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<1>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>]>;
def int_x86_avx512_mask_getmant_ps_512 :
GCCBuiltin<"__builtin_ia32_getmantps512_mask">,
Intrinsic<[llvm_v16f32_ty],
[llvm_v16f32_ty,llvm_i32_ty, llvm_v16f32_ty,llvm_i16_ty,llvm_i32_ty],
- [IntrNoMem, ImmArg<1>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<1>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_getmant_ss :
GCCBuiltin<"__builtin_ia32_getmantss_round_mask">,
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_v4f32_ty, llvm_i32_ty, llvm_v4f32_ty,
- llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>, ImmArg<5>]>;
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_mask_getmant_sd :
GCCBuiltin<"__builtin_ia32_getmantsd_round_mask">,
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_v2f64_ty, llvm_i32_ty, llvm_v2f64_ty,
- llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<2>, ImmArg<5>]>;
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<5>>]>;
def int_x86_avx512_rsqrt14_ss : GCCBuiltin<"__builtin_ia32_rsqrt14ss_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty,
@@ -3510,41 +3518,41 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx512_rcp28_ps : GCCBuiltin<"__builtin_ia32_rcp28ps_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_rcp28_pd : GCCBuiltin<"__builtin_ia32_rcp28pd_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_exp2_ps : GCCBuiltin<"__builtin_ia32_exp2ps_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
- llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i16_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_exp2_pd : GCCBuiltin<"__builtin_ia32_exp2pd_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
- llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i8_ty, llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_rcp28_ss : GCCBuiltin<"__builtin_ia32_rcp28ss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_rcp28_sd : GCCBuiltin<"__builtin_ia32_rcp28sd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_rsqrt28_ps : GCCBuiltin<"__builtin_ia32_rsqrt28ps_mask">,
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_i16_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_rsqrt28_pd : GCCBuiltin<"__builtin_ia32_rsqrt28pd_mask">,
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_rsqrt28_ss : GCCBuiltin<"__builtin_ia32_rsqrt28ss_round_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_v4f32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_rsqrt28_sd : GCCBuiltin<"__builtin_ia32_rsqrt28sd_round_mask">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_v2f64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_psad_bw_512 : GCCBuiltin<"__builtin_ia32_psadbw512">,
Intrinsic<[llvm_v8i64_ty], [llvm_v64i8_ty, llvm_v64i8_ty],
[IntrNoMem, Commutative]>;
@@ -3574,19 +3582,19 @@ let TargetPrefix = "x86" in {
GCCBuiltin<"__builtin_ia32_dbpsadbw128">,
Intrinsic<[llvm_v8i16_ty],
[llvm_v16i8_ty, llvm_v16i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_dbpsadbw_256 :
GCCBuiltin<"__builtin_ia32_dbpsadbw256">,
Intrinsic<[llvm_v16i16_ty],
[llvm_v32i8_ty, llvm_v32i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_dbpsadbw_512 :
GCCBuiltin<"__builtin_ia32_dbpsadbw512">,
Intrinsic<[llvm_v32i16_ty],
[llvm_v64i8_ty, llvm_v64i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
}
// Gather and Scatter ops
@@ -3597,117 +3605,117 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_gather_dpd_512 :
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_dps_512 :
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty,
llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_qpd_512 :
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_qps_512 :
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_dpq_512 :
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_dpi_512 :
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty,
llvm_v16i32_ty, llvm_i16_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_qpq_512 :
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather_qpi_512 :
Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div2_df :
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div2_di :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div4_df :
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div4_di :
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div4_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div4_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div8_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3div8_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv2_df :
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv2_di :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv4_df :
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv4_di :
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv4_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv4_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv8_sf :
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gather3siv8_si :
Intrinsic<[llvm_v8i32_ty],
[llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
// scatter
// NOTE: These are deprecated in favor of the versions that take a vXi1 mask.
@@ -3716,149 +3724,149 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_scatter_dpd_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_dps_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty,
llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_qpd_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_qps_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_dpq_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,
llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_dpi_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i16_ty,
llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_qpq_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty,llvm_v8i64_ty, llvm_v8i64_ty,
llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatter_qpi_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_i8_ty, llvm_v8i64_ty, llvm_v8i32_ty,
llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv2_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv2_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv4_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv4_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv4_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv4_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv8_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterdiv8_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv2_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv2_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv4_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv4_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv4_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv4_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv8_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scattersiv8_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_i8_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
// gather prefetch
// NOTE: These can't be ArgMemOnly because you can put the address completely
// in the index register.
def int_x86_avx512_gatherpf_dpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfdpd">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gatherpf_dps_512 : GCCBuiltin<"__builtin_ia32_gatherpfdps">,
Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gatherpf_qpd_512 : GCCBuiltin<"__builtin_ia32_gatherpfqpd">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_gatherpf_qps_512 : GCCBuiltin<"__builtin_ia32_gatherpfqps">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
// scatter prefetch
// NOTE: These can't be ArgMemOnly because you can put the address completely
// in the index register.
def int_x86_avx512_scatterpf_dpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfdpd">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i32_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterpf_dps_512 : GCCBuiltin<"__builtin_ia32_scatterpfdps">,
Intrinsic<[], [llvm_i16_ty, llvm_v16i32_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterpf_qpd_512 : GCCBuiltin<"__builtin_ia32_scatterpfqpd">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_scatterpf_qps_512 : GCCBuiltin<"__builtin_ia32_scatterpfqps">,
Intrinsic<[], [llvm_i8_ty, llvm_v8i64_ty, llvm_ptr_ty,
- llvm_i32_ty, llvm_i32_ty], [ImmArg<3>, ImmArg<4>]>;
+ llvm_i32_ty, llvm_i32_ty], [ImmArg<ArgIndex<3>>, ImmArg<ArgIndex<4>>]>;
}
// AVX512 gather/scatter intrinsics that use vXi1 masks.
@@ -3868,134 +3876,134 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_mask_gather_dpd_512 :
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_dps_512 :
Intrinsic<[llvm_v16f32_ty], [llvm_v16f32_ty, llvm_ptr_ty,
llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_qpd_512 :
Intrinsic<[llvm_v8f64_ty], [llvm_v8f64_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_qps_512 :
Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_dpq_512 :
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_dpi_512 :
Intrinsic<[llvm_v16i32_ty], [llvm_v16i32_ty, llvm_ptr_ty,
llvm_v16i32_ty, llvm_v16i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_qpq_512 :
Intrinsic<[llvm_v8i64_ty], [llvm_v8i64_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather_qpi_512 :
Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_ptr_ty,
llvm_v8i64_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div2_df :
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div2_di :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div4_df :
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div4_di :
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div4_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div4_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v2i64_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div8_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3div8_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i64_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv2_df :
Intrinsic<[llvm_v2f64_ty],
[llvm_v2f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv2_di :
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v2i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv4_df :
Intrinsic<[llvm_v4f64_ty],
[llvm_v4f64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv4_di :
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv4_sf :
Intrinsic<[llvm_v4f32_ty],
[llvm_v4f32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv4_si :
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_ptr_ty, llvm_v4i32_ty, llvm_v4i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv8_sf :
Intrinsic<[llvm_v8f32_ty],
[llvm_v8f32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_gather3siv8_si :
Intrinsic<[llvm_v8i32_ty],
[llvm_v8i32_ty, llvm_ptr_ty, llvm_v8i32_ty, llvm_v8i1_ty, llvm_i32_ty],
- [IntrReadMem, ImmArg<4>]>;
+ [IntrReadMem, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_dpd_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,
llvm_v8i32_ty, llvm_v8f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_dps_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty,
llvm_v16i32_ty, llvm_v16f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_qpd_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,
llvm_v8i64_ty, llvm_v8f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_qps_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,
llvm_v8i64_ty, llvm_v8f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
// NOTE: These can't be ArgMemOnly because you can put the address completely
@@ -4003,99 +4011,99 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_mask_scatter_dpq_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,
llvm_v8i32_ty, llvm_v8i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_dpi_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v16i1_ty,
llvm_v16i32_ty, llvm_v16i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_qpq_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty,llvm_v8i64_ty, llvm_v8i64_ty,
llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatter_qpi_512 :
Intrinsic<[], [llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i64_ty, llvm_v8i32_ty,
llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv2_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv2_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv4_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv4_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv4_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv4_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v2i64_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv8_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scatterdiv8_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i64_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv2_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv2_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_v2i1_ty, llvm_v4i32_ty, llvm_v2i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv4_df :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv4_di :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i64_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv4_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv4_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_v4i1_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv8_sf :
Intrinsic<[],
[llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8f32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_scattersiv8_si :
Intrinsic<[],
[llvm_ptr_ty, llvm_v8i1_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty],
- [ImmArg<4>]>;
+ [ImmArg<ArgIndex<4>>]>;
}
// AVX-512 conflict detection instruction
@@ -4128,11 +4136,11 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_vcomi_sd : GCCBuiltin<"__builtin_ia32_vcomisd">,
Intrinsic<[llvm_i32_ty], [llvm_v2f64_ty,
llvm_v2f64_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_vcomi_ss : GCCBuiltin<"__builtin_ia32_vcomiss">,
Intrinsic<[llvm_i32_ty], [llvm_v4f32_ty,
llvm_v4f32_ty, llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
}
// Compress, Expand
@@ -4676,37 +4684,37 @@ let TargetPrefix = "x86" in {
GCCBuiltin<"__builtin_ia32_pternlogd128">,
Intrinsic<[llvm_v4i32_ty],
[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_pternlog_d_256 :
GCCBuiltin<"__builtin_ia32_pternlogd256">,
Intrinsic<[llvm_v8i32_ty],
[llvm_v8i32_ty, llvm_v8i32_ty, llvm_v8i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_pternlog_d_512 :
GCCBuiltin<"__builtin_ia32_pternlogd512">,
Intrinsic<[llvm_v16i32_ty],
[llvm_v16i32_ty, llvm_v16i32_ty, llvm_v16i32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<3>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_pternlog_q_128 :
GCCBuiltin<"__builtin_ia32_pternlogq128">,
Intrinsic<[llvm_v2i64_ty],
[llvm_v2i64_ty, llvm_v2i64_ty, llvm_v2i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_pternlog_q_256 :
GCCBuiltin<"__builtin_ia32_pternlogq256">,
Intrinsic<[llvm_v4i64_ty],
[llvm_v4i64_ty, llvm_v4i64_ty, llvm_v4i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_pternlog_q_512 :
GCCBuiltin<"__builtin_ia32_pternlogq512">,
Intrinsic<[llvm_v8i64_ty],
[llvm_v8i64_ty, llvm_v8i64_ty, llvm_v8i64_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<3>>]>;
}
// vp2intersect
@@ -4744,34 +4752,34 @@ let TargetPrefix = "x86" in {
def int_x86_avx512_cmp_ps_512 :
Intrinsic<[llvm_v16i1_ty], [llvm_v16f32_ty, llvm_v16f32_ty,
llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_cmp_pd_512 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f64_ty, llvm_v8f64_ty,
llvm_i32_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<3>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<3>>]>;
def int_x86_avx512_cmp_ps_256 :
Intrinsic<[llvm_v8i1_ty], [llvm_v8f32_ty, llvm_v8f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cmp_pd_256 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f64_ty, llvm_v4f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cmp_ps_128 :
Intrinsic<[llvm_v4i1_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_cmp_pd_128 :
Intrinsic<[llvm_v2i1_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
- llvm_i32_ty], [IntrNoMem, ImmArg<2>]>;
+ llvm_i32_ty], [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_avx512_mask_cmp_ss :
GCCBuiltin<"__builtin_ia32_cmpss_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v4f32_ty, llvm_v4f32_ty,
llvm_i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
def int_x86_avx512_mask_cmp_sd :
GCCBuiltin<"__builtin_ia32_cmpsd_mask">,
Intrinsic<[llvm_i8_ty], [llvm_v2f64_ty, llvm_v2f64_ty,
llvm_i32_ty, llvm_i8_ty, llvm_i32_ty],
- [IntrNoMem, ImmArg<2>, ImmArg<4>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>, ImmArg<ArgIndex<4>>]>;
}
//===----------------------------------------------------------------------===//
@@ -4779,7 +4787,7 @@ let TargetPrefix = "x86" in {
let TargetPrefix = "x86" in {
def int_x86_sha1rnds4 : GCCBuiltin<"__builtin_ia32_sha1rnds4">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty, llvm_i8_ty],
- [IntrNoMem, ImmArg<2>]>;
+ [IntrNoMem, ImmArg<ArgIndex<2>>]>;
def int_x86_sha1nexte : GCCBuiltin<"__builtin_ia32_sha1nexte">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
def int_x86_sha1msg1 : GCCBuiltin<"__builtin_ia32_sha1msg1">,
@@ -4922,3 +4930,50 @@ let TargetPrefix = "x86" in {
def int_x86_enqcmds : GCCBuiltin<"__builtin_ia32_enqcmds">,
Intrinsic<[llvm_i8_ty], [llvm_ptr_ty, llvm_ptr_ty], []>;
}
+
+//===----------------------------------------------------------------------===//
+// SERIALIZE - Serialize instruction fetch and execution
+
+let TargetPrefix = "x86" in {
+ def int_x86_serialize : GCCBuiltin<"__builtin_ia32_serialize">,
+ Intrinsic<[], [], []>;
+}
+
+//===----------------------------------------------------------------------===//
+// TSXLDTRK - TSX Suspend Load Address Tracking
+
+let TargetPrefix = "x86" in {
+ def int_x86_xsusldtrk : GCCBuiltin<"__builtin_ia32_xsusldtrk">,
+ Intrinsic<[], [], []>;
+ def int_x86_xresldtrk : GCCBuiltin<"__builtin_ia32_xresldtrk">,
+ Intrinsic<[], [], []>;
+}
+//===----------------------------------------------------------------------===//
+// AMX - Intel AMX extensions
+
+let TargetPrefix = "x86" in {
+ def int_x86_ldtilecfg : GCCBuiltin<"__builtin_ia32_tile_loadconfig">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_sttilecfg : GCCBuiltin<"__builtin_ia32_tile_storeconfig">,
+ Intrinsic<[], [llvm_ptr_ty], []>;
+ def int_x86_tilerelease : GCCBuiltin<"__builtin_ia32_tilerelease">,
+ Intrinsic<[], [], []>;
+ def int_x86_tilezero : GCCBuiltin<"__builtin_ia32_tilezero">,
+ Intrinsic<[], [llvm_i8_ty], []>;
+ def int_x86_tileloadd64 : GCCBuiltin<"__builtin_ia32_tileloadd64">,
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty], []>;
+ def int_x86_tileloaddt164 : GCCBuiltin<"__builtin_ia32_tileloaddt164">,
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty], []>;
+ def int_x86_tilestored64 : GCCBuiltin<"__builtin_ia32_tilestored64">,
+ Intrinsic<[], [llvm_i8_ty, llvm_ptr_ty, llvm_i64_ty], []>;
+ def int_x86_tdpbssd : GCCBuiltin<"__builtin_ia32_tdpbssd">,
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty], []>;
+ def int_x86_tdpbsud : GCCBuiltin<"__builtin_ia32_tdpbsud">,
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty], []>;
+ def int_x86_tdpbusd : GCCBuiltin<"__builtin_ia32_tdpbusd">,
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty], []>;
+ def int_x86_tdpbuud : GCCBuiltin<"__builtin_ia32_tdpbuud">,
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty], []>;
+ def int_x86_tdpbf16ps : GCCBuiltin<"__builtin_ia32_tdpbf16ps">,
+ Intrinsic<[], [llvm_i8_ty, llvm_i8_ty, llvm_i8_ty], []>;
+}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsXCore.td b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsXCore.td
index 7fe8bdfd3bd0..89dbc65fea44 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsXCore.td
+++ b/contrib/llvm-project/llvm/include/llvm/IR/IntrinsicsXCore.td
@@ -38,58 +38,58 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
// Resource instructions.
def int_xcore_getr : Intrinsic<[llvm_anyptr_ty],[llvm_i32_ty]>;
def int_xcore_freer : Intrinsic<[],[llvm_anyptr_ty],
- [NoCapture<0>]>;
- def int_xcore_in : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],[NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
+ def int_xcore_in : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],[NoCapture<ArgIndex<0>>]>;
def int_xcore_int : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_inct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_out : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_outt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_outct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_chkct : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_testct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_testwct : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_setd : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_setc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_inshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_outshr : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_setpt : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_clrpt : Intrinsic<[],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_getts : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_syncr : Intrinsic<[],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_settw : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_setv : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_setev : Intrinsic<[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
- def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
- def int_xcore_edu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
+ def int_xcore_eeu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<ArgIndex<0>>]>;
+ def int_xcore_edu : Intrinsic<[],[llvm_anyptr_ty], [NoCapture<ArgIndex<0>>]>;
def int_xcore_setclk : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
- [NoCapture<0>, NoCapture<1>]>;
+ [NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>]>;
def int_xcore_setrdy : Intrinsic<[],[llvm_anyptr_ty, llvm_anyptr_ty],
- [NoCapture<0>, NoCapture<1>]>;
+ [NoCapture<ArgIndex<0>>, NoCapture<ArgIndex<1>>]>;
def int_xcore_setpsc : Intrinsic<[],[llvm_anyptr_ty, llvm_i32_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_peek : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_endin : Intrinsic<[llvm_i32_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
// Intrinsics for events.
def int_xcore_waitevent : Intrinsic<[llvm_ptr_ty],[], [IntrReadMem]>;
@@ -103,18 +103,18 @@ let TargetPrefix = "xcore" in { // All intrinsics start with "llvm.xcore.".
// Intrinsics for threads.
def int_xcore_getst : Intrinsic <[llvm_anyptr_ty],[llvm_anyptr_ty],
- [NoCapture<0>]>;
- def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
+ def int_xcore_msync : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<ArgIndex<0>>]>;
def int_xcore_ssync : Intrinsic <[],[]>;
- def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<0>]>;
+ def int_xcore_mjoin : Intrinsic <[],[llvm_anyptr_ty], [NoCapture<ArgIndex<0>>]>;
def int_xcore_initsp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_initpc : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_initlr : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_initcp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
def int_xcore_initdp : Intrinsic <[],[llvm_anyptr_ty, llvm_ptr_ty],
- [NoCapture<0>]>;
+ [NoCapture<ArgIndex<0>>]>;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/LLVMContext.h b/contrib/llvm-project/llvm/include/llvm/IR/LLVMContext.h
index 39d19b7cffd9..c465e02c2fc5 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/LLVMContext.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/LLVMContext.h
@@ -31,12 +31,17 @@ class LLVMContextImpl;
class Module;
class OptPassGate;
template <typename T> class SmallVectorImpl;
+template <typename T> class StringMapEntry;
class SMDiagnostic;
class StringRef;
class Twine;
-class RemarkStreamer;
+class LLVMRemarkStreamer;
class raw_ostream;
+namespace remarks {
+class RemarkStreamer;
+}
+
namespace SyncScope {
typedef uint8_t ID;
@@ -79,12 +84,15 @@ public:
/// Known operand bundle tag IDs, which always have the same value. All
/// operand bundle tags that LLVM has special knowledge of are listed here.
/// Additionally, this scheme allows LLVM to efficiently check for specific
- /// operand bundle tags without comparing strings.
+ /// operand bundle tags without comparing strings. Keep this in sync with
+ /// LLVMContext::LLVMContext().
enum : unsigned {
OB_deopt = 0, // "deopt"
OB_funclet = 1, // "funclet"
OB_gc_transition = 2, // "gc-transition"
OB_cfguardtarget = 3, // "cfguardtarget"
+ OB_preallocated = 4, // "preallocated"
+ OB_gc_live = 5, // "gc-live"
};
/// getMDKindID - Return a unique non-zero ID for the specified metadata kind.
@@ -101,6 +109,10 @@ public:
/// \see LLVMContext::getOperandBundleTagID
void getOperandBundleTags(SmallVectorImpl<StringRef> &Result) const;
+ /// getOrInsertBundleTag - Returns the Tag to use for an operand bundle of
+ /// name TagName.
+ StringMapEntry<uint32_t> *getOrInsertBundleTag(StringRef TagName) const;
+
/// getOperandBundleTagID - Maps a bundle tag to an integer ID. Every bundle
/// tag registered with an LLVMContext has an unique ID.
uint32_t getOperandBundleTagID(StringRef Tag) const;
@@ -218,23 +230,27 @@ public:
/// included in optimization diagnostics.
void setDiagnosticsHotnessThreshold(uint64_t Threshold);
- /// Return the streamer used by the backend to save remark diagnostics. If it
- /// does not exist, diagnostics are not saved in a file but only emitted via
- /// the diagnostic handler.
- RemarkStreamer *getRemarkStreamer();
- const RemarkStreamer *getRemarkStreamer() const;
-
- /// Set the diagnostics output used for optimization diagnostics.
- /// This filename may be embedded in a section for tools to find the
- /// diagnostics whenever they're needed.
+ /// The "main remark streamer" used by all the specialized remark streamers.
+ /// This streamer keeps generic remark metadata in memory throughout the life
+ /// of the LLVMContext. This metadata may be emitted in a section in object
+ /// files depending on the format requirements.
///
- /// If a remark streamer is already set, it will be replaced with
- /// \p RemarkStreamer.
+ /// All specialized remark streamers should convert remarks to
+ /// llvm::remarks::Remark and emit them through this streamer.
+ remarks::RemarkStreamer *getMainRemarkStreamer();
+ const remarks::RemarkStreamer *getMainRemarkStreamer() const;
+ void setMainRemarkStreamer(
+ std::unique_ptr<remarks::RemarkStreamer> MainRemarkStreamer);
+
+ /// The "LLVM remark streamer" used by LLVM to serialize remark diagnostics
+ /// comming from IR and MIR passes.
///
- /// By default, diagnostics are not saved in a file but only emitted via the
- /// diagnostic handler. Even if an output file is set, the handler is invoked
- /// for each diagnostic message.
- void setRemarkStreamer(std::unique_ptr<RemarkStreamer> RemarkStreamer);
+ /// If it does not exist, diagnostics are not saved in a file but only emitted
+ /// via the diagnostic handler.
+ LLVMRemarkStreamer *getLLVMRemarkStreamer();
+ const LLVMRemarkStreamer *getLLVMRemarkStreamer() const;
+ void
+ setLLVMRemarkStreamer(std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer);
/// Get the prefix that should be printed in front of a diagnostic of
/// the given \p Severity
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/LLVMRemarkStreamer.h b/contrib/llvm-project/llvm/include/llvm/IR/LLVMRemarkStreamer.h
new file mode 100644
index 000000000000..97082a44e62f
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/LLVMRemarkStreamer.h
@@ -0,0 +1,95 @@
+//===- llvm/IR/LLVMRemarkStreamer.h - Streamer for LLVM remarks--*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the conversion between IR Diagnostics and
+// serializable remarks::Remark objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_LLVMREMARKSTREAMER_H
+#define LLVM_IR_LLVMREMARKSTREAMER_H
+
+#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/Remarks/RemarkStreamer.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include <memory>
+#include <string>
+
+namespace llvm {
+/// Streamer for LLVM remarks which has logic for dealing with DiagnosticInfo
+/// objects.
+class LLVMRemarkStreamer {
+ remarks::RemarkStreamer &RS;
+ /// Convert diagnostics into remark objects.
+ /// The lifetime of the members of the result is bound to the lifetime of
+ /// the LLVM diagnostics.
+ remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag) const;
+
+public:
+ LLVMRemarkStreamer(remarks::RemarkStreamer &RS) : RS(RS) {}
+ /// Emit a diagnostic through the streamer.
+ void emit(const DiagnosticInfoOptimizationBase &Diag);
+};
+
+template <typename ThisError>
+struct LLVMRemarkSetupErrorInfo : public ErrorInfo<ThisError> {
+ std::string Msg;
+ std::error_code EC;
+
+ LLVMRemarkSetupErrorInfo(Error E) {
+ handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
+ Msg = EIB.message();
+ EC = EIB.convertToErrorCode();
+ });
+ }
+
+ void log(raw_ostream &OS) const override { OS << Msg; }
+ std::error_code convertToErrorCode() const override { return EC; }
+};
+
+struct LLVMRemarkSetupFileError
+ : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFileError> {
+ static char ID;
+ using LLVMRemarkSetupErrorInfo<
+ LLVMRemarkSetupFileError>::LLVMRemarkSetupErrorInfo;
+};
+
+struct LLVMRemarkSetupPatternError
+ : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupPatternError> {
+ static char ID;
+ using LLVMRemarkSetupErrorInfo<
+ LLVMRemarkSetupPatternError>::LLVMRemarkSetupErrorInfo;
+};
+
+struct LLVMRemarkSetupFormatError
+ : LLVMRemarkSetupErrorInfo<LLVMRemarkSetupFormatError> {
+ static char ID;
+ using LLVMRemarkSetupErrorInfo<
+ LLVMRemarkSetupFormatError>::LLVMRemarkSetupErrorInfo;
+};
+
+/// Setup optimization remarks that output to a file.
+Expected<std::unique_ptr<ToolOutputFile>>
+setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness,
+ unsigned RemarksHotnessThreshold = 0);
+
+/// Setup optimization remarks that output directly to a raw_ostream.
+/// \p OS is managed by the caller and should be open for writing as long as \p
+/// Context is streaming remarks to it.
+Error setupLLVMOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
+ StringRef RemarksPasses,
+ StringRef RemarksFormat,
+ bool RemarksWithHotness,
+ unsigned RemarksHotnessThreshold = 0);
+
+} // end namespace llvm
+
+#endif // LLVM_IR_LLVMREMARKSTREAMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassManagers.h b/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassManagers.h
index 5044c1f6ed31..6b1ddd4d79f8 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassManagers.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassManagers.h
@@ -330,7 +330,8 @@ public:
/// through getAnalysis interface.
virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass);
- virtual Pass *getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F);
+ virtual std::tuple<Pass *, bool> getOnTheFlyPass(Pass *P, AnalysisID PI,
+ Function &F);
/// Initialize available analysis information.
void initializeAnalysisInfo() {
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassNameParser.h b/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassNameParser.h
index 30820e750350..c33b9fc40472 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassNameParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/LegacyPassNameParser.h
@@ -92,47 +92,6 @@ private:
}
};
-///===----------------------------------------------------------------------===//
-/// FilteredPassNameParser class - Make use of the pass registration
-/// mechanism to automatically add a command line argument to opt for
-/// each pass that satisfies a filter criteria. Filter should return
-/// true for passes to be registered as command-line options.
-///
-template<typename Filter>
-class FilteredPassNameParser : public PassNameParser {
-private:
- Filter filter;
-
-public:
- bool ignorablePassImpl(const PassInfo *P) const override {
- return !filter(*P);
- }
-};
-
-///===----------------------------------------------------------------------===//
-/// PassArgFilter - A filter for use with PassNameFilterParser that only
-/// accepts a Pass whose Arg matches certain strings.
-///
-/// Use like this:
-///
-/// extern const char AllowedPassArgs[] = "-anders_aa -dse";
-///
-/// static cl::list<
-/// const PassInfo*,
-/// bool,
-/// FilteredPassNameParser<PassArgFilter<AllowedPassArgs> > >
-/// PassList(cl::desc("Passes available:"));
-///
-/// Only the -anders_aa and -dse options will be available to the user.
-///
-template<const char *Args>
-class PassArgFilter {
-public:
- bool operator()(const PassInfo &P) const {
- return StringRef(Args).contains(P.getPassArgument());
- }
-};
-
} // End llvm namespace
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Mangler.h b/contrib/llvm-project/llvm/include/llvm/IR/Mangler.h
index e4a05ab46a65..747a4085235c 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Mangler.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Mangler.h
@@ -14,11 +14,11 @@
#define LLVM_IR_MANGLER_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/IR/GlobalValue.h"
namespace llvm {
class DataLayout;
+class GlobalValue;
template <typename T> class SmallVectorImpl;
class Triple;
class Twine;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/MatrixBuilder.h b/contrib/llvm-project/llvm/include/llvm/IR/MatrixBuilder.h
new file mode 100644
index 000000000000..5d04b3563dd5
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/MatrixBuilder.h
@@ -0,0 +1,221 @@
+//===- llvm/MatrixBuilder.h - Builder to lower matrix ops -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MatrixBuilder class, which is used as a convenient way
+// to lower matrix operations to LLVM IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_MATRIXBUILDER_H
+#define LLVM_IR_MATRIXBUILDER_H
+
+#include "llvm/IR/Constant.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/Alignment.h"
+
+namespace llvm {
+
+class Function;
+class Twine;
+class Module;
+
+template <class IRBuilderTy> class MatrixBuilder {
+ IRBuilderTy &B;
+ Module *getModule() { return B.GetInsertBlock()->getParent()->getParent(); }
+
+ std::pair<Value *, Value *> splatScalarOperandIfNeeded(Value *LHS,
+ Value *RHS) {
+ assert((LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy()) &&
+ "One of the operands must be a matrix (embedded in a vector)");
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+ RHS = B.CreateVectorSplat(
+ cast<VectorType>(LHS->getType())->getNumElements(), RHS,
+ "scalar.splat");
+ else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+ LHS = B.CreateVectorSplat(
+ cast<VectorType>(RHS->getType())->getNumElements(), LHS,
+ "scalar.splat");
+ return {LHS, RHS};
+ }
+
+public:
+ MatrixBuilder(IRBuilderTy &Builder) : B(Builder) {}
+
+ /// Create a column major, strided matrix load.
+ /// \p DataPtr - Start address of the matrix read
+ /// \p Rows - Number of rows in matrix (must be a constant)
+ /// \p Columns - Number of columns in matrix (must be a constant)
+ /// \p Stride - Space between columns
+ CallInst *CreateColumnMajorLoad(Value *DataPtr, Align Alignment,
+ Value *Stride, bool IsVolatile, unsigned Rows,
+ unsigned Columns, const Twine &Name = "") {
+
+ // Deal with the pointer
+ PointerType *PtrTy = cast<PointerType>(DataPtr->getType());
+ Type *EltTy = PtrTy->getElementType();
+
+ auto *RetType = FixedVectorType::get(EltTy, Rows * Columns);
+
+ Value *Ops[] = {DataPtr, Stride, B.getInt1(IsVolatile), B.getInt32(Rows),
+ B.getInt32(Columns)};
+ Type *OverloadedTypes[] = {RetType};
+
+ Function *TheFn = Intrinsic::getDeclaration(
+ getModule(), Intrinsic::matrix_column_major_load, OverloadedTypes);
+
+ CallInst *Call = B.CreateCall(TheFn->getFunctionType(), TheFn, Ops, Name);
+ Attribute AlignAttr =
+ Attribute::getWithAlignment(Call->getContext(), Alignment);
+ Call->addAttribute(1, AlignAttr);
+ return Call;
+ }
+
+ /// Create a column major, strided matrix store.
+ /// \p Matrix - Matrix to store
+ /// \p Ptr - Pointer to write back to
+ /// \p Stride - Space between columns
+ CallInst *CreateColumnMajorStore(Value *Matrix, Value *Ptr, Align Alignment,
+ Value *Stride, bool IsVolatile,
+ unsigned Rows, unsigned Columns,
+ const Twine &Name = "") {
+ Value *Ops[] = {Matrix, Ptr,
+ Stride, B.getInt1(IsVolatile),
+ B.getInt32(Rows), B.getInt32(Columns)};
+ Type *OverloadedTypes[] = {Matrix->getType()};
+
+ Function *TheFn = Intrinsic::getDeclaration(
+ getModule(), Intrinsic::matrix_column_major_store, OverloadedTypes);
+
+ CallInst *Call = B.CreateCall(TheFn->getFunctionType(), TheFn, Ops, Name);
+ Attribute AlignAttr =
+ Attribute::getWithAlignment(Call->getContext(), Alignment);
+ Call->addAttribute(2, AlignAttr);
+ return Call;
+ }
+
+ /// Create a llvm.matrix.transpose call, transposing \p Matrix with \p Rows
+ /// rows and \p Columns columns.
+ CallInst *CreateMatrixTranspose(Value *Matrix, unsigned Rows,
+ unsigned Columns, const Twine &Name = "") {
+ auto *OpType = cast<VectorType>(Matrix->getType());
+ auto *ReturnType =
+ FixedVectorType::get(OpType->getElementType(), Rows * Columns);
+
+ Type *OverloadedTypes[] = {ReturnType};
+ Value *Ops[] = {Matrix, B.getInt32(Rows), B.getInt32(Columns)};
+ Function *TheFn = Intrinsic::getDeclaration(
+ getModule(), Intrinsic::matrix_transpose, OverloadedTypes);
+
+ return B.CreateCall(TheFn->getFunctionType(), TheFn, Ops, Name);
+ }
+
+ /// Create a llvm.matrix.multiply call, multiplying matrixes \p LHS and \p
+ /// RHS.
+ CallInst *CreateMatrixMultiply(Value *LHS, Value *RHS, unsigned LHSRows,
+ unsigned LHSColumns, unsigned RHSColumns,
+ const Twine &Name = "") {
+ auto *LHSType = cast<VectorType>(LHS->getType());
+ auto *RHSType = cast<VectorType>(RHS->getType());
+
+ auto *ReturnType =
+ FixedVectorType::get(LHSType->getElementType(), LHSRows * RHSColumns);
+
+ Value *Ops[] = {LHS, RHS, B.getInt32(LHSRows), B.getInt32(LHSColumns),
+ B.getInt32(RHSColumns)};
+ Type *OverloadedTypes[] = {ReturnType, LHSType, RHSType};
+
+ Function *TheFn = Intrinsic::getDeclaration(
+ getModule(), Intrinsic::matrix_multiply, OverloadedTypes);
+ return B.CreateCall(TheFn->getFunctionType(), TheFn, Ops, Name);
+ }
+
+ /// Insert a single element \p NewVal into \p Matrix at indices (\p RowIdx, \p
+ /// ColumnIdx).
+ Value *CreateMatrixInsert(Value *Matrix, Value *NewVal, Value *RowIdx,
+ Value *ColumnIdx, unsigned NumRows) {
+ return B.CreateInsertElement(
+ Matrix, NewVal,
+ B.CreateAdd(B.CreateMul(ColumnIdx, ConstantInt::get(
+ ColumnIdx->getType(), NumRows)),
+ RowIdx));
+ }
+
+ /// Add matrixes \p LHS and \p RHS. Support both integer and floating point
+ /// matrixes.
+ Value *CreateAdd(Value *LHS, Value *RHS) {
+ assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+ RHS = B.CreateVectorSplat(
+ cast<VectorType>(LHS->getType())->getNumElements(), RHS,
+ "scalar.splat");
+ else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+ LHS = B.CreateVectorSplat(
+ cast<VectorType>(RHS->getType())->getNumElements(), LHS,
+ "scalar.splat");
+
+ return cast<VectorType>(LHS->getType())
+ ->getElementType()
+ ->isFloatingPointTy()
+ ? B.CreateFAdd(LHS, RHS)
+ : B.CreateAdd(LHS, RHS);
+ }
+
+ /// Subtract matrixes \p LHS and \p RHS. Support both integer and floating
+ /// point matrixes.
+ Value *CreateSub(Value *LHS, Value *RHS) {
+ assert(LHS->getType()->isVectorTy() || RHS->getType()->isVectorTy());
+ if (LHS->getType()->isVectorTy() && !RHS->getType()->isVectorTy())
+ RHS = B.CreateVectorSplat(
+ cast<VectorType>(LHS->getType())->getNumElements(), RHS,
+ "scalar.splat");
+ else if (!LHS->getType()->isVectorTy() && RHS->getType()->isVectorTy())
+ LHS = B.CreateVectorSplat(
+ cast<VectorType>(RHS->getType())->getNumElements(), LHS,
+ "scalar.splat");
+
+ return cast<VectorType>(LHS->getType())
+ ->getElementType()
+ ->isFloatingPointTy()
+ ? B.CreateFSub(LHS, RHS)
+ : B.CreateSub(LHS, RHS);
+ }
+
+ /// Multiply matrix \p LHS with scalar \p RHS or scalar \p LHS with matrix \p
+ /// RHS.
+ Value *CreateScalarMultiply(Value *LHS, Value *RHS) {
+ std::tie(LHS, RHS) = splatScalarOperandIfNeeded(LHS, RHS);
+ if (LHS->getType()->getScalarType()->isFloatingPointTy())
+ return B.CreateFMul(LHS, RHS);
+ return B.CreateMul(LHS, RHS);
+ }
+
+ /// Extracts the element at (\p RowIdx, \p ColumnIdx) from \p Matrix.
+ Value *CreateExtractElement(Value *Matrix, Value *RowIdx, Value *ColumnIdx,
+ unsigned NumRows, Twine const &Name = "") {
+
+ unsigned MaxWidth = std::max(RowIdx->getType()->getScalarSizeInBits(),
+ ColumnIdx->getType()->getScalarSizeInBits());
+ Type *IntTy = IntegerType::get(RowIdx->getType()->getContext(), MaxWidth);
+ RowIdx = B.CreateZExt(RowIdx, IntTy);
+ ColumnIdx = B.CreateZExt(ColumnIdx, IntTy);
+ Value *NumRowsV = B.getIntN(MaxWidth, NumRows);
+ return B.CreateExtractElement(
+ Matrix, B.CreateAdd(B.CreateMul(ColumnIdx, NumRowsV), RowIdx),
+ "matext");
+ }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_IR_MATRIXBUILDER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Metadata.h b/contrib/llvm-project/llvm/include/llvm/IR/Metadata.h
index dda939b97575..46526c70ea3b 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Metadata.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Metadata.h
@@ -527,7 +527,7 @@ template <class V, class M> struct IsValidReference {
/// As an analogue to \a isa(), check whether \c MD has an \a Value inside of
/// type \c X.
template <class X, class Y>
-inline typename std::enable_if<detail::IsValidPointer<X, Y>::value, bool>::type
+inline std::enable_if_t<detail::IsValidPointer<X, Y>::value, bool>
hasa(Y &&MD) {
assert(MD && "Null pointer sent into hasa");
if (auto *V = dyn_cast<ConstantAsMetadata>(MD))
@@ -535,9 +535,8 @@ hasa(Y &&MD) {
return false;
}
template <class X, class Y>
-inline
- typename std::enable_if<detail::IsValidReference<X, Y &>::value, bool>::type
- hasa(Y &MD) {
+inline std::enable_if_t<detail::IsValidReference<X, Y &>::value, bool>
+hasa(Y &MD) {
return hasa(&MD);
}
@@ -545,14 +544,13 @@ inline
///
/// As an analogue to \a cast(), extract the \a Value subclass \c X from \c MD.
template <class X, class Y>
-inline typename std::enable_if<detail::IsValidPointer<X, Y>::value, X *>::type
+inline std::enable_if_t<detail::IsValidPointer<X, Y>::value, X *>
extract(Y &&MD) {
return cast<X>(cast<ConstantAsMetadata>(MD)->getValue());
}
template <class X, class Y>
-inline
- typename std::enable_if<detail::IsValidReference<X, Y &>::value, X *>::type
- extract(Y &MD) {
+inline std::enable_if_t<detail::IsValidReference<X, Y &>::value, X *>
+extract(Y &MD) {
return extract(&MD);
}
@@ -561,7 +559,7 @@ inline
/// As an analogue to \a cast_or_null(), extract the \a Value subclass \c X
/// from \c MD, allowing \c MD to be null.
template <class X, class Y>
-inline typename std::enable_if<detail::IsValidPointer<X, Y>::value, X *>::type
+inline std::enable_if_t<detail::IsValidPointer<X, Y>::value, X *>
extract_or_null(Y &&MD) {
if (auto *V = cast_or_null<ConstantAsMetadata>(MD))
return cast<X>(V->getValue());
@@ -574,7 +572,7 @@ extract_or_null(Y &&MD) {
/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a
/// Value it does contain is of the wrong subclass.
template <class X, class Y>
-inline typename std::enable_if<detail::IsValidPointer<X, Y>::value, X *>::type
+inline std::enable_if_t<detail::IsValidPointer<X, Y>::value, X *>
dyn_extract(Y &&MD) {
if (auto *V = dyn_cast<ConstantAsMetadata>(MD))
return dyn_cast<X>(V->getValue());
@@ -587,7 +585,7 @@ dyn_extract(Y &&MD) {
/// from \c MD, return null if \c MD doesn't contain a \a Value or if the \a
/// Value it does contain is of the wrong subclass, allowing \c MD to be null.
template <class X, class Y>
-inline typename std::enable_if<detail::IsValidPointer<X, Y>::value, X *>::type
+inline std::enable_if_t<detail::IsValidPointer<X, Y>::value, X *>
dyn_extract_or_null(Y &&MD) {
if (auto *V = dyn_cast_or_null<ConstantAsMetadata>(MD))
return dyn_cast<X>(V->getValue());
@@ -976,7 +974,7 @@ public:
/// Try to create a uniqued version of \c N -- in place, if possible -- and
/// return it. If \c N cannot be uniqued, return a distinct node instead.
template <class T>
- static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ static std::enable_if_t<std::is_base_of<MDNode, T>::value, T *>
replaceWithPermanent(std::unique_ptr<T, TempMDNodeDeleter> N) {
return cast<T>(N.release()->replaceWithPermanentImpl());
}
@@ -988,7 +986,7 @@ public:
///
/// \pre N does not self-reference.
template <class T>
- static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ static std::enable_if_t<std::is_base_of<MDNode, T>::value, T *>
replaceWithUniqued(std::unique_ptr<T, TempMDNodeDeleter> N) {
return cast<T>(N.release()->replaceWithUniquedImpl());
}
@@ -998,7 +996,7 @@ public:
/// Create a distinct version of \c N -- in place, if possible -- and return
/// it. Takes ownership of the temporary node.
template <class T>
- static typename std::enable_if<std::is_base_of<MDNode, T>::value, T *>::type
+ static std::enable_if_t<std::is_base_of<MDNode, T>::value, T *>
replaceWithDistinct(std::unique_ptr<T, TempMDNodeDeleter> N) {
return cast<T>(N.release()->replaceWithDistinctImpl());
}
@@ -1237,15 +1235,13 @@ public:
template <class U>
MDTupleTypedArrayWrapper(
const MDTupleTypedArrayWrapper<U> &Other,
- typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
- nullptr)
+ std::enable_if_t<std::is_convertible<U *, T *>::value> * = nullptr)
: N(Other.get()) {}
template <class U>
explicit MDTupleTypedArrayWrapper(
const MDTupleTypedArrayWrapper<U> &Other,
- typename std::enable_if<!std::is_convertible<U *, T *>::value>::type * =
- nullptr)
+ std::enable_if_t<!std::is_convertible<U *, T *>::value> * = nullptr)
: N(Other.get()) {}
explicit operator bool() const { return get(); }
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Module.h b/contrib/llvm-project/llvm/include/llvm/IR/Module.h
index 68cd583c136c..3f97d048f862 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Module.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Module.h
@@ -46,6 +46,7 @@ class FunctionType;
class GVMaterializer;
class LLVMContext;
class MemoryBuffer;
+class ModuleSummaryIndex;
class Pass;
class RandomNumberGenerator;
template <class PtrType> class SmallPtrSetImpl;
@@ -79,6 +80,8 @@ public:
using NamedMDListType = ilist<NamedMDNode>;
/// The type of the comdat "symbol" table.
using ComdatSymTabType = StringMap<Comdat>;
+ /// The type for mapping names to named metadata.
+ using NamedMDSymTabType = StringMap<NamedMDNode *>;
/// The Global Variable iterator.
using global_iterator = GlobalListType::iterator;
@@ -154,6 +157,11 @@ public:
/// converted result in MFB.
static bool isValidModFlagBehavior(Metadata *MD, ModFlagBehavior &MFB);
+ /// Check if the given module flag metadata represents a valid module flag,
+ /// and store the flag behavior, the key string and the value metadata.
+ static bool isValidModuleFlag(const MDNode &ModFlag, ModFlagBehavior &MFB,
+ MDString *&Key, Metadata *&Val);
+
struct ModuleFlagEntry {
ModFlagBehavior Behavior;
MDString *Key;
@@ -175,7 +183,7 @@ private:
IFuncListType IFuncList; ///< The IFuncs in the module
NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
- ValueSymbolTable *ValSymTab; ///< Symbol table for values
+ std::unique_ptr<ValueSymbolTable> ValSymTab; ///< Symbol table for values
ComdatSymTabType ComdatSymTab; ///< Symbol table for COMDATs
std::unique_ptr<MemoryBuffer>
OwnedMemoryBuffer; ///< Memory buffer directly owned by this
@@ -187,7 +195,7 @@ private:
///< recorded in bitcode.
std::string TargetTriple; ///< Platform target triple Module compiled on
///< Format: (arch)(sub)-(vendor)-(sys0-(abi)
- void *NamedMDSymTab; ///< NamedMDNode names.
+ NamedMDSymTabType NamedMDSymTab; ///< NamedMDNode names.
DataLayout DL; ///< DataLayout associated with the module
friend class Constant;
@@ -257,7 +265,7 @@ public:
/// when other randomness consuming passes are added or removed. In
/// addition, the random stream will be reproducible across LLVM
/// versions when the pass does not change.
- std::unique_ptr<RandomNumberGenerator> createRNG(const Pass* P) const;
+ std::unique_ptr<RandomNumberGenerator> createRNG(const StringRef Name) const;
/// Return true if size-info optimization remark is enabled, false
/// otherwise.
@@ -271,22 +279,22 @@ public:
/// @{
/// Set the module identifier.
- void setModuleIdentifier(StringRef ID) { ModuleID = ID; }
+ void setModuleIdentifier(StringRef ID) { ModuleID = std::string(ID); }
/// Set the module's original source file name.
- void setSourceFileName(StringRef Name) { SourceFileName = Name; }
+ void setSourceFileName(StringRef Name) { SourceFileName = std::string(Name); }
/// Set the data layout
void setDataLayout(StringRef Desc);
void setDataLayout(const DataLayout &Other);
/// Set the target triple.
- void setTargetTriple(StringRef T) { TargetTriple = T; }
+ void setTargetTriple(StringRef T) { TargetTriple = std::string(T); }
/// Set the module-scope inline assembly blocks.
/// A trailing newline is added if the input doesn't have one.
void setModuleInlineAsm(StringRef Asm) {
- GlobalScopeAsm = Asm;
+ GlobalScopeAsm = std::string(Asm);
if (!GlobalScopeAsm.empty() && GlobalScopeAsm.back() != '\n')
GlobalScopeAsm += '\n';
}
@@ -491,10 +499,12 @@ public:
void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, Constant *Val);
void addModuleFlag(ModFlagBehavior Behavior, StringRef Key, uint32_t Val);
void addModuleFlag(MDNode *Node);
+ /// Like addModuleFlag but replaces the old module flag if it already exists.
+ void setModuleFlag(ModFlagBehavior Behavior, StringRef Key, Metadata *Val);
-/// @}
-/// @name Materialization
-/// @{
+ /// @}
+ /// @name Materialization
+ /// @{
/// Sets the GVMaterializer to GVM. This module must not yet have a
/// Materializer. To reset the materializer for a module that already has one,
@@ -583,6 +593,7 @@ public:
const_global_iterator global_begin() const { return GlobalList.begin(); }
global_iterator global_end () { return GlobalList.end(); }
const_global_iterator global_end () const { return GlobalList.end(); }
+ size_t global_size () const { return GlobalList.size(); }
bool global_empty() const { return GlobalList.empty(); }
iterator_range<global_iterator> globals() {
@@ -846,6 +857,13 @@ public:
Metadata *getProfileSummary(bool IsCS);
/// @}
+ /// Returns whether semantic interposition is to be respected.
+ bool getSemanticInterposition() const;
+ bool noSemanticInterposition() const;
+
+ /// Set whether semantic interposition is to be respected.
+ void setSemanticInterposition(bool);
+
/// Returns true if PLT should be avoided for RTLib calls.
bool getRtLibUseGOT() const;
@@ -866,6 +884,10 @@ public:
/// Take ownership of the given memory buffer.
void setOwnedMemoryBuffer(std::unique_ptr<MemoryBuffer> MB);
+
+ /// Set the partial sample profile ratio in the profile summary module flag,
+ /// if applicable.
+ void setPartialSampleProfileRatio(const ModuleSummaryIndex &Index);
};
/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndex.h b/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndex.h
index aa4054c8409e..12a829b14e36 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndex.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndex.h
@@ -23,6 +23,7 @@
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Allocator.h"
@@ -552,6 +553,41 @@ public:
unsigned AlwaysInline : 1;
};
+ /// Describes the uses of a parameter by the function.
+ struct ParamAccess {
+ static constexpr uint32_t RangeWidth = 64;
+
+ /// Describes the use of a value in a call instruction, specifying the
+ /// call's target, the value's parameter number, and the possible range of
+ /// offsets from the beginning of the value that are passed.
+ struct Call {
+ uint64_t ParamNo = 0;
+ GlobalValue::GUID Callee = 0;
+ ConstantRange Offsets{/*BitWidth=*/RangeWidth, /*isFullSet=*/true};
+
+ Call() = default;
+ Call(uint64_t ParamNo, GlobalValue::GUID Callee,
+ const ConstantRange &Offsets)
+ : ParamNo(ParamNo), Callee(Callee), Offsets(Offsets) {}
+ };
+
+ uint64_t ParamNo = 0;
+ /// The range contains byte offsets from the parameter pointer which
+ /// accessed by the function. In the per-module summary, it only includes
+ /// accesses made by the function instructions. In the combined summary, it
+ /// also includes accesses by nested function calls.
+ ConstantRange Use{/*BitWidth=*/RangeWidth, /*isFullSet=*/true};
+ /// In the per-module summary, it summarizes the byte offset applied to each
+ /// pointer parameter before passing to each corresponding callee.
+ /// In the combined summary, it's empty and information is propagated by
+ /// inter-procedural analysis and applied to the Use field.
+ std::vector<Call> Calls;
+
+ ParamAccess() = default;
+ ParamAccess(uint64_t ParamNo, const ConstantRange &Use)
+ : ParamNo(ParamNo), Use(Use) {}
+ };
+
/// Create an empty FunctionSummary (with specified call edges).
/// Used to represent external nodes and the dummy root node.
static FunctionSummary
@@ -567,7 +603,8 @@ public:
std::vector<FunctionSummary::VFuncId>(),
std::vector<FunctionSummary::VFuncId>(),
std::vector<FunctionSummary::ConstVCall>(),
- std::vector<FunctionSummary::ConstVCall>());
+ std::vector<FunctionSummary::ConstVCall>(),
+ std::vector<FunctionSummary::ParamAccess>());
}
/// A dummy node to reference external functions that aren't in the index
@@ -591,6 +628,10 @@ private:
std::unique_ptr<TypeIdInfo> TIdInfo;
+ /// Uses for every parameter to this function.
+ using ParamAccessesTy = std::vector<ParamAccess>;
+ std::unique_ptr<ParamAccessesTy> ParamAccesses;
+
public:
FunctionSummary(GVFlags Flags, unsigned NumInsts, FFlags FunFlags,
uint64_t EntryCount, std::vector<ValueInfo> Refs,
@@ -599,18 +640,21 @@ public:
std::vector<VFuncId> TypeTestAssumeVCalls,
std::vector<VFuncId> TypeCheckedLoadVCalls,
std::vector<ConstVCall> TypeTestAssumeConstVCalls,
- std::vector<ConstVCall> TypeCheckedLoadConstVCalls)
+ std::vector<ConstVCall> TypeCheckedLoadConstVCalls,
+ std::vector<ParamAccess> Params)
: GlobalValueSummary(FunctionKind, Flags, std::move(Refs)),
InstCount(NumInsts), FunFlags(FunFlags), EntryCount(EntryCount),
CallGraphEdgeList(std::move(CGEdges)) {
if (!TypeTests.empty() || !TypeTestAssumeVCalls.empty() ||
!TypeCheckedLoadVCalls.empty() || !TypeTestAssumeConstVCalls.empty() ||
!TypeCheckedLoadConstVCalls.empty())
- TIdInfo = std::make_unique<TypeIdInfo>(TypeIdInfo{
- std::move(TypeTests), std::move(TypeTestAssumeVCalls),
- std::move(TypeCheckedLoadVCalls),
- std::move(TypeTestAssumeConstVCalls),
- std::move(TypeCheckedLoadConstVCalls)});
+ TIdInfo = std::make_unique<TypeIdInfo>(
+ TypeIdInfo{std::move(TypeTests), std::move(TypeTestAssumeVCalls),
+ std::move(TypeCheckedLoadVCalls),
+ std::move(TypeTestAssumeConstVCalls),
+ std::move(TypeCheckedLoadConstVCalls)});
+ if (!Params.empty())
+ ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(Params));
}
// Gets the number of readonly and writeonly refs in RefEdgeList
std::pair<unsigned, unsigned> specialRefCounts() const;
@@ -681,6 +725,23 @@ public:
return {};
}
+ /// Returns the list of known uses of pointer parameters.
+ ArrayRef<ParamAccess> paramAccesses() const {
+ if (ParamAccesses)
+ return *ParamAccesses;
+ return {};
+ }
+
+ /// Sets the list of known uses of pointer parameters.
+ void setParamAccesses(std::vector<ParamAccess> NewParams) {
+ if (NewParams.empty())
+ ParamAccesses.reset();
+ else if (ParamAccesses)
+ *ParamAccesses = std::move(NewParams);
+ else
+ ParamAccesses = std::make_unique<ParamAccessesTy>(std::move(NewParams));
+ }
+
/// Add a type test to the summary. This is used by WholeProgramDevirt if we
/// were unable to devirtualize a checked call.
void addTypeTest(GlobalValue::GUID Guid) {
@@ -757,14 +818,33 @@ private:
public:
struct GVarFlags {
- GVarFlags(bool ReadOnly, bool WriteOnly)
- : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly) {}
-
- // In permodule summaries both MaybeReadOnly and MaybeWriteOnly
- // bits are set, because attribute propagation occurs later on
- // thin link phase.
+ GVarFlags(bool ReadOnly, bool WriteOnly, bool Constant,
+ GlobalObject::VCallVisibility Vis)
+ : MaybeReadOnly(ReadOnly), MaybeWriteOnly(WriteOnly),
+ Constant(Constant), VCallVisibility(Vis) {}
+
+ // If true indicates that this global variable might be accessed
+ // purely by non-volatile load instructions. This in turn means
+ // it can be internalized in source and destination modules during
+ // thin LTO import because it neither modified nor its address
+ // is taken.
unsigned MaybeReadOnly : 1;
+ // If true indicates that variable is possibly only written to, so
+ // its value isn't loaded and its address isn't taken anywhere.
+ // False, when 'Constant' attribute is set.
unsigned MaybeWriteOnly : 1;
+ // Indicates that value is a compile-time constant. Global variable
+ // can be 'Constant' while not being 'ReadOnly' on several occasions:
+ // - it is volatile, (e.g mapped device address)
+ // - its address is taken, meaning that unlike 'ReadOnly' vars we can't
+ // internalize it.
+ // Constant variables are always imported thus giving compiler an
+ // opportunity to make some extra optimizations. Readonly constants
+ // are also internalized.
+ unsigned Constant : 1;
+ // Set from metadata on vtable definitions during the module summary
+ // analysis.
+ unsigned VCallVisibility : 2;
} VarFlags;
GlobalVarSummary(GVFlags Flags, GVarFlags VarFlags,
@@ -782,6 +862,13 @@ public:
void setWriteOnly(bool WO) { VarFlags.MaybeWriteOnly = WO; }
bool maybeReadOnly() const { return VarFlags.MaybeReadOnly; }
bool maybeWriteOnly() const { return VarFlags.MaybeWriteOnly; }
+ bool isConstant() const { return VarFlags.Constant; }
+ void setVCallVisibility(GlobalObject::VCallVisibility Vis) {
+ VarFlags.VCallVisibility = Vis;
+ }
+ GlobalObject::VCallVisibility getVCallVisibility() const {
+ return (GlobalObject::VCallVisibility)VarFlags.VCallVisibility;
+ }
void setVTableFuncs(VTableFuncList Funcs) {
assert(!VTableFuncs);
@@ -807,7 +894,8 @@ struct TypeTestResolution {
Single, ///< Single element (last example in "Short Inline Bit Vectors")
AllOnes, ///< All-ones bit vector ("Eliminating Bit Vector Checks for
/// All-Ones Bit Vectors")
- } TheKind = Unsat;
+ Unknown, ///< Unknown (analysis not performed, don't lower)
+ } TheKind = Unknown;
/// Range of size-1 expressed as a bit width. For example, if the size is in
/// range [1,256], this number will be 8. This helps generate the most compact
@@ -933,7 +1021,8 @@ private:
/// with that type identifier's metadata. Produced by per module summary
/// analysis and consumed by thin link. For more information, see description
/// above where TypeIdCompatibleVtableInfo is defined.
- std::map<std::string, TypeIdCompatibleVtableInfo> TypeIdCompatibleVtableMap;
+ std::map<std::string, TypeIdCompatibleVtableInfo, std::less<>>
+ TypeIdCompatibleVtableMap;
/// Mapping from original ID to GUID. If original ID can map to multiple
/// GUIDs, it will be mapped to 0.
@@ -980,6 +1069,10 @@ private:
StringSaver Saver;
BumpPtrAllocator Alloc;
+ // The total number of basic blocks in the module in the per-module summary or
+ // the total number of basic blocks in the LTO unit in the combined index.
+ uint64_t BlockCount;
+
// YAML I/O support.
friend yaml::MappingTraits<ModuleSummaryIndex>;
@@ -992,18 +1085,30 @@ private:
public:
// See HaveGVs variable comment.
ModuleSummaryIndex(bool HaveGVs, bool EnableSplitLTOUnit = false)
- : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc) {
- }
+ : HaveGVs(HaveGVs), EnableSplitLTOUnit(EnableSplitLTOUnit), Saver(Alloc),
+ BlockCount(0) {}
// Current version for the module summary in bitcode files.
// The BitcodeSummaryVersion should be bumped whenever we introduce changes
// in the way some record are interpreted, like flags for instance.
// Note that incrementing this may require changes in both BitcodeReader.cpp
// and BitcodeWriter.cpp.
- static constexpr uint64_t BitcodeSummaryVersion = 8;
+ static constexpr uint64_t BitcodeSummaryVersion = 9;
+
+ // Regular LTO module name for ASM writer
+ static constexpr const char *getRegularLTOModuleName() {
+ return "[Regular LTO]";
+ }
bool haveGVs() const { return HaveGVs; }
+ uint64_t getFlags() const;
+ void setFlags(uint64_t Flags);
+
+ uint64_t getBlockCount() const { return BlockCount; }
+ void addBlockCount(uint64_t C) { BlockCount += C; }
+ void setBlockCount(uint64_t C) { BlockCount = C; }
+
gvsummary_iterator begin() { return GlobalValueMap.begin(); }
const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); }
gvsummary_iterator end() { return GlobalValueMap.end(); }
@@ -1264,7 +1369,7 @@ public:
NewName += ".llvm.";
NewName += utostr((uint64_t(ModHash[0]) << 32) |
ModHash[1]); // Take the first 64 bits
- return NewName.str();
+ return std::string(NewName.str());
}
/// Helper to obtain the unpromoted name for a global value (or the original
@@ -1310,7 +1415,7 @@ public:
if (It->second.first == TypeId)
return It->second.second;
auto It = TypeIdMap.insert(
- {GlobalValue::getGUID(TypeId), {TypeId, TypeIdSummary()}});
+ {GlobalValue::getGUID(TypeId), {std::string(TypeId), TypeIdSummary()}});
return It->second.second;
}
@@ -1330,8 +1435,7 @@ public:
TypeId));
}
- const std::map<std::string, TypeIdCompatibleVtableInfo> &
- typeIdCompatibleVtableMap() const {
+ const auto &typeIdCompatibleVtableMap() const {
return TypeIdCompatibleVtableMap;
}
@@ -1340,7 +1444,7 @@ public:
/// the ThinLTO backends.
TypeIdCompatibleVtableInfo &
getOrInsertTypeIdCompatibleVtableSummary(StringRef TypeId) {
- return TypeIdCompatibleVtableMap[TypeId];
+ return TypeIdCompatibleVtableMap[std::string(TypeId)];
}
/// For the given \p TypeId, this returns the TypeIdCompatibleVtableMap
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h b/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
index 4d4a67c75172..f7fa16df1100 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ModuleSummaryIndexYAML.h
@@ -17,6 +17,7 @@ namespace yaml {
template <> struct ScalarEnumerationTraits<TypeTestResolution::Kind> {
static void enumeration(IO &io, TypeTestResolution::Kind &value) {
+ io.enumCase(value, "Unknown", TypeTestResolution::Unknown);
io.enumCase(value, "Unsat", TypeTestResolution::Unsat);
io.enumCase(value, "ByteArray", TypeTestResolution::ByteArray);
io.enumCase(value, "Inline", TypeTestResolution::Inline);
@@ -223,13 +224,15 @@ template <> struct CustomMappingTraits<GlobalValueSummaryMapTy> {
Elem.SummaryList.push_back(std::make_unique<FunctionSummary>(
GlobalValueSummary::GVFlags(
static_cast<GlobalValue::LinkageTypes>(FSum.Linkage),
- FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal, FSum.CanAutoHide),
+ FSum.NotEligibleToImport, FSum.Live, FSum.IsLocal,
+ FSum.CanAutoHide),
/*NumInsts=*/0, FunctionSummary::FFlags{}, /*EntryCount=*/0, Refs,
ArrayRef<FunctionSummary::EdgeTy>{}, std::move(FSum.TypeTests),
std::move(FSum.TypeTestAssumeVCalls),
std::move(FSum.TypeCheckedLoadVCalls),
std::move(FSum.TypeTestAssumeConstVCalls),
- std::move(FSum.TypeCheckedLoadConstVCalls)));
+ std::move(FSum.TypeCheckedLoadConstVCalls),
+ ArrayRef<FunctionSummary::ParamAccess>{}));
}
}
static void output(IO &io, GlobalValueSummaryMapTy &V) {
@@ -262,7 +265,7 @@ template <> struct CustomMappingTraits<TypeIdSummaryMapTy> {
static void inputOne(IO &io, StringRef Key, TypeIdSummaryMapTy &V) {
TypeIdSummary TId;
io.mapRequired(Key.str().c_str(), TId);
- V.insert({GlobalValue::getGUID(Key), {Key, TId}});
+ V.insert({GlobalValue::getGUID(Key), {std::string(Key), TId}});
}
static void output(IO &io, TypeIdSummaryMapTy &V) {
for (auto TidIter = V.begin(); TidIter != V.end(); TidIter++)
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/NoFolder.h b/contrib/llvm-project/llvm/include/llvm/IR/NoFolder.h
index 835236b1eac0..dcffa6b2f9da 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/NoFolder.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/NoFolder.h
@@ -26,11 +26,14 @@
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
/// NoFolder - Create "constants" (actually, instructions) with no folding.
-class NoFolder {
+class NoFolder final : public IRBuilderFolder {
+ virtual void anchor();
+
public:
explicit NoFolder() = default;
@@ -39,105 +42,76 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateAdd(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false,
+ bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateAdd(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
- Instruction *CreateNSWAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWAdd(LHS, RHS);
- }
-
- Instruction *CreateNUWAdd(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWAdd(LHS, RHS);
- }
-
- Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFAdd(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFAdd(LHS, RHS);
}
Instruction *CreateSub(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false,
+ bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateSub(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
- Instruction *CreateNSWSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWSub(LHS, RHS);
- }
-
- Instruction *CreateNUWSub(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWSub(LHS, RHS);
- }
-
- Instruction *CreateFSub(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFSub(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFSub(LHS, RHS);
}
Instruction *CreateMul(Constant *LHS, Constant *RHS,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false,
+ bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateMul(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
- Instruction *CreateNSWMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNSWMul(LHS, RHS);
- }
-
- Instruction *CreateNUWMul(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateNUWMul(LHS, RHS);
- }
-
- Instruction *CreateFMul(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFMul(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFMul(LHS, RHS);
}
Instruction *CreateUDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateUDiv(LHS, RHS);
return BinaryOperator::CreateExactUDiv(LHS, RHS);
}
- Instruction *CreateExactUDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateExactUDiv(LHS, RHS);
- }
-
Instruction *CreateSDiv(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateSDiv(LHS, RHS);
return BinaryOperator::CreateExactSDiv(LHS, RHS);
}
- Instruction *CreateExactSDiv(Constant *LHS, Constant *RHS) const {
- return BinaryOperator::CreateExactSDiv(LHS, RHS);
- }
-
- Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFDiv(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFDiv(LHS, RHS);
}
- Instruction *CreateURem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateURem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateURem(LHS, RHS);
}
- Instruction *CreateSRem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateSRem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateSRem(LHS, RHS);
}
- Instruction *CreateFRem(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateFRem(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateFRem(LHS, RHS);
}
Instruction *CreateShl(Constant *LHS, Constant *RHS, bool HasNUW = false,
- bool HasNSW = false) const {
+ bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateShl(LHS, RHS);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
@@ -145,33 +119,33 @@ public:
}
Instruction *CreateLShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateLShr(LHS, RHS);
return BinaryOperator::CreateExactLShr(LHS, RHS);
}
Instruction *CreateAShr(Constant *LHS, Constant *RHS,
- bool isExact = false) const {
+ bool isExact = false) const override {
if (!isExact)
return BinaryOperator::CreateAShr(LHS, RHS);
return BinaryOperator::CreateExactAShr(LHS, RHS);
}
- Instruction *CreateAnd(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateAnd(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateAnd(LHS, RHS);
}
- Instruction *CreateOr(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateOr(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateOr(LHS, RHS);
}
- Instruction *CreateXor(Constant *LHS, Constant *RHS) const {
+ Instruction *CreateXor(Constant *LHS, Constant *RHS) const override {
return BinaryOperator::CreateXor(LHS, RHS);
}
Instruction *CreateBinOp(Instruction::BinaryOps Opc,
- Constant *LHS, Constant *RHS) const {
+ Constant *LHS, Constant *RHS) const override {
return BinaryOperator::Create(Opc, LHS, RHS);
}
@@ -180,30 +154,24 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateNeg(Constant *C,
- bool HasNUW = false, bool HasNSW = false) const {
+ bool HasNUW = false,
+ bool HasNSW = false) const override {
BinaryOperator *BO = BinaryOperator::CreateNeg(C);
if (HasNUW) BO->setHasNoUnsignedWrap();
if (HasNSW) BO->setHasNoSignedWrap();
return BO;
}
- Instruction *CreateNSWNeg(Constant *C) const {
- return BinaryOperator::CreateNSWNeg(C);
- }
-
- Instruction *CreateNUWNeg(Constant *C) const {
- return BinaryOperator::CreateNUWNeg(C);
- }
-
- Instruction *CreateFNeg(Constant *C) const {
+ Instruction *CreateFNeg(Constant *C) const override {
return UnaryOperator::CreateFNeg(C);
}
- Instruction *CreateNot(Constant *C) const {
+ Instruction *CreateNot(Constant *C) const override {
return BinaryOperator::CreateNot(C);
}
- Instruction *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const {
+ Instruction *CreateUnOp(Instruction::UnaryOps Opc,
+ Constant *C) const override {
return UnaryOperator::Create(Opc, C);
}
@@ -212,11 +180,12 @@ public:
//===--------------------------------------------------------------------===//
Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
}
- Constant *CreateGetElementPtr(Type *Ty, Constant *C, Constant *Idx) const {
+ Constant *CreateGetElementPtr(Type *Ty, Constant *C,
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
@@ -224,25 +193,25 @@ public:
}
Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ ArrayRef<Value *> IdxList) const override {
return GetElementPtrInst::Create(Ty, C, IdxList);
}
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const {
+ Constant *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const {
+ Constant *Idx) const override {
// This form of the function only exists to avoid ambiguous overload
// warnings about whether to convert Idx to ArrayRef<Constant *> or
// ArrayRef<Value *>.
return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
}
- Instruction *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const {
+ Instruction *CreateInBoundsGetElementPtr(
+ Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
}
@@ -251,44 +220,49 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateCast(Instruction::CastOps Op, Constant *C,
- Type *DestTy) const {
+ Type *DestTy) const override {
return CastInst::Create(Op, C, DestTy);
}
- Instruction *CreatePointerCast(Constant *C, Type *DestTy) const {
+ Instruction *CreatePointerCast(Constant *C, Type *DestTy) const override {
return CastInst::CreatePointerCast(C, DestTy);
}
+ Instruction *CreatePointerBitCastOrAddrSpaceCast(
+ Constant *C, Type *DestTy) const override {
+ return CastInst::CreatePointerBitCastOrAddrSpaceCast(C, DestTy);
+ }
+
Instruction *CreateIntCast(Constant *C, Type *DestTy,
- bool isSigned) const {
+ bool isSigned) const override {
return CastInst::CreateIntegerCast(C, DestTy, isSigned);
}
- Instruction *CreateFPCast(Constant *C, Type *DestTy) const {
+ Instruction *CreateFPCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateFPCast(C, DestTy);
}
- Instruction *CreateBitCast(Constant *C, Type *DestTy) const {
+ Instruction *CreateBitCast(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::BitCast, C, DestTy);
}
- Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const {
+ Instruction *CreateIntToPtr(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::IntToPtr, C, DestTy);
}
- Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const {
+ Instruction *CreatePtrToInt(Constant *C, Type *DestTy) const override {
return CreateCast(Instruction::PtrToInt, C, DestTy);
}
- Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const {
+ Instruction *CreateZExtOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateZExtOrBitCast(C, DestTy);
}
- Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const {
+ Instruction *CreateSExtOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateSExtOrBitCast(C, DestTy);
}
- Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const {
+ Instruction *CreateTruncOrBitCast(Constant *C, Type *DestTy) const override {
return CastInst::CreateTruncOrBitCast(C, DestTy);
}
@@ -297,12 +271,12 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateICmp(CmpInst::Predicate P,
- Constant *LHS, Constant *RHS) const {
+ Constant *LHS, Constant *RHS) const override {
return new ICmpInst(P, LHS, RHS);
}
Instruction *CreateFCmp(CmpInst::Predicate P,
- Constant *LHS, Constant *RHS) const {
+ Constant *LHS, Constant *RHS) const override {
return new FCmpInst(P, LHS, RHS);
}
@@ -311,31 +285,32 @@ public:
//===--------------------------------------------------------------------===//
Instruction *CreateSelect(Constant *C,
- Constant *True, Constant *False) const {
+ Constant *True, Constant *False) const override {
return SelectInst::Create(C, True, False);
}
- Instruction *CreateExtractElement(Constant *Vec, Constant *Idx) const {
+ Instruction *CreateExtractElement(Constant *Vec,
+ Constant *Idx) const override {
return ExtractElementInst::Create(Vec, Idx);
}
Instruction *CreateInsertElement(Constant *Vec, Constant *NewElt,
- Constant *Idx) const {
+ Constant *Idx) const override {
return InsertElementInst::Create(Vec, NewElt, Idx);
}
Instruction *CreateShuffleVector(Constant *V1, Constant *V2,
- Constant *Mask) const {
+ ArrayRef<int> Mask) const override {
return new ShuffleVectorInst(V1, V2, Mask);
}
Instruction *CreateExtractValue(Constant *Agg,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return ExtractValueInst::Create(Agg, IdxList);
}
Instruction *CreateInsertValue(Constant *Agg, Constant *Val,
- ArrayRef<unsigned> IdxList) const {
+ ArrayRef<unsigned> IdxList) const override {
return InsertValueInst::Create(Agg, Val, IdxList);
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Operator.h b/contrib/llvm-project/llvm/include/llvm/IR/Operator.h
index 35e08d9215e2..acfacbd6c74e 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Operator.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Operator.h
@@ -545,15 +545,29 @@ public:
});
}
+ /// Compute the maximum alignment that this GEP is garranteed to preserve.
+ Align getMaxPreservedAlignment(const DataLayout &DL) const;
+
/// Accumulate the constant address offset of this GEP if possible.
///
- /// This routine accepts an APInt into which it will accumulate the constant
- /// offset of this GEP if the GEP is in fact constant. If the GEP is not
- /// all-constant, it returns false and the value of the offset APInt is
- /// undefined (it is *not* preserved!). The APInt passed into this routine
- /// must be at exactly as wide as the IntPtr type for the address space of the
- /// base GEP pointer.
- bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
+ /// This routine accepts an APInt into which it will try to accumulate the
+ /// constant offset of this GEP.
+ ///
+ /// If \p ExternalAnalysis is provided it will be used to calculate a offset
+ /// when a operand of GEP is not constant.
+ /// For example, for a value \p ExternalAnalysis might try to calculate a
+ /// lower bound. If \p ExternalAnalysis is successful, it should return true.
+ ///
+ /// If the \p ExternalAnalysis returns false or the value returned by \p
+ /// ExternalAnalysis results in a overflow/underflow, this routine returns
+ /// false and the value of the offset APInt is undefined (it is *not*
+ /// preserved!).
+ ///
+ /// The APInt passed into this routine must be at exactly as wide as the
+ /// IntPtr type for the address space of the base GEP pointer.
+ bool accumulateConstantOffset(
+ const DataLayout &DL, APInt &Offset,
+ function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
};
class PtrToIntOperator
@@ -599,6 +613,25 @@ public:
}
};
+class AddrSpaceCastOperator
+ : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
+ friend class AddrSpaceCastInst;
+ friend class ConstantExpr;
+
+public:
+ Value *getPointerOperand() { return getOperand(0); }
+
+ const Value *getPointerOperand() const { return getOperand(0); }
+
+ unsigned getSrcAddressSpace() const {
+ return getPointerOperand()->getType()->getPointerAddressSpace();
+ }
+
+ unsigned getDestAddressSpace() const {
+ return getType()->getPointerAddressSpace();
+ }
+};
+
} // end namespace llvm
#endif // LLVM_IR_OPERATOR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/PassInstrumentation.h b/contrib/llvm-project/llvm/include/llvm/IR/PassInstrumentation.h
index f8a1196871cf..bcc434548e67 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/PassInstrumentation.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/PassInstrumentation.h
@@ -56,12 +56,12 @@
#include "llvm/ADT/Any.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/TypeName.h"
#include <type_traits>
namespace llvm {
class PreservedAnalyses;
+class StringRef;
/// This class manages callbacks registration, as well as provides a way for
/// PassInstrumentation to pass control to the registered callbacks.
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h b/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h
index 58591ab380cc..4d5f292ba9a1 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/PassManager.h
@@ -47,8 +47,8 @@
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/TypeName.h"
-#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstring>
@@ -503,9 +503,6 @@ public:
for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) {
auto *P = Passes[Idx].get();
- if (DebugLogging)
- dbgs() << "Running pass: " << P->name() << " on " << IR.getName()
- << "\n";
// Check the PassInstrumentation's BeforePass callbacks before running the
// pass, skip its execution completely if asked to (callback returns
@@ -513,7 +510,15 @@ public:
if (!PI.runBeforePass<IRUnitT>(*P, IR))
continue;
- PreservedAnalyses PassPA = P->run(IR, AM, ExtraArgs...);
+ if (DebugLogging)
+ dbgs() << "Running pass: " << P->name() << " on " << IR.getName()
+ << "\n";
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(P->name(), IR.getName());
+ PassPA = P->run(IR, AM, ExtraArgs...);
+ }
// Call onto PassInstrumentation's AfterPass callbacks immediately after
// running the pass.
@@ -727,9 +732,9 @@ public:
/// Construct an empty analysis manager.
///
/// If \p DebugLogging is true, we'll log our progress to llvm::dbgs().
- AnalysisManager(bool DebugLogging = false) : DebugLogging(DebugLogging) {}
- AnalysisManager(AnalysisManager &&) = default;
- AnalysisManager &operator=(AnalysisManager &&) = default;
+ AnalysisManager(bool DebugLogging = false);
+ AnalysisManager(AnalysisManager &&);
+ AnalysisManager &operator=(AnalysisManager &&);
/// Returns true if the analysis manager has an empty results cache.
bool empty() const {
@@ -744,20 +749,7 @@ public:
/// This doesn't invalidate, but instead simply deletes, the relevant results.
/// It is useful when the IR is being removed and we want to clear out all the
/// memory pinned for it.
- void clear(IRUnitT &IR, llvm::StringRef Name) {
- if (DebugLogging)
- dbgs() << "Clearing all analysis results for: " << Name << "\n";
-
- auto ResultsListI = AnalysisResultLists.find(&IR);
- if (ResultsListI == AnalysisResultLists.end())
- return;
- // Delete the map entries that point into the results list.
- for (auto &IDAndResult : ResultsListI->second)
- AnalysisResults.erase({IDAndResult.first, &IR});
-
- // And actually destroy and erase the results associated with this IR.
- AnalysisResultLists.erase(ResultsListI);
- }
+ void clear(IRUnitT &IR, llvm::StringRef Name);
/// Clear all analysis results cached by this AnalysisManager.
///
@@ -808,6 +800,16 @@ public:
return &static_cast<ResultModelT *>(ResultConcept)->Result;
}
+ /// Verify that the given Result cannot be invalidated, assert otherwise.
+ template <typename PassT>
+ void verifyNotInvalidated(IRUnitT &IR, typename PassT::Result *Result) const {
+ PreservedAnalyses PA = PreservedAnalyses::none();
+ SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
+ Invalidator Inv(IsResultInvalidated, AnalysisResults);
+ assert(!Result->invalidate(IR, PA, Inv) &&
+ "Cached result cannot be invalidated");
+ }
+
/// Register an analysis pass with the manager.
///
/// The parameter is a callable whose result is an analysis pass. This allows
@@ -856,67 +858,7 @@ public:
///
/// Walk through all of the analyses pertaining to this unit of IR and
/// invalidate them, unless they are preserved by the PreservedAnalyses set.
- void invalidate(IRUnitT &IR, const PreservedAnalyses &PA) {
- // We're done if all analyses on this IR unit are preserved.
- if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
- return;
-
- if (DebugLogging)
- dbgs() << "Invalidating all non-preserved analyses for: " << IR.getName()
- << "\n";
-
- // Track whether each analysis's result is invalidated in
- // IsResultInvalidated.
- SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
- Invalidator Inv(IsResultInvalidated, AnalysisResults);
- AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
- for (auto &AnalysisResultPair : ResultsList) {
- // This is basically the same thing as Invalidator::invalidate, but we
- // can't call it here because we're operating on the type-erased result.
- // Moreover if we instead called invalidate() directly, it would do an
- // unnecessary look up in ResultsList.
- AnalysisKey *ID = AnalysisResultPair.first;
- auto &Result = *AnalysisResultPair.second;
-
- auto IMapI = IsResultInvalidated.find(ID);
- if (IMapI != IsResultInvalidated.end())
- // This result was already handled via the Invalidator.
- continue;
-
- // Try to invalidate the result, giving it the Invalidator so it can
- // recursively query for any dependencies it has and record the result.
- // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
- // Result.invalidate may insert things into the map, invalidating our
- // iterator.
- bool Inserted =
- IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)})
- .second;
- (void)Inserted;
- assert(Inserted && "Should never have already inserted this ID, likely "
- "indicates a cycle!");
- }
-
- // Now erase the results that were marked above as invalidated.
- if (!IsResultInvalidated.empty()) {
- for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
- AnalysisKey *ID = I->first;
- if (!IsResultInvalidated.lookup(ID)) {
- ++I;
- continue;
- }
-
- if (DebugLogging)
- dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
- << " on " << IR.getName() << "\n";
-
- I = ResultsList.erase(I);
- AnalysisResults.erase({ID, &IR});
- }
- }
-
- if (ResultsList.empty())
- AnalysisResultLists.erase(&IR);
- }
+ void invalidate(IRUnitT &IR, const PreservedAnalyses &PA);
private:
/// Look up a registered analysis pass.
@@ -937,41 +879,7 @@ private:
/// Get an analysis result, running the pass if necessary.
ResultConceptT &getResultImpl(AnalysisKey *ID, IRUnitT &IR,
- ExtraArgTs... ExtraArgs) {
- typename AnalysisResultMapT::iterator RI;
- bool Inserted;
- std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
- std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
-
- // If we don't have a cached result for this function, look up the pass and
- // run it to produce a result, which we then add to the cache.
- if (Inserted) {
- auto &P = this->lookUpPass(ID);
- if (DebugLogging)
- dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
- << "\n";
-
- PassInstrumentation PI;
- if (ID != PassInstrumentationAnalysis::ID()) {
- PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
- PI.runBeforeAnalysis(P, IR);
- }
-
- AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
- ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
-
- PI.runAfterAnalysis(P, IR);
-
- // P.run may have inserted elements into AnalysisResults and invalidated
- // RI.
- RI = AnalysisResults.find({ID, &IR});
- assert(RI != AnalysisResults.end() && "we just inserted it!");
-
- RI->second = std::prev(ResultList.end());
- }
-
- return *RI->second->second;
- }
+ ExtraArgTs... ExtraArgs);
/// Get a cached analysis result or return null.
ResultConceptT *getCachedResultImpl(AnalysisKey *ID, IRUnitT &IR) const {
@@ -1167,7 +1075,24 @@ public:
public:
explicit Result(const AnalysisManagerT &OuterAM) : OuterAM(&OuterAM) {}
- const AnalysisManagerT &getManager() const { return *OuterAM; }
+ /// Get a cached analysis. If the analysis can be invalidated, this will
+ /// assert.
+ template <typename PassT, typename IRUnitTParam>
+ typename PassT::Result *getCachedResult(IRUnitTParam &IR) const {
+ typename PassT::Result *Res =
+ OuterAM->template getCachedResult<PassT>(IR);
+ if (Res)
+ OuterAM->template verifyNotInvalidated<PassT>(IR, Res);
+ return Res;
+ }
+
+ /// Method provided for unit testing, not intended for general use.
+ template <typename PassT, typename IRUnitTParam>
+ bool cachedResultExists(IRUnitTParam &IR) const {
+ typename PassT::Result *Res =
+ OuterAM->template getCachedResult<PassT>(IR);
+ return Res != nullptr;
+ }
/// When invalidation occurs, remove any registered invalidation events.
bool invalidate(
@@ -1306,7 +1231,12 @@ public:
// false).
if (!PI.runBeforePass<Function>(Pass, F))
continue;
- PreservedAnalyses PassPA = Pass.run(F, FAM);
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass.name(), F.getName());
+ PassPA = Pass.run(F, FAM);
+ }
PI.runAfterPass(Pass, F);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h b/contrib/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h
new file mode 100644
index 000000000000..978655ac69c4
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/PassManagerImpl.h
@@ -0,0 +1,157 @@
+//===- PassManagerImpl.h - Pass management infrastructure -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// Provides implementations for PassManager and AnalysisManager template
+/// methods. These classes should be explicitly instantiated for any IR unit,
+/// and files doing the explicit instantiation should include this header.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_IR_PASSMANAGERIMPL_H
+#define LLVM_IR_PASSMANAGERIMPL_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager(
+ bool DebugLogging)
+ : DebugLogging(DebugLogging) {}
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline AnalysisManager<IRUnitT, ExtraArgTs...>::AnalysisManager(
+ AnalysisManager &&) = default;
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline AnalysisManager<IRUnitT, ExtraArgTs...> &
+AnalysisManager<IRUnitT, ExtraArgTs...>::operator=(AnalysisManager &&) =
+ default;
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline void
+AnalysisManager<IRUnitT, ExtraArgTs...>::clear(IRUnitT &IR,
+ llvm::StringRef Name) {
+ if (DebugLogging)
+ dbgs() << "Clearing all analysis results for: " << Name << "\n";
+
+ auto ResultsListI = AnalysisResultLists.find(&IR);
+ if (ResultsListI == AnalysisResultLists.end())
+ return;
+ // Delete the map entries that point into the results list.
+ for (auto &IDAndResult : ResultsListI->second)
+ AnalysisResults.erase({IDAndResult.first, &IR});
+
+ // And actually destroy and erase the results associated with this IR.
+ AnalysisResultLists.erase(ResultsListI);
+}
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline typename AnalysisManager<IRUnitT, ExtraArgTs...>::ResultConceptT &
+AnalysisManager<IRUnitT, ExtraArgTs...>::getResultImpl(
+ AnalysisKey *ID, IRUnitT &IR, ExtraArgTs... ExtraArgs) {
+ typename AnalysisResultMapT::iterator RI;
+ bool Inserted;
+ std::tie(RI, Inserted) = AnalysisResults.insert(std::make_pair(
+ std::make_pair(ID, &IR), typename AnalysisResultListT::iterator()));
+
+ // If we don't have a cached result for this function, look up the pass and
+ // run it to produce a result, which we then add to the cache.
+ if (Inserted) {
+ auto &P = this->lookUpPass(ID);
+ if (DebugLogging)
+ dbgs() << "Running analysis: " << P.name() << " on " << IR.getName()
+ << "\n";
+
+ PassInstrumentation PI;
+ if (ID != PassInstrumentationAnalysis::ID()) {
+ PI = getResult<PassInstrumentationAnalysis>(IR, ExtraArgs...);
+ PI.runBeforeAnalysis(P, IR);
+ }
+
+ AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
+ ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...));
+
+ PI.runAfterAnalysis(P, IR);
+
+ // P.run may have inserted elements into AnalysisResults and invalidated
+ // RI.
+ RI = AnalysisResults.find({ID, &IR});
+ assert(RI != AnalysisResults.end() && "we just inserted it!");
+
+ RI->second = std::prev(ResultList.end());
+ }
+
+ return *RI->second->second;
+}
+
+template <typename IRUnitT, typename... ExtraArgTs>
+inline void AnalysisManager<IRUnitT, ExtraArgTs...>::invalidate(
+ IRUnitT &IR, const PreservedAnalyses &PA) {
+ // We're done if all analyses on this IR unit are preserved.
+ if (PA.allAnalysesInSetPreserved<AllAnalysesOn<IRUnitT>>())
+ return;
+
+ if (DebugLogging)
+ dbgs() << "Invalidating all non-preserved analyses for: " << IR.getName()
+ << "\n";
+
+ // Track whether each analysis's result is invalidated in
+ // IsResultInvalidated.
+ SmallDenseMap<AnalysisKey *, bool, 8> IsResultInvalidated;
+ Invalidator Inv(IsResultInvalidated, AnalysisResults);
+ AnalysisResultListT &ResultsList = AnalysisResultLists[&IR];
+ for (auto &AnalysisResultPair : ResultsList) {
+ // This is basically the same thing as Invalidator::invalidate, but we
+ // can't call it here because we're operating on the type-erased result.
+ // Moreover if we instead called invalidate() directly, it would do an
+ // unnecessary look up in ResultsList.
+ AnalysisKey *ID = AnalysisResultPair.first;
+ auto &Result = *AnalysisResultPair.second;
+
+ auto IMapI = IsResultInvalidated.find(ID);
+ if (IMapI != IsResultInvalidated.end())
+ // This result was already handled via the Invalidator.
+ continue;
+
+ // Try to invalidate the result, giving it the Invalidator so it can
+ // recursively query for any dependencies it has and record the result.
+ // Note that we cannot reuse 'IMapI' here or pre-insert the ID, as
+ // Result.invalidate may insert things into the map, invalidating our
+ // iterator.
+ bool Inserted =
+ IsResultInvalidated.insert({ID, Result.invalidate(IR, PA, Inv)}).second;
+ (void)Inserted;
+ assert(Inserted && "Should never have already inserted this ID, likely "
+ "indicates a cycle!");
+ }
+
+ // Now erase the results that were marked above as invalidated.
+ if (!IsResultInvalidated.empty()) {
+ for (auto I = ResultsList.begin(), E = ResultsList.end(); I != E;) {
+ AnalysisKey *ID = I->first;
+ if (!IsResultInvalidated.lookup(ID)) {
+ ++I;
+ continue;
+ }
+
+ if (DebugLogging)
+ dbgs() << "Invalidating analysis: " << this->lookUpPass(ID).name()
+ << " on " << IR.getName() << "\n";
+
+ I = ResultsList.erase(I);
+ AnalysisResults.erase({ID, &IR});
+ }
+ }
+
+ if (ResultsList.empty())
+ AnalysisResultLists.erase(&IR);
+}
+} // end namespace llvm
+
+#endif // LLVM_IR_PASSMANAGERIMPL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/PassTimingInfo.h b/contrib/llvm-project/llvm/include/llvm/IR/PassTimingInfo.h
index b8d8f117f73d..b70850fd64d7 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/PassTimingInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/PassTimingInfo.h
@@ -55,11 +55,9 @@ class TimePassesHandler {
/// A group of all pass-timing timers.
TimerGroup TG;
+ using TimerVector = llvm::SmallVector<std::unique_ptr<Timer>, 4>;
/// Map of timers for pass invocations
- DenseMap<PassInvocationID, std::unique_ptr<Timer>> TimingData;
-
- /// Map that counts invocations of passes, for use in UniqPassID construction.
- StringMap<unsigned> PassIDCountMap;
+ StringMap<TimerVector> TimingData;
/// Stack of currently active timers.
SmallVector<Timer *, 8> TimerStack;
@@ -96,9 +94,6 @@ private:
/// Returns the new timer for each new run of the pass.
Timer &getPassTimer(StringRef PassID);
- /// Returns the incremented counter for the next invocation of \p PassID.
- unsigned nextPassID(StringRef PassID) { return ++PassIDCountMap[PassID]; }
-
void startTimer(StringRef PassID);
void stopTimer(StringRef PassID);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/PatternMatch.h b/contrib/llvm-project/llvm/include/llvm/IR/PatternMatch.h
index 6621fc9f819c..4c11bc82510b 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/PatternMatch.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/PatternMatch.h
@@ -32,6 +32,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -49,6 +50,10 @@ template <typename Val, typename Pattern> bool match(Val *V, const Pattern &P) {
return const_cast<Pattern &>(P).match(V);
}
+template <typename Pattern> bool match(ArrayRef<int> Mask, const Pattern &P) {
+ return const_cast<Pattern &>(P).match(Mask);
+}
+
template <typename SubPattern_t> struct OneUse_match {
SubPattern_t SubPattern;
@@ -70,6 +75,11 @@ template <typename Class> struct class_match {
/// Match an arbitrary value and ignore it.
inline class_match<Value> m_Value() { return class_match<Value>(); }
+/// Match an arbitrary unary operation and ignore it.
+inline class_match<UnaryOperator> m_UnOp() {
+ return class_match<UnaryOperator>();
+}
+
/// Match an arbitrary binary operation and ignore it.
inline class_match<BinaryOperator> m_BinOp() {
return class_match<BinaryOperator>();
@@ -152,8 +162,10 @@ inline match_combine_and<LTy, RTy> m_CombineAnd(const LTy &L, const RTy &R) {
struct apint_match {
const APInt *&Res;
+ bool AllowUndef;
- apint_match(const APInt *&R) : Res(R) {}
+ apint_match(const APInt *&Res, bool AllowUndef)
+ : Res(Res), AllowUndef(AllowUndef) {}
template <typename ITy> bool match(ITy *V) {
if (auto *CI = dyn_cast<ConstantInt>(V)) {
@@ -162,7 +174,8 @@ struct apint_match {
}
if (V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
- if (auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue())) {
+ if (auto *CI = dyn_cast_or_null<ConstantInt>(
+ C->getSplatValue(AllowUndef))) {
Res = &CI->getValue();
return true;
}
@@ -174,7 +187,11 @@ struct apint_match {
// function for both apint/apfloat.
struct apfloat_match {
const APFloat *&Res;
- apfloat_match(const APFloat *&R) : Res(R) {}
+ bool AllowUndef;
+
+ apfloat_match(const APFloat *&Res, bool AllowUndef)
+ : Res(Res), AllowUndef(AllowUndef) {}
+
template <typename ITy> bool match(ITy *V) {
if (auto *CI = dyn_cast<ConstantFP>(V)) {
Res = &CI->getValueAPF();
@@ -182,7 +199,8 @@ struct apfloat_match {
}
if (V->getType()->isVectorTy())
if (const auto *C = dyn_cast<Constant>(V))
- if (auto *CI = dyn_cast_or_null<ConstantFP>(C->getSplatValue())) {
+ if (auto *CI = dyn_cast_or_null<ConstantFP>(
+ C->getSplatValue(AllowUndef))) {
Res = &CI->getValueAPF();
return true;
}
@@ -192,11 +210,37 @@ struct apfloat_match {
/// Match a ConstantInt or splatted ConstantVector, binding the
/// specified pointer to the contained APInt.
-inline apint_match m_APInt(const APInt *&Res) { return Res; }
+inline apint_match m_APInt(const APInt *&Res) {
+ // Forbid undefs by default to maintain previous behavior.
+ return apint_match(Res, /* AllowUndef */ false);
+}
+
+/// Match APInt while allowing undefs in splat vector constants.
+inline apint_match m_APIntAllowUndef(const APInt *&Res) {
+ return apint_match(Res, /* AllowUndef */ true);
+}
+
+/// Match APInt while forbidding undefs in splat vector constants.
+inline apint_match m_APIntForbidUndef(const APInt *&Res) {
+ return apint_match(Res, /* AllowUndef */ false);
+}
/// Match a ConstantFP or splatted ConstantVector, binding the
/// specified pointer to the contained APFloat.
-inline apfloat_match m_APFloat(const APFloat *&Res) { return Res; }
+inline apfloat_match m_APFloat(const APFloat *&Res) {
+ // Forbid undefs by default to maintain previous behavior.
+ return apfloat_match(Res, /* AllowUndef */ false);
+}
+
+/// Match APFloat while allowing undefs in splat vector constants.
+inline apfloat_match m_APFloatAllowUndef(const APFloat *&Res) {
+ return apfloat_match(Res, /* AllowUndef */ true);
+}
+
+/// Match APFloat while forbidding undefs in splat vector constants.
+inline apfloat_match m_APFloatForbidUndef(const APFloat *&Res) {
+ return apfloat_match(Res, /* AllowUndef */ false);
+}
template <int64_t Val> struct constantint_match {
template <typename ITy> bool match(ITy *V) {
@@ -218,20 +262,26 @@ template <int64_t Val> inline constantint_match<Val> m_ConstantInt() {
return constantint_match<Val>();
}
-/// This helper class is used to match scalar and vector integer constants that
-/// satisfy a specified predicate.
-/// For vector constants, undefined elements are ignored.
-template <typename Predicate> struct cst_pred_ty : public Predicate {
+/// This helper class is used to match constant scalars, vector splats,
+/// and fixed width vectors that satisfy a specified predicate.
+/// For fixed width vector constants, undefined elements are ignored.
+template <typename Predicate, typename ConstantVal>
+struct cstval_pred_ty : public Predicate {
template <typename ITy> bool match(ITy *V) {
- if (const auto *CI = dyn_cast<ConstantInt>(V))
- return this->isValue(CI->getValue());
- if (V->getType()->isVectorTy()) {
+ if (const auto *CV = dyn_cast<ConstantVal>(V))
+ return this->isValue(CV->getValue());
+ if (const auto *VTy = dyn_cast<VectorType>(V->getType())) {
if (const auto *C = dyn_cast<Constant>(V)) {
- if (const auto *CI = dyn_cast_or_null<ConstantInt>(C->getSplatValue()))
- return this->isValue(CI->getValue());
+ if (const auto *CV = dyn_cast_or_null<ConstantVal>(C->getSplatValue()))
+ return this->isValue(CV->getValue());
+
+ // Number of elements of a scalable vector unknown at compile time
+ auto *FVTy = dyn_cast<FixedVectorType>(VTy);
+ if (!FVTy)
+ return false;
// Non-splat vector constant: check each element for a match.
- unsigned NumElts = V->getType()->getVectorNumElements();
+ unsigned NumElts = FVTy->getNumElements();
assert(NumElts != 0 && "Constant vector with no elements?");
bool HasNonUndefElements = false;
for (unsigned i = 0; i != NumElts; ++i) {
@@ -240,8 +290,8 @@ template <typename Predicate> struct cst_pred_ty : public Predicate {
return false;
if (isa<UndefValue>(Elt))
continue;
- auto *CI = dyn_cast<ConstantInt>(Elt);
- if (!CI || !this->isValue(CI->getValue()))
+ auto *CV = dyn_cast<ConstantVal>(Elt);
+ if (!CV || !this->isValue(CV->getValue()))
return false;
HasNonUndefElements = true;
}
@@ -252,6 +302,14 @@ template <typename Predicate> struct cst_pred_ty : public Predicate {
}
};
+/// specialization of cstval_pred_ty for ConstantInt
+template <typename Predicate>
+using cst_pred_ty = cstval_pred_ty<Predicate, ConstantInt>;
+
+/// specialization of cstval_pred_ty for ConstantFP
+template <typename Predicate>
+using cstfp_pred_ty = cstval_pred_ty<Predicate, ConstantFP>;
+
/// This helper class is used to match scalar and vector constants that
/// satisfy a specified predicate, and bind them to an APInt.
template <typename Predicate> struct api_pred_ty : public Predicate {
@@ -277,40 +335,6 @@ template <typename Predicate> struct api_pred_ty : public Predicate {
}
};
-/// This helper class is used to match scalar and vector floating-point
-/// constants that satisfy a specified predicate.
-/// For vector constants, undefined elements are ignored.
-template <typename Predicate> struct cstfp_pred_ty : public Predicate {
- template <typename ITy> bool match(ITy *V) {
- if (const auto *CF = dyn_cast<ConstantFP>(V))
- return this->isValue(CF->getValueAPF());
- if (V->getType()->isVectorTy()) {
- if (const auto *C = dyn_cast<Constant>(V)) {
- if (const auto *CF = dyn_cast_or_null<ConstantFP>(C->getSplatValue()))
- return this->isValue(CF->getValueAPF());
-
- // Non-splat vector constant: check each element for a match.
- unsigned NumElts = V->getType()->getVectorNumElements();
- assert(NumElts != 0 && "Constant vector with no elements?");
- bool HasNonUndefElements = false;
- for (unsigned i = 0; i != NumElts; ++i) {
- Constant *Elt = C->getAggregateElement(i);
- if (!Elt)
- return false;
- if (isa<UndefValue>(Elt))
- continue;
- auto *CF = dyn_cast<ConstantFP>(Elt);
- if (!CF || !this->isValue(CF->getValueAPF()))
- return false;
- HasNonUndefElements = true;
- }
- return HasNonUndefElements;
- }
- }
- return false;
- }
-};
-
///////////////////////////////////////////////////////////////////////////////
//
// Encapsulate constant value queries for use in templated predicate matchers.
@@ -418,6 +442,7 @@ inline cst_pred_ty<is_zero_int> m_ZeroInt() {
struct is_zero {
template <typename ITy> bool match(ITy *V) {
auto *C = dyn_cast<Constant>(V);
+ // FIXME: this should be able to do something for scalable vectors
return C && (C->isNullValue() || cst_pred_ty<is_zero_int>().match(C));
}
};
@@ -530,6 +555,15 @@ inline cstfp_pred_ty<is_nan> m_NaN() {
return cstfp_pred_ty<is_nan>();
}
+struct is_inf {
+ bool isValue(const APFloat &C) { return C.isInfinity(); }
+};
+/// Match a positive or negative infinity FP constant.
+/// For vectors, this includes constants with undefined elements.
+inline cstfp_pred_ty<is_inf> m_Inf() {
+ return cstfp_pred_ty<is_inf>();
+}
+
struct is_any_zero_fp {
bool isValue(const APFloat &C) { return C.isZero(); }
};
@@ -579,6 +613,8 @@ inline bind_ty<const Value> m_Value(const Value *&V) { return V; }
/// Match an instruction, capturing it if we match.
inline bind_ty<Instruction> m_Instruction(Instruction *&I) { return I; }
+/// Match a unary operator, capturing it if we match.
+inline bind_ty<UnaryOperator> m_UnOp(UnaryOperator *&I) { return I; }
/// Match a binary operator, capturing it if we match.
inline bind_ty<BinaryOperator> m_BinOp(BinaryOperator *&I) { return I; }
/// Match a with overflow intrinsic, capturing it if we match.
@@ -751,6 +787,26 @@ inline AnyBinaryOp_match<LHS, RHS> m_BinOp(const LHS &L, const RHS &R) {
}
//===----------------------------------------------------------------------===//
+// Matcher for any unary operator.
+// TODO fuse unary, binary matcher into n-ary matcher
+//
+template <typename OP_t> struct AnyUnaryOp_match {
+ OP_t X;
+
+ AnyUnaryOp_match(const OP_t &X) : X(X) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<UnaryOperator>(V))
+ return X.match(I->getOperand(0));
+ return false;
+ }
+};
+
+template <typename OP_t> inline AnyUnaryOp_match<OP_t> m_UnOp(const OP_t &X) {
+ return AnyUnaryOp_match<OP_t>(X);
+}
+
+//===----------------------------------------------------------------------===//
// Matchers for specific binary operators.
//
@@ -1155,13 +1211,16 @@ struct CmpClass_match {
: Predicate(Pred), L(LHS), R(RHS) {}
template <typename OpTy> bool match(OpTy *V) {
- if (auto *I = dyn_cast<Class>(V))
- if ((L.match(I->getOperand(0)) && R.match(I->getOperand(1))) ||
- (Commutable && L.match(I->getOperand(1)) &&
- R.match(I->getOperand(0)))) {
+ if (auto *I = dyn_cast<Class>(V)) {
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
Predicate = I->getPredicate();
return true;
+ } else if (Commutable && L.match(I->getOperand(1)) &&
+ R.match(I->getOperand(0))) {
+ Predicate = I->getSwappedPredicate();
+ return true;
}
+ }
return false;
}
};
@@ -1264,7 +1323,7 @@ inline OneOps_match<OpTy, Instruction::Freeze> m_Freeze(const OpTy &Op) {
/// Matches InsertElementInst.
template <typename Val_t, typename Elt_t, typename Idx_t>
inline ThreeOps_match<Val_t, Elt_t, Idx_t, Instruction::InsertElement>
-m_InsertElement(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx) {
+m_InsertElt(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx) {
return ThreeOps_match<Val_t, Elt_t, Idx_t, Instruction::InsertElement>(
Val, Elt, Idx);
}
@@ -1272,16 +1331,73 @@ m_InsertElement(const Val_t &Val, const Elt_t &Elt, const Idx_t &Idx) {
/// Matches ExtractElementInst.
template <typename Val_t, typename Idx_t>
inline TwoOps_match<Val_t, Idx_t, Instruction::ExtractElement>
-m_ExtractElement(const Val_t &Val, const Idx_t &Idx) {
+m_ExtractElt(const Val_t &Val, const Idx_t &Idx) {
return TwoOps_match<Val_t, Idx_t, Instruction::ExtractElement>(Val, Idx);
}
-/// Matches ShuffleVectorInst.
+/// Matches shuffle.
+template <typename T0, typename T1, typename T2> struct Shuffle_match {
+ T0 Op1;
+ T1 Op2;
+ T2 Mask;
+
+ Shuffle_match(const T0 &Op1, const T1 &Op2, const T2 &Mask)
+ : Op1(Op1), Op2(Op2), Mask(Mask) {}
+
+ template <typename OpTy> bool match(OpTy *V) {
+ if (auto *I = dyn_cast<ShuffleVectorInst>(V)) {
+ return Op1.match(I->getOperand(0)) && Op2.match(I->getOperand(1)) &&
+ Mask.match(I->getShuffleMask());
+ }
+ return false;
+ }
+};
+
+struct m_Mask {
+ ArrayRef<int> &MaskRef;
+ m_Mask(ArrayRef<int> &MaskRef) : MaskRef(MaskRef) {}
+ bool match(ArrayRef<int> Mask) {
+ MaskRef = Mask;
+ return true;
+ }
+};
+
+struct m_ZeroMask {
+ bool match(ArrayRef<int> Mask) {
+ return all_of(Mask, [](int Elem) { return Elem == 0 || Elem == -1; });
+ }
+};
+
+struct m_SpecificMask {
+ ArrayRef<int> &MaskRef;
+ m_SpecificMask(ArrayRef<int> &MaskRef) : MaskRef(MaskRef) {}
+ bool match(ArrayRef<int> Mask) { return MaskRef == Mask; }
+};
+
+struct m_SplatOrUndefMask {
+ int &SplatIndex;
+ m_SplatOrUndefMask(int &SplatIndex) : SplatIndex(SplatIndex) {}
+ bool match(ArrayRef<int> Mask) {
+ auto First = find_if(Mask, [](int Elem) { return Elem != -1; });
+ if (First == Mask.end())
+ return false;
+ SplatIndex = *First;
+ return all_of(Mask,
+ [First](int Elem) { return Elem == *First || Elem == -1; });
+ }
+};
+
+/// Matches ShuffleVectorInst independently of mask value.
+template <typename V1_t, typename V2_t>
+inline TwoOps_match<V1_t, V2_t, Instruction::ShuffleVector>
+m_Shuffle(const V1_t &v1, const V2_t &v2) {
+ return TwoOps_match<V1_t, V2_t, Instruction::ShuffleVector>(v1, v2);
+}
+
template <typename V1_t, typename V2_t, typename Mask_t>
-inline ThreeOps_match<V1_t, V2_t, Mask_t, Instruction::ShuffleVector>
-m_ShuffleVector(const V1_t &v1, const V2_t &v2, const Mask_t &m) {
- return ThreeOps_match<V1_t, V2_t, Mask_t, Instruction::ShuffleVector>(v1, v2,
- m);
+inline Shuffle_match<V1_t, V2_t, Mask_t>
+m_Shuffle(const V1_t &v1, const V2_t &v2, const Mask_t &mask) {
+ return Shuffle_match<V1_t, V2_t, Mask_t>(v1, v2, mask);
}
/// Matches LoadInst.
@@ -1378,25 +1494,31 @@ m_ZExtOrSExtOrSelf(const OpTy &Op) {
return m_CombineOr(m_ZExtOrSExt(Op), Op);
}
-/// Matches UIToFP.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::UIToFP> m_UIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::UIToFP>(Op);
}
-/// Matches SIToFP.
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::SIToFP> m_SIToFP(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::SIToFP>(Op);
}
-/// Matches FPTrunc
+template <typename OpTy>
+inline CastClass_match<OpTy, Instruction::FPToUI> m_FPToUI(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::FPToUI>(Op);
+}
+
+template <typename OpTy>
+inline CastClass_match<OpTy, Instruction::FPToSI> m_FPToSI(const OpTy &Op) {
+ return CastClass_match<OpTy, Instruction::FPToSI>(Op);
+}
+
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPTrunc> m_FPTrunc(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPTrunc>(Op);
}
-/// Matches FPExt
template <typename OpTy>
inline CastClass_match<OpTy, Instruction::FPExt> m_FPExt(const OpTy &Op) {
return CastClass_match<OpTy, Instruction::FPExt>(Op);
@@ -1636,7 +1758,8 @@ m_UnordFMin(const LHS &L, const RHS &R) {
}
//===----------------------------------------------------------------------===//
-// Matchers for overflow check patterns: e.g. (a + b) u< a
+// Matchers for overflow check patterns: e.g. (a + b) u< a, (a ^ -1) <u b
+// Note that S might be matched to other instructions than AddInst.
//
template <typename LHS_t, typename RHS_t, typename Sum_t>
@@ -1667,6 +1790,19 @@ struct UAddWithOverflow_match {
if (AddExpr.match(ICmpRHS) && (ICmpLHS == AddLHS || ICmpLHS == AddRHS))
return L.match(AddLHS) && R.match(AddRHS) && S.match(ICmpRHS);
+ Value *Op1;
+ auto XorExpr = m_OneUse(m_Xor(m_Value(Op1), m_AllOnes()));
+ // (a ^ -1) <u b
+ if (Pred == ICmpInst::ICMP_ULT) {
+ if (XorExpr.match(ICmpLHS))
+ return L.match(Op1) && R.match(ICmpRHS) && S.match(ICmpLHS);
+ }
+ // b > u (a ^ -1)
+ if (Pred == ICmpInst::ICMP_UGT) {
+ if (XorExpr.match(ICmpRHS))
+ return L.match(Op1) && R.match(ICmpLHS) && S.match(ICmpRHS);
+ }
+
// Match special-case for increment-by-1.
if (Pred == ICmpInst::ICMP_EQ) {
// (a + 1) == 0
@@ -1764,6 +1900,12 @@ struct m_Intrinsic_Ty<T0, T1, T2, T3, T4> {
Argument_match<T4>>;
};
+template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
+struct m_Intrinsic_Ty<T0, T1, T2, T3, T4, T5> {
+ using Ty = match_combine_and<typename m_Intrinsic_Ty<T0, T1, T2, T3, T4>::Ty,
+ Argument_match<T5>>;
+};
+
/// Match intrinsic calls like this:
/// m_Intrinsic<Intrinsic::fabs>(m_Value(X))
template <Intrinsic::ID IntrID> inline IntrinsicID_match m_Intrinsic() {
@@ -1803,6 +1945,15 @@ m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3,
m_Argument<4>(Op4));
}
+template <Intrinsic::ID IntrID, typename T0, typename T1, typename T2,
+ typename T3, typename T4, typename T5>
+inline typename m_Intrinsic_Ty<T0, T1, T2, T3, T4, T5>::Ty
+m_Intrinsic(const T0 &Op0, const T1 &Op1, const T2 &Op2, const T3 &Op3,
+ const T4 &Op4, const T5 &Op5) {
+ return m_CombineAnd(m_Intrinsic<IntrID>(Op0, Op1, Op2, Op3, Op4),
+ m_Argument<5>(Op5));
+}
+
// Helper intrinsic matching specializations.
template <typename Opnd0>
inline typename m_Intrinsic_Ty<Opnd0>::Ty m_BitReverse(const Opnd0 &Op0) {
@@ -1847,7 +1998,7 @@ inline AnyBinaryOp_match<LHS, RHS, true> m_c_BinOp(const LHS &L, const RHS &R) {
}
/// Matches an ICmp with a predicate over LHS and RHS in either order.
-/// Does not swap the predicate.
+/// Swaps the predicate if operands are commuted.
template <typename LHS, typename RHS>
inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate, true>
m_c_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
@@ -2002,6 +2153,42 @@ inline ExtractValue_match<Ind, Val_t> m_ExtractValue(const Val_t &V) {
return ExtractValue_match<Ind, Val_t>(V);
}
+/// Matches patterns for `vscale`. This can either be a call to `llvm.vscale` or
+/// the constant expression
+/// `ptrtoint(gep <vscale x 1 x i8>, <vscale x 1 x i8>* null, i32 1>`
+/// under the right conditions determined by DataLayout.
+struct VScaleVal_match {
+private:
+ template <typename Base, typename Offset>
+ inline BinaryOp_match<Base, Offset, Instruction::GetElementPtr>
+ m_OffsetGep(const Base &B, const Offset &O) {
+ return BinaryOp_match<Base, Offset, Instruction::GetElementPtr>(B, O);
+ }
+
+public:
+ const DataLayout &DL;
+ VScaleVal_match(const DataLayout &DL) : DL(DL) {}
+
+ template <typename ITy> bool match(ITy *V) {
+ if (m_Intrinsic<Intrinsic::vscale>().match(V))
+ return true;
+
+ if (m_PtrToInt(m_OffsetGep(m_Zero(), m_SpecificInt(1))).match(V)) {
+ Type *PtrTy = cast<Operator>(V)->getOperand(0)->getType();
+ auto *DerefTy = PtrTy->getPointerElementType();
+ if (isa<ScalableVectorType>(DerefTy) &&
+ DL.getTypeAllocSizeInBits(DerefTy).getKnownMinSize() == 8)
+ return true;
+ }
+
+ return false;
+ }
+};
+
+inline VScaleVal_match m_VScale(const DataLayout &DL) {
+ return VScaleVal_match(DL);
+}
+
} // end namespace PatternMatch
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ProfileSummary.h b/contrib/llvm-project/llvm/include/llvm/IR/ProfileSummary.h
index 78635ec4386c..889568e7946b 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ProfileSummary.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ProfileSummary.h
@@ -14,6 +14,7 @@
#define LLVM_IR_PROFILESUMMARY_H
#include <algorithm>
+#include <cassert>
#include <cstdint>
#include <vector>
@@ -21,6 +22,7 @@ namespace llvm {
class LLVMContext;
class Metadata;
+class raw_ostream;
// The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
// The semantics of counts depend on the type of profile. For instrumentation
@@ -49,6 +51,17 @@ private:
SummaryEntryVector DetailedSummary;
uint64_t TotalCount, MaxCount, MaxInternalCount, MaxFunctionCount;
uint32_t NumCounts, NumFunctions;
+ /// If 'Partial' is false, it means the profile being used to optimize
+ /// a target is collected from the same target.
+ /// If 'Partial' is true, it means the profile is for common/shared
+ /// code. The common profile is usually merged from profiles collected
+ /// from running other targets.
+ bool Partial = false;
+ /// This approximately represents the ratio of the number of profile counters
+ /// of the program being built to the number of profile counters in the
+ /// partial sample profile. When 'Partial' is false, it is undefined. This is
+ /// currently only available under thin LTO mode.
+ double PartialProfileRatio = 0;
/// Return detailed summary as metadata.
Metadata *getDetailedSummaryMD(LLVMContext &Context);
@@ -58,15 +71,18 @@ public:
ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
uint64_t TotalCount, uint64_t MaxCount,
uint64_t MaxInternalCount, uint64_t MaxFunctionCount,
- uint32_t NumCounts, uint32_t NumFunctions)
+ uint32_t NumCounts, uint32_t NumFunctions,
+ bool Partial = false, double PartialProfileRatio = 0)
: PSK(K), DetailedSummary(std::move(DetailedSummary)),
TotalCount(TotalCount), MaxCount(MaxCount),
MaxInternalCount(MaxInternalCount), MaxFunctionCount(MaxFunctionCount),
- NumCounts(NumCounts), NumFunctions(NumFunctions) {}
+ NumCounts(NumCounts), NumFunctions(NumFunctions), Partial(Partial),
+ PartialProfileRatio(PartialProfileRatio) {}
Kind getKind() const { return PSK; }
/// Return summary information as metadata.
- Metadata *getMD(LLVMContext &Context);
+ Metadata *getMD(LLVMContext &Context, bool AddPartialField = true,
+ bool AddPartialProfileRatioField = true);
/// Construct profile summary from metdata.
static ProfileSummary *getFromMD(Metadata *MD);
SummaryEntryVector &getDetailedSummary() { return DetailedSummary; }
@@ -76,6 +92,15 @@ public:
uint64_t getTotalCount() { return TotalCount; }
uint64_t getMaxCount() { return MaxCount; }
uint64_t getMaxInternalCount() { return MaxInternalCount; }
+ void setPartialProfile(bool PP) { Partial = PP; }
+ bool isPartialProfile() { return Partial; }
+ double getPartialProfileRatio() { return PartialProfileRatio; }
+ void setPartialProfileRatio(double R) {
+ assert(isPartialProfile() && "Unexpected when not partial profile");
+ PartialProfileRatio = R;
+ }
+ void printSummary(raw_ostream &OS);
+ void printDetailedSummary(raw_ostream &OS);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/RemarkStreamer.h b/contrib/llvm-project/llvm/include/llvm/IR/RemarkStreamer.h
deleted file mode 100644
index 9ea12e8389f0..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/IR/RemarkStreamer.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===- llvm/IR/RemarkStreamer.h - Remark Streamer ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the main interface for outputting remarks.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_REMARKSTREAMER_H
-#define LLVM_IR_REMARKSTREAMER_H
-
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/Remarks/RemarkSerializer.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/raw_ostream.h"
-#include <string>
-#include <vector>
-
-namespace llvm {
-/// Streamer for remarks.
-class RemarkStreamer {
- /// The regex used to filter remarks based on the passes that emit them.
- Optional<Regex> PassFilter;
- /// The object used to serialize the remarks to a specific format.
- std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer;
- /// The filename that the remark diagnostics are emitted to.
- const Optional<std::string> Filename;
-
- /// Convert diagnostics into remark objects.
- /// The lifetime of the members of the result is bound to the lifetime of
- /// the LLVM diagnostics.
- remarks::Remark toRemark(const DiagnosticInfoOptimizationBase &Diag);
-
-public:
- RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
- Optional<StringRef> Filename = None);
- /// Return the filename that the remark diagnostics are emitted to.
- Optional<StringRef> getFilename() const {
- return Filename ? Optional<StringRef>(*Filename) : None;
- }
- /// Return stream that the remark diagnostics are emitted to.
- raw_ostream &getStream() { return RemarkSerializer->OS; }
- /// Return the serializer used for this stream.
- remarks::RemarkSerializer &getSerializer() { return *RemarkSerializer; }
- /// Set a pass filter based on a regex \p Filter.
- /// Returns an error if the regex is invalid.
- Error setFilter(StringRef Filter);
- /// Emit a diagnostic through the streamer.
- void emit(const DiagnosticInfoOptimizationBase &Diag);
- /// Check if the remarks also need to have associated metadata in a section.
- bool needsSection() const;
-};
-
-template <typename ThisError>
-struct RemarkSetupErrorInfo : public ErrorInfo<ThisError> {
- std::string Msg;
- std::error_code EC;
-
- RemarkSetupErrorInfo(Error E) {
- handleAllErrors(std::move(E), [&](const ErrorInfoBase &EIB) {
- Msg = EIB.message();
- EC = EIB.convertToErrorCode();
- });
- }
-
- void log(raw_ostream &OS) const override { OS << Msg; }
- std::error_code convertToErrorCode() const override { return EC; }
-};
-
-struct RemarkSetupFileError : RemarkSetupErrorInfo<RemarkSetupFileError> {
- static char ID;
- using RemarkSetupErrorInfo<RemarkSetupFileError>::RemarkSetupErrorInfo;
-};
-
-struct RemarkSetupPatternError : RemarkSetupErrorInfo<RemarkSetupPatternError> {
- static char ID;
- using RemarkSetupErrorInfo<RemarkSetupPatternError>::RemarkSetupErrorInfo;
-};
-
-struct RemarkSetupFormatError : RemarkSetupErrorInfo<RemarkSetupFormatError> {
- static char ID;
- using RemarkSetupErrorInfo<RemarkSetupFormatError>::RemarkSetupErrorInfo;
-};
-
-/// Setup optimization remarks that output to a file.
-Expected<std::unique_ptr<ToolOutputFile>>
-setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, StringRef RemarksFormat,
- bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold = 0);
-
-/// Setup optimization remarks that output directly to a raw_ostream.
-/// \p OS is managed by the caller and should be open for writing as long as \p
-/// Context is streaming remarks to it.
-Error setupOptimizationRemarks(LLVMContext &Context, raw_ostream &OS,
- StringRef RemarksPasses, StringRef RemarksFormat,
- bool RemarksWithHotness,
- unsigned RemarksHotnessThreshold = 0);
-
-} // end namespace llvm
-
-#endif // LLVM_IR_REMARKSTREAMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def b/contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def
index fe2c32e3c975..903db6c70498 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def
+++ b/contrib/llvm-project/llvm/include/llvm/IR/RuntimeLibcalls.def
@@ -234,6 +234,11 @@ HANDLE_LIBCALL(ROUND_F64, "round")
HANDLE_LIBCALL(ROUND_F80, "roundl")
HANDLE_LIBCALL(ROUND_F128, "roundl")
HANDLE_LIBCALL(ROUND_PPCF128, "roundl")
+HANDLE_LIBCALL(ROUNDEVEN_F32, "roundevenf")
+HANDLE_LIBCALL(ROUNDEVEN_F64, "roundeven")
+HANDLE_LIBCALL(ROUNDEVEN_F80, "roundevenl")
+HANDLE_LIBCALL(ROUNDEVEN_F128, "roundevenl")
+HANDLE_LIBCALL(ROUNDEVEN_PPCF128, "roundevenl")
HANDLE_LIBCALL(FLOOR_F32, "floorf")
HANDLE_LIBCALL(FLOOR_F64, "floor")
HANDLE_LIBCALL(FLOOR_F80, "floorl")
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Statepoint.h b/contrib/llvm-project/llvm/include/llvm/IR/Statepoint.h
index 89f130bc3351..1ace39c10701 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Statepoint.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Statepoint.h
@@ -55,37 +55,25 @@ enum class StatepointFlags {
class GCRelocateInst;
class GCResultInst;
-bool isStatepoint(const CallBase *Call);
-bool isStatepoint(const Value *V);
-bool isStatepoint(const Value &V);
-
-bool isGCRelocate(const CallBase *Call);
-bool isGCRelocate(const Value *V);
-
-bool isGCResult(const CallBase *Call);
-bool isGCResult(const Value *V);
-
-/// A wrapper around a GC intrinsic call, this provides most of the actual
-/// functionality for Statepoint and ImmutableStatepoint. It is
-/// templatized to allow easily specializing of const and non-const
-/// concrete subtypes.
-template <typename FunTy, typename InstructionTy, typename ValueTy,
- typename CallBaseTy>
-class StatepointBase {
- CallBaseTy *StatepointCall;
+/// Represents a gc.statepoint intrinsic call. This extends directly from
+/// CallBase as the IntrinsicInst only supports calls and gc.statepoint is
+/// invokable.
+class GCStatepointInst : public CallBase {
+public:
+ GCStatepointInst() = delete;
+ GCStatepointInst(const GCStatepointInst &) = delete;
+ GCStatepointInst &operator=(const GCStatepointInst &) = delete;
-protected:
- explicit StatepointBase(InstructionTy *I) {
- StatepointCall = isStatepoint(I) ? cast<CallBaseTy>(I) : nullptr;
+ static bool classof(const CallBase *I) {
+ if (const Function *CF = I->getCalledFunction())
+ return CF->getIntrinsicID() == Intrinsic::experimental_gc_statepoint;
+ return false;
}
- explicit StatepointBase(CallBaseTy *Call) {
- StatepointCall = isStatepoint(Call) ? Call : nullptr;
+ static bool classof(const Value *V) {
+ return isa<CallBase>(V) && classof(cast<CallBase>(V));
}
-public:
- using arg_iterator = typename CallBaseTy::const_op_iterator;
-
enum {
IDPos = 0,
NumPatchBytesPos = 1,
@@ -95,220 +83,172 @@ public:
CallArgsBeginPos = 5,
};
- void *operator new(size_t, unsigned) = delete;
- void *operator new(size_t s) = delete;
-
- explicit operator bool() const {
- // We do not assign non-statepoint call instructions to StatepointCall.
- return (bool)StatepointCall;
- }
-
- /// Return the underlying call instruction.
- CallBaseTy *getCall() const {
- assert(*this && "check validity first!");
- return StatepointCall;
- }
-
- uint64_t getFlags() const {
- return cast<ConstantInt>(getCall()->getArgOperand(FlagsPos))
- ->getZExtValue();
- }
-
/// Return the ID associated with this statepoint.
uint64_t getID() const {
- const Value *IDVal = getCall()->getArgOperand(IDPos);
- return cast<ConstantInt>(IDVal)->getZExtValue();
+ return cast<ConstantInt>(getArgOperand(IDPos))->getZExtValue();
}
/// Return the number of patchable bytes associated with this statepoint.
uint32_t getNumPatchBytes() const {
- const Value *NumPatchBytesVal = getCall()->getArgOperand(NumPatchBytesPos);
+ const Value *NumPatchBytesVal = getArgOperand(NumPatchBytesPos);
uint64_t NumPatchBytes =
cast<ConstantInt>(NumPatchBytesVal)->getZExtValue();
assert(isInt<32>(NumPatchBytes) && "should fit in 32 bits!");
return NumPatchBytes;
}
- /// Return the value actually being called or invoked.
- ValueTy *getCalledValue() const {
- return getCall()->getArgOperand(CalledFunctionPos);
+ /// Number of arguments to be passed to the actual callee.
+ int getNumCallArgs() const {
+ return cast<ConstantInt>(getArgOperand(NumCallArgsPos))->getZExtValue();
}
- // FIXME: Migrate users of this to `getCall` and remove it.
- InstructionTy *getInstruction() const { return getCall(); }
-
- /// Return the function being called if this is a direct call, otherwise
- /// return null (if it's an indirect call).
- FunTy *getCalledFunction() const {
- return dyn_cast<Function>(getCalledValue());
+ uint64_t getFlags() const {
+ return cast<ConstantInt>(getArgOperand(FlagsPos))->getZExtValue();
}
- /// Return the caller function for this statepoint.
- FunTy *getCaller() const { return getCall()->getCaller(); }
+ /// Return the value actually being called or invoked.
+ Value *getActualCalledOperand() const {
+ return getArgOperand(CalledFunctionPos);
+ }
- /// Determine if the statepoint cannot unwind.
- bool doesNotThrow() const {
- Function *F = getCalledFunction();
- return getCall()->doesNotThrow() || (F ? F->doesNotThrow() : false);
+ /// Returns the function called if this is a wrapping a direct call, and null
+ /// otherwise.
+ Function *getActualCalledFunction() const {
+ return dyn_cast_or_null<Function>(getActualCalledOperand());
}
/// Return the type of the value returned by the call underlying the
/// statepoint.
Type *getActualReturnType() const {
- auto *FTy = cast<FunctionType>(
- cast<PointerType>(getCalledValue()->getType())->getElementType());
- return FTy->getReturnType();
+ auto *CalleeTy =
+ cast<PointerType>(getActualCalledOperand()->getType())->getElementType();
+ return cast<FunctionType>(CalleeTy)->getReturnType();
}
- /// Number of arguments to be passed to the actual callee.
- int getNumCallArgs() const {
- const Value *NumCallArgsVal = getCall()->getArgOperand(NumCallArgsPos);
- return cast<ConstantInt>(NumCallArgsVal)->getZExtValue();
- }
- size_t arg_size() const { return getNumCallArgs(); }
- arg_iterator arg_begin() const {
- assert(CallArgsBeginPos <= (int)getCall()->arg_size());
- return getCall()->arg_begin() + CallArgsBeginPos;
+ /// Return the number of arguments to the underlying call.
+ size_t actual_arg_size() const { return getNumCallArgs(); }
+ /// Return an iterator to the begining of the arguments to the underlying call
+ const_op_iterator actual_arg_begin() const {
+ assert(CallArgsBeginPos <= (int)arg_size());
+ return arg_begin() + CallArgsBeginPos;
}
- arg_iterator arg_end() const {
- auto I = arg_begin() + arg_size();
- assert((getCall()->arg_end() - I) >= 0);
+ /// Return an end iterator of the arguments to the underlying call
+ const_op_iterator actual_arg_end() const {
+ auto I = actual_arg_begin() + actual_arg_size();
+ assert((arg_end() - I) >= 0);
return I;
}
-
- ValueTy *getArgument(unsigned Index) {
- assert(Index < arg_size() && "out of bounds!");
- return *(arg_begin() + Index);
+ /// range adapter for actual call arguments
+ iterator_range<const_op_iterator> actual_args() const {
+ return make_range(actual_arg_begin(), actual_arg_end());
}
- /// range adapter for call arguments
- iterator_range<arg_iterator> call_args() const {
- return make_range(arg_begin(), arg_end());
- }
-
- /// Return true if the call or the callee has the given attribute.
- bool paramHasAttr(unsigned i, Attribute::AttrKind A) const {
- Function *F = getCalledFunction();
- return getCall()->paramHasAttr(i + CallArgsBeginPos, A) ||
- (F ? F->getAttributes().hasAttribute(i, A) : false);
- }
-
- /// Number of GC transition args.
- int getNumTotalGCTransitionArgs() const {
- const Value *NumGCTransitionArgs = *arg_end();
- return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
- }
- arg_iterator gc_transition_args_begin() const {
- auto I = arg_end() + 1;
- assert((getCall()->arg_end() - I) >= 0);
+ const_op_iterator gc_transition_args_begin() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
+ return Opt->Inputs.begin();
+ auto I = actual_arg_end() + 1;
+ assert((arg_end() - I) >= 0);
return I;
}
- arg_iterator gc_transition_args_end() const {
- auto I = gc_transition_args_begin() + getNumTotalGCTransitionArgs();
- assert((getCall()->arg_end() - I) >= 0);
+ const_op_iterator gc_transition_args_end() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_gc_transition))
+ return Opt->Inputs.end();
+ auto I = gc_transition_args_begin() + getNumDeoptArgs();
+ assert((arg_end() - I) >= 0);
return I;
}
/// range adapter for GC transition arguments
- iterator_range<arg_iterator> gc_transition_args() const {
+ iterator_range<const_op_iterator> gc_transition_args() const {
return make_range(gc_transition_args_begin(), gc_transition_args_end());
}
- /// Number of additional arguments excluding those intended
- /// for garbage collection.
- int getNumTotalVMSArgs() const {
- const Value *NumVMSArgs = *gc_transition_args_end();
- return cast<ConstantInt>(NumVMSArgs)->getZExtValue();
- }
-
- arg_iterator deopt_begin() const {
- auto I = gc_transition_args_end() + 1;
- assert((getCall()->arg_end() - I) >= 0);
+ const_op_iterator deopt_begin() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
+ return Opt->Inputs.begin();
+ // The current format has two length prefix bundles between call args and
+ // start of gc args. This will be removed in the near future.
+ uint64_t NumTrans = getNumGCTransitionArgs();
+ const_op_iterator I = actual_arg_end() + 2 + NumTrans;
+ assert((arg_end() - I) >= 0);
return I;
}
- arg_iterator deopt_end() const {
- auto I = deopt_begin() + getNumTotalVMSArgs();
- assert((getCall()->arg_end() - I) >= 0);
+ const_op_iterator deopt_end() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_deopt))
+ return Opt->Inputs.end();
+ auto I = deopt_begin() + getNumDeoptArgs();
+ assert((arg_end() - I) >= 0);
return I;
}
/// range adapter for vm state arguments
- iterator_range<arg_iterator> deopt_operands() const {
+ iterator_range<const_op_iterator> deopt_operands() const {
return make_range(deopt_begin(), deopt_end());
}
- arg_iterator gc_args_begin() const { return deopt_end(); }
- arg_iterator gc_args_end() const { return getCall()->arg_end(); }
+ /// Returns an iterator to the begining of the argument range describing gc
+ /// values for the statepoint.
+ const_op_iterator gc_args_begin() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
+ return Opt->Inputs.begin();
+
+ // The current format has two length prefix bundles between call args and
+ // start of gc args. This will be removed in the near future.
+ uint64_t NumTrans = getNumGCTransitionArgs();
+ uint64_t NumDeopt = getNumDeoptArgs();
+ auto I = actual_arg_end() + 2 + NumTrans + NumDeopt;
+ assert((arg_end() - I) >= 0);
+ return I;
+ }
+
+ /// Return an end iterator for the gc argument range
+ const_op_iterator gc_args_end() const {
+ if (auto Opt = getOperandBundle(LLVMContext::OB_gc_live))
+ return Opt->Inputs.end();
+ return arg_end();
+ }
+
+ /// Return the operand index at which the gc args begin
unsigned gcArgsStartIdx() const {
- return gc_args_begin() - getCall()->op_begin();
+ assert(!getOperandBundle(LLVMContext::OB_gc_live));
+ return gc_args_begin() - op_begin();
}
/// range adapter for gc arguments
- iterator_range<arg_iterator> gc_args() const {
+ iterator_range<const_op_iterator> gc_args() const {
return make_range(gc_args_begin(), gc_args_end());
}
+
/// Get list of all gc reloactes linked to this statepoint
/// May contain several relocations for the same base/derived pair.
/// For example this could happen due to relocations on unwinding
/// path of invoke.
- std::vector<const GCRelocateInst *> getRelocates() const;
+ inline std::vector<const GCRelocateInst *> getGCRelocates() const;
- /// Get the experimental_gc_result call tied to this statepoint. Can be
- /// nullptr if there isn't a gc_result tied to this statepoint. Guaranteed to
- /// be a CallInst if non-null.
+ /// Get the experimental_gc_result call tied to this statepoint if there is
+ /// one, otherwise return nullptr.
const GCResultInst *getGCResult() const {
- for (auto *U : getInstruction()->users())
+ for (auto *U : users())
if (auto *GRI = dyn_cast<GCResultInst>(U))
return GRI;
return nullptr;
}
-#ifndef NDEBUG
- /// Asserts if this statepoint is malformed. Common cases for failure
- /// include incorrect length prefixes for variable length sections or
- /// illegal values for parameters.
- void verify() {
- assert(getNumCallArgs() >= 0 &&
- "number of arguments to actually callee can't be negative");
-
- // The internal asserts in the iterator accessors do the rest.
- (void)arg_begin();
- (void)arg_end();
- (void)gc_transition_args_begin();
- (void)gc_transition_args_end();
- (void)deopt_begin();
- (void)deopt_end();
- (void)gc_args_begin();
- (void)gc_args_end();
- }
-#endif
-};
-
-/// A specialization of it's base class for read only access
-/// to a gc.statepoint.
-class ImmutableStatepoint
- : public StatepointBase<const Function, const Instruction, const Value,
- const CallBase> {
- using Base = StatepointBase<const Function, const Instruction, const Value,
- const CallBase>;
-
-public:
- explicit ImmutableStatepoint(const Instruction *I) : Base(I) {}
- explicit ImmutableStatepoint(const CallBase *Call) : Base(Call) {}
-};
-
-/// A specialization of it's base class for read-write access
-/// to a gc.statepoint.
-class Statepoint
- : public StatepointBase<Function, Instruction, Value, CallBase> {
- using Base = StatepointBase<Function, Instruction, Value, CallBase>;
+private:
+ int getNumGCTransitionArgs() const {
+ const Value *NumGCTransitionArgs = *actual_arg_end();
+ return cast<ConstantInt>(NumGCTransitionArgs)->getZExtValue();
+ }
-public:
- explicit Statepoint(Instruction *I) : Base(I) {}
- explicit Statepoint(CallBase *Call) : Base(Call) {}
+ int getNumDeoptArgs() const {
+ uint64_t NumTrans = getNumGCTransitionArgs();
+ const_op_iterator trans_end = actual_arg_end() + 1 + NumTrans;
+ const Value *NumDeoptArgs = *trans_end;
+ return cast<ConstantInt>(NumDeoptArgs)->getZExtValue();
+ }
};
/// Common base class for representing values projected from a statepoint.
@@ -333,15 +273,13 @@ public:
}
/// The statepoint with which this gc.relocate is associated.
- const CallBase *getStatepoint() const {
+ const GCStatepointInst *getStatepoint() const {
const Value *Token = getArgOperand(0);
// This takes care both of relocates for call statepoints and relocates
// on normal path of invoke statepoint.
- if (!isa<LandingPadInst>(Token)) {
- assert(isStatepoint(Token));
- return cast<CallBase>(Token);
- }
+ if (!isa<LandingPadInst>(Token))
+ return cast<GCStatepointInst>(Token);
// This relocate is on exceptional path of an invoke statepoint
const BasicBlock *InvokeBB =
@@ -350,9 +288,8 @@ public:
assert(InvokeBB && "safepoints should have unique landingpads");
assert(InvokeBB->getTerminator() &&
"safepoint block should be well formed");
- assert(isStatepoint(InvokeBB->getTerminator()));
- return cast<CallBase>(InvokeBB->getTerminator());
+ return cast<GCStatepointInst>(InvokeBB->getTerminator());
}
};
@@ -381,10 +318,14 @@ public:
}
Value *getBasePtr() const {
+ if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live))
+ return *(Opt->Inputs.begin() + getBasePtrIndex());
return *(getStatepoint()->arg_begin() + getBasePtrIndex());
}
Value *getDerivedPtr() const {
+ if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live))
+ return *(Opt->Inputs.begin() + getDerivedPtrIndex());
return *(getStatepoint()->arg_begin() + getDerivedPtrIndex());
}
};
@@ -401,21 +342,17 @@ public:
}
};
-template <typename FunTy, typename InstructionTy, typename ValueTy,
- typename CallBaseTy>
-std::vector<const GCRelocateInst *>
-StatepointBase<FunTy, InstructionTy, ValueTy, CallBaseTy>::getRelocates()
- const {
+std::vector<const GCRelocateInst *> GCStatepointInst::getGCRelocates() const {
std::vector<const GCRelocateInst *> Result;
// Search for relocated pointers. Note that working backwards from the
// gc_relocates ensures that we only get pairs which are actually relocated
// and used after the statepoint.
- for (const User *U : StatepointCall->users())
+ for (const User *U : users())
if (auto *Relocate = dyn_cast<GCRelocateInst>(U))
Result.push_back(Relocate);
- auto *StatepointInvoke = dyn_cast<InvokeInst>(StatepointCall);
+ auto *StatepointInvoke = dyn_cast<InvokeInst>(this);
if (!StatepointInvoke)
return Result;
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Type.h b/contrib/llvm-project/llvm/include/llvm/IR/Type.h
index d0961dac833d..1f546884b924 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Type.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Type.h
@@ -53,27 +53,28 @@ public:
/// Also update LLVMTypeKind and LLVMGetTypeKind () in the C binding.
///
enum TypeID {
- // PrimitiveTypes - make sure LastPrimitiveTyID stays up to date.
- VoidTyID = 0, ///< 0: type with no size
- HalfTyID, ///< 1: 16-bit floating point type
- FloatTyID, ///< 2: 32-bit floating point type
- DoubleTyID, ///< 3: 64-bit floating point type
- X86_FP80TyID, ///< 4: 80-bit floating point type (X87)
- FP128TyID, ///< 5: 128-bit floating point type (112-bit mantissa)
- PPC_FP128TyID, ///< 6: 128-bit floating point type (two 64-bits, PowerPC)
- LabelTyID, ///< 7: Labels
- MetadataTyID, ///< 8: Metadata
- X86_MMXTyID, ///< 9: MMX vectors (64 bits, X86 specific)
- TokenTyID, ///< 10: Tokens
+ // PrimitiveTypes
+ HalfTyID = 0, ///< 16-bit floating point type
+ BFloatTyID, ///< 16-bit floating point type (7-bit significand)
+ FloatTyID, ///< 32-bit floating point type
+ DoubleTyID, ///< 64-bit floating point type
+ X86_FP80TyID, ///< 80-bit floating point type (X87)
+ FP128TyID, ///< 128-bit floating point type (112-bit significand)
+ PPC_FP128TyID, ///< 128-bit floating point type (two 64-bits, PowerPC)
+ VoidTyID, ///< type with no size
+ LabelTyID, ///< Labels
+ MetadataTyID, ///< Metadata
+ X86_MMXTyID, ///< MMX vectors (64 bits, X86 specific)
+ TokenTyID, ///< Tokens
// Derived types... see DerivedTypes.h file.
- // Make sure FirstDerivedTyID stays up to date!
- IntegerTyID, ///< 11: Arbitrary bit width integers
- FunctionTyID, ///< 12: Functions
- StructTyID, ///< 13: Structures
- ArrayTyID, ///< 14: Arrays
- PointerTyID, ///< 15: Pointers
- VectorTyID ///< 16: SIMD 'packed' format, or other vector type
+ IntegerTyID, ///< Arbitrary bit width integers
+ FunctionTyID, ///< Functions
+ PointerTyID, ///< Pointers
+ StructTyID, ///< Structures
+ ArrayTyID, ///< Arrays
+ FixedVectorTyID, ///< Fixed width SIMD vector type
+ ScalableVectorTyID ///< Scalable SIMD vector type
};
private:
@@ -110,10 +111,6 @@ protected:
/// Float).
Type * const *ContainedTys = nullptr;
- static bool isSequentialType(TypeID TyID) {
- return TyID == ArrayTyID || TyID == VectorTyID;
- }
-
public:
/// Print the current type.
/// Omit the type details if \p NoDetails == true.
@@ -143,6 +140,9 @@ public:
/// Return true if this is 'half', a 16-bit IEEE fp type.
bool isHalfTy() const { return getTypeID() == HalfTyID; }
+ /// Return true if this is 'bfloat', a 16-bit bfloat type.
+ bool isBFloatTy() const { return getTypeID() == BFloatTyID; }
+
/// Return true if this is 'float', a 32-bit IEEE fp type.
bool isFloatTy() const { return getTypeID() == FloatTyID; }
@@ -160,8 +160,8 @@ public:
/// Return true if this is one of the six floating-point types
bool isFloatingPointTy() const {
- return getTypeID() == HalfTyID || getTypeID() == FloatTyID ||
- getTypeID() == DoubleTyID ||
+ return getTypeID() == HalfTyID || getTypeID() == BFloatTyID ||
+ getTypeID() == FloatTyID || getTypeID() == DoubleTyID ||
getTypeID() == X86_FP80TyID || getTypeID() == FP128TyID ||
getTypeID() == PPC_FP128TyID;
}
@@ -169,6 +169,7 @@ public:
const fltSemantics &getFltSemantics() const {
switch (getTypeID()) {
case HalfTyID: return APFloat::IEEEhalf();
+ case BFloatTyID: return APFloat::BFloat();
case FloatTyID: return APFloat::IEEEsingle();
case DoubleTyID: return APFloat::IEEEdouble();
case X86_FP80TyID: return APFloat::x87DoubleExtended();
@@ -227,7 +228,9 @@ public:
bool isPtrOrPtrVectorTy() const { return getScalarType()->isPointerTy(); }
/// True if this is an instance of VectorType.
- bool isVectorTy() const { return getTypeID() == VectorTyID; }
+ inline bool isVectorTy() const {
+ return getTypeID() == ScalableVectorTyID || getTypeID() == FixedVectorTyID;
+ }
/// Return true if this type could be converted with a lossless BitCast to
/// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
@@ -270,8 +273,7 @@ public:
return true;
// If it is not something that can have a size (e.g. a function or label),
// it doesn't have a size.
- if (getTypeID() != StructTyID && getTypeID() != ArrayTyID &&
- getTypeID() != VectorTyID)
+ if (getTypeID() != StructTyID && getTypeID() != ArrayTyID && !isVectorTy())
return false;
// Otherwise we have to try harder to decide.
return isSizedDerivedType(Visited);
@@ -304,10 +306,10 @@ public:
/// If this is a vector type, return the element type, otherwise return
/// 'this'.
- Type *getScalarType() const {
+ inline Type *getScalarType() const {
if (isVectorTy())
- return getVectorElementType();
- return const_cast<Type*>(this);
+ return getContainedType(0);
+ return const_cast<Type *>(this);
}
//===--------------------------------------------------------------------===//
@@ -343,8 +345,8 @@ public:
//===--------------------------------------------------------------------===//
// Helper methods corresponding to subclass methods. This forces a cast to
- // the specified subclass and calls its accessor. "getVectorNumElements" (for
- // example) is shorthand for cast<VectorType>(Ty)->getNumElements(). This is
+ // the specified subclass and calls its accessor. "getArrayNumElements" (for
+ // example) is shorthand for cast<ArrayType>(Ty)->getNumElements(). This is
// only intended to cover the core methods that are frequently used, helper
// methods should not be added here.
@@ -358,11 +360,6 @@ public:
inline unsigned getStructNumElements() const;
inline Type *getStructElementType(unsigned N) const;
- inline Type *getSequentialElementType() const {
- assert(isSequentialType(getTypeID()) && "Not a sequential type!");
- return ContainedTys[0];
- }
-
inline uint64_t getArrayNumElements() const;
Type *getArrayElementType() const {
@@ -370,14 +367,6 @@ public:
return ContainedTys[0];
}
- inline bool getVectorIsScalable() const;
- inline unsigned getVectorNumElements() const;
- inline ElementCount getVectorElementCount() const;
- Type *getVectorElementType() const {
- assert(getTypeID() == VectorTyID);
- return ContainedTys[0];
- }
-
Type *getPointerElementType() const {
assert(getTypeID() == PointerTyID);
return ContainedTys[0];
@@ -408,6 +397,7 @@ public:
static Type *getVoidTy(LLVMContext &C);
static Type *getLabelTy(LLVMContext &C);
static Type *getHalfTy(LLVMContext &C);
+ static Type *getBFloatTy(LLVMContext &C);
static Type *getFloatTy(LLVMContext &C);
static Type *getDoubleTy(LLVMContext &C);
static Type *getMetadataTy(LLVMContext &C);
@@ -443,6 +433,7 @@ public:
// types as pointee.
//
static PointerType *getHalfPtrTy(LLVMContext &C, unsigned AS = 0);
+ static PointerType *getBFloatPtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getFloatPtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getDoublePtrTy(LLVMContext &C, unsigned AS = 0);
static PointerType *getX86_FP80PtrTy(LLVMContext &C, unsigned AS = 0);
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Use.h b/contrib/llvm-project/llvm/include/llvm/IR/Use.h
index 034ca2c8ac23..917db2679c55 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Use.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Use.h
@@ -41,17 +41,6 @@ class Value;
/// all of the uses for a particular value definition. It also supports jumping
/// directly to the used value when we arrive from the User's operands, and
/// jumping directly to the User when we arrive from the Value's uses.
-///
-/// The pointer to the used Value is explicit, and the pointer to the User is
-/// implicit. The implicit pointer is found via a waymarking algorithm
-/// described in the programmer's manual:
-///
-/// http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
-///
-/// This is essentially the single most memory intensive object in LLVM because
-/// of the number of uses in the system. At the same time, the constant time
-/// operations it allows are essential to many optimizations having reasonable
-/// time complexity.
class Use {
public:
Use(const Use &U) = delete;
@@ -60,34 +49,6 @@ public:
/// that also works with less standard-compliant compilers
void swap(Use &RHS);
- /// Pointer traits for the UserRef PointerIntPair. This ensures we always
- /// use the LSB regardless of pointer alignment on different targets.
- struct UserRefPointerTraits {
- static inline void *getAsVoidPointer(User *P) { return P; }
-
- static inline User *getFromVoidPointer(void *P) {
- return (User *)P;
- }
-
- enum { NumLowBitsAvailable = 1 };
- };
-
- // A type for the word following an array of hung-off Uses in memory, which is
- // a pointer back to their User with the bottom bit set.
- using UserRef = PointerIntPair<User *, 1, unsigned, UserRefPointerTraits>;
-
- /// Pointer traits for the Prev PointerIntPair. This ensures we always use
- /// the two LSBs regardless of pointer alignment on different targets.
- struct PrevPointerTraits {
- static inline void *getAsVoidPointer(Use **P) { return P; }
-
- static inline Use **getFromVoidPointer(void *P) {
- return (Use **)P;
- }
-
- enum { NumLowBitsAvailable = 2 };
- };
-
private:
/// Destructor - Only for zap()
~Use() {
@@ -95,13 +56,12 @@ private:
removeFromList();
}
- enum PrevPtrTag { zeroDigitTag, oneDigitTag, stopTag, fullStopTag };
-
/// Constructor
- Use(PrevPtrTag tag) { Prev.setInt(tag); }
+ Use(User *Parent) : Parent(Parent) {}
public:
friend class Value;
+ friend class User;
operator Value *() const { return Val; }
Value *get() const { return Val; }
@@ -110,7 +70,7 @@ public:
///
/// For an instruction operand, for example, this will return the
/// instruction.
- User *getUser() const LLVM_READONLY;
+ User *getUser() const { return Parent; };
inline void set(Value *Val);
@@ -125,38 +85,29 @@ public:
/// Return the operand # of this use in its User.
unsigned getOperandNo() const;
- /// Initializes the waymarking tags on an array of Uses.
- ///
- /// This sets up the array of Uses such that getUser() can find the User from
- /// any of those Uses.
- static Use *initTags(Use *Start, Use *Stop);
-
/// Destroys Use operands when the number of operands of
/// a User changes.
static void zap(Use *Start, const Use *Stop, bool del = false);
private:
- const Use *getImpliedUser() const LLVM_READONLY;
Value *Val = nullptr;
Use *Next = nullptr;
- PointerIntPair<Use **, 2, PrevPtrTag, PrevPointerTraits> Prev;
-
- void setPrev(Use **NewPrev) { Prev.setPointer(NewPrev); }
+ Use **Prev = nullptr;
+ User *Parent = nullptr;
void addToList(Use **List) {
Next = *List;
if (Next)
- Next->setPrev(&Next);
- setPrev(List);
- *List = this;
+ Next->Prev = &Next;
+ Prev = List;
+ *Prev = this;
}
void removeFromList() {
- Use **StrippedPrev = Prev.getPointer();
- *StrippedPrev = Next;
+ *Prev = Next;
if (Next)
- Next->setPrev(StrippedPrev);
+ Next->Prev = Prev;
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/User.h b/contrib/llvm-project/llvm/include/llvm/IR/User.h
index 850ee72a0387..ebfae1db2980 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/User.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/User.h
@@ -218,6 +218,11 @@ public:
NumUserOperands = NumOps;
}
+ /// A droppable user is a user for which uses can be dropped without affecting
+ /// correctness and should be dropped rather than preventing a transformation
+ /// from happening.
+ bool isDroppable() const;
+
// ---------------------------------------------------------------------------
// Operand Iterator interface...
//
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/VPIntrinsics.def b/contrib/llvm-project/llvm/include/llvm/IR/VPIntrinsics.def
new file mode 100644
index 000000000000..d3e1fc854373
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/IR/VPIntrinsics.def
@@ -0,0 +1,84 @@
+//===-- IR/VPIntrinsics.def - Describes llvm.vp.* Intrinsics -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains descriptions of the various Vector Predication intrinsics.
+// This is used as a central place for enumerating the different instructions
+// and should eventually be the place to put comments about the instructions.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+// Provide definitions of macros so that users of this file do not have to
+// define everything to use it...
+//
+#ifndef REGISTER_VP_INTRINSIC
+#define REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)
+#endif
+
+// Map this VP intrinsic to its functional Opcode
+#ifndef HANDLE_VP_TO_OC
+#define HANDLE_VP_TO_OC(VPID, OC)
+#endif
+
+///// Integer Arithmetic /////
+
+// llvm.vp.add(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_add, 2, 3)
+HANDLE_VP_TO_OC(vp_add, Add)
+
+// llvm.vp.and(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_and, 2, 3)
+HANDLE_VP_TO_OC(vp_and, And)
+
+// llvm.vp.ashr(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_ashr, 2, 3)
+HANDLE_VP_TO_OC(vp_ashr, AShr)
+
+// llvm.vp.lshr(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_lshr, 2, 3)
+HANDLE_VP_TO_OC(vp_lshr, LShr)
+
+// llvm.vp.mul(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_mul, 2, 3)
+HANDLE_VP_TO_OC(vp_mul, Mul)
+
+// llvm.vp.or(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_or, 2, 3)
+HANDLE_VP_TO_OC(vp_or, Or)
+
+// llvm.vp.sdiv(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_sdiv, 2, 3)
+HANDLE_VP_TO_OC(vp_sdiv, SDiv)
+
+// llvm.vp.shl(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_shl, 2, 3)
+HANDLE_VP_TO_OC(vp_shl, Shl)
+
+// llvm.vp.srem(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_srem, 2, 3)
+HANDLE_VP_TO_OC(vp_srem, SRem)
+
+// llvm.vp.sub(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_sub, 2, 3)
+HANDLE_VP_TO_OC(vp_sub, Sub)
+
+// llvm.vp.udiv(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_udiv, 2, 3)
+HANDLE_VP_TO_OC(vp_udiv, UDiv)
+
+// llvm.vp.urem(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_urem, 2, 3)
+HANDLE_VP_TO_OC(vp_urem, URem)
+
+// llvm.vp.xor(x,y,mask,vlen)
+REGISTER_VP_INTRINSIC(vp_xor, 2, 3)
+HANDLE_VP_TO_OC(vp_xor, Xor)
+
+#undef REGISTER_VP_INTRINSIC
+#undef HANDLE_VP_TO_OC
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/Value.h b/contrib/llvm-project/llvm/include/llvm/IR/Value.h
index f2c4b3b3f203..04ca68274626 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/Value.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/Value.h
@@ -72,8 +72,6 @@ using ValueName = StringMapEntry<Value *>;
/// objects that watch it and listen to RAUW and Destroy events. See
/// llvm/IR/ValueHandle.h for details.
class Value {
- // The least-significant bit of the first word of Value *must* be zero:
- // http://www.llvm.org/docs/ProgrammersManual.html#the-waymarking-algorithm
Type *VTy;
Use *UseList;
@@ -444,6 +442,34 @@ public:
/// This is logically equivalent to getNumUses() >= N.
bool hasNUsesOrMore(unsigned N) const;
+ /// Return true if there is exactly one user of this value that cannot be
+ /// dropped.
+ ///
+ /// This is specialized because it is a common request and does not require
+ /// traversing the whole use list.
+ Use *getSingleUndroppableUse();
+
+ /// Return true if there this value.
+ ///
+ /// This is specialized because it is a common request and does not require
+ /// traversing the whole use list.
+ bool hasNUndroppableUses(unsigned N) const;
+
+ /// Return true if this value has N users or more.
+ ///
+ /// This is logically equivalent to getNumUses() >= N.
+ bool hasNUndroppableUsesOrMore(unsigned N) const;
+
+ /// Remove every uses that can safely be removed.
+ ///
+ /// This will remove for example uses in llvm.assume.
+ /// This should be used when performing want to perform a tranformation but
+ /// some Droppable uses pervent it.
+ /// This function optionally takes a filter to only remove some droppable
+ /// uses.
+ void dropDroppableUses(llvm::function_ref<bool(const Use *)> ShouldDrop =
+ [](const Use *) { return true; });
+
/// Check if this value is used in the specified basic block.
bool isUsedInBasicBlock(const BasicBlock *BB) const;
@@ -567,18 +593,23 @@ public:
}
/// Accumulate the constant offset this value has compared to a base pointer.
- /// Only 'getelementptr' instructions (GEPs) with constant indices are
- /// accumulated but other instructions, e.g., casts, are stripped away as
- /// well. The accumulated constant offset is added to \p Offset and the base
+ /// Only 'getelementptr' instructions (GEPs) are accumulated but other
+ /// instructions, e.g., casts, are stripped away as well.
+ /// The accumulated constant offset is added to \p Offset and the base
/// pointer is returned.
///
/// The APInt \p Offset has to have a bit-width equal to the IntPtr type for
/// the address space of 'this' pointer value, e.g., use
/// DataLayout::getIndexTypeSizeInBits(Ty).
///
- /// If \p AllowNonInbounds is true, constant offsets in GEPs are stripped and
+ /// If \p AllowNonInbounds is true, offsets in GEPs are stripped and
/// accumulated even if the GEP is not "inbounds".
///
+ /// If \p ExternalAnalysis is provided it will be used to calculate a offset
+ /// when a operand of GEP is not constant.
+ /// For example, for a value \p ExternalAnalysis might try to calculate a
+ /// lower bound. If \p ExternalAnalysis is successful, it should return true.
+ ///
/// If this is called on a non-pointer value, it returns 'this' and the
/// \p Offset is not modified.
///
@@ -587,9 +618,10 @@ public:
/// between the underlying value and the returned one. Thus, if no constant
/// offset was found, the returned value is the underlying one and \p Offset
/// is unchanged.
- const Value *stripAndAccumulateConstantOffsets(const DataLayout &DL,
- APInt &Offset,
- bool AllowNonInbounds) const;
+ const Value *stripAndAccumulateConstantOffsets(
+ const DataLayout &DL, APInt &Offset, bool AllowNonInbounds,
+ function_ref<bool(Value &Value, APInt &Offset)> ExternalAnalysis =
+ nullptr) const;
Value *stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset,
bool AllowNonInbounds) {
return const_cast<Value *>(
@@ -614,10 +646,12 @@ public:
///
/// Returns the original pointer value. If this is called on a non-pointer
/// value, it returns 'this'.
- const Value *stripInBoundsOffsets() const;
- Value *stripInBoundsOffsets() {
+ const Value *stripInBoundsOffsets(function_ref<void(const Value *)> Func =
+ [](const Value *) {}) const;
+ inline Value *stripInBoundsOffsets(function_ref<void(const Value *)> Func =
+ [](const Value *) {}) {
return const_cast<Value *>(
- static_cast<const Value *>(this)->stripInBoundsOffsets());
+ static_cast<const Value *>(this)->stripInBoundsOffsets(Func));
}
/// Returns the number of bytes known to be dereferenceable for the
@@ -632,7 +666,7 @@ public:
///
/// Returns an alignment which is either specified explicitly, e.g. via
/// align attribute of a function argument, or guaranteed by DataLayout.
- MaybeAlign getPointerAlignment(const DataLayout &DL) const;
+ Align getPointerAlignment(const DataLayout &DL) const;
/// Translate PHI node to its predecessor from the given basic block.
///
@@ -805,7 +839,7 @@ template <class Compare> void Value::sortUseList(Compare Cmp) {
// Fix the Prev pointers.
for (Use *I = UseList, **Prev = &UseList; I; I = I->Next) {
- I->setPrev(Prev);
+ I->Prev = Prev;
Prev = &I->Next;
}
}
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h b/contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h
index 50b7701f6716..badc1ca8d1f6 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h
@@ -89,7 +89,11 @@ public:
}
Value *operator->() const { return getValPtr(); }
- Value &operator*() const { return *getValPtr(); }
+ Value &operator*() const {
+ Value *V = getValPtr();
+ assert(V && "Dereferencing deleted ValueHandle");
+ return *V;
+ }
protected:
Value *getValPtr() const { return Val; }
@@ -303,30 +307,10 @@ public:
ValueTy &operator*() const { return *getValPtr(); }
};
-// Specialize DenseMapInfo to allow AssertingVH to participate in DenseMap.
+// Treat AssertingVH<T> like T* inside maps. This also allows using find_as()
+// to look up a value without constructing a value handle.
template<typename T>
-struct DenseMapInfo<AssertingVH<T>> {
- static inline AssertingVH<T> getEmptyKey() {
- AssertingVH<T> Res;
- Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
- return Res;
- }
-
- static inline AssertingVH<T> getTombstoneKey() {
- AssertingVH<T> Res;
- Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
- return Res;
- }
-
- static unsigned getHashValue(const AssertingVH<T> &Val) {
- return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
- }
-
- static bool isEqual(const AssertingVH<T> &LHS, const AssertingVH<T> &RHS) {
- return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
- RHS.getRawValPtr());
- }
-};
+struct DenseMapInfo<AssertingVH<T>> : DenseMapInfo<T *> {};
/// Value handle that tracks a Value across RAUW.
///
@@ -410,6 +394,7 @@ protected:
public:
CallbackVH() : ValueHandleBase(Callback) {}
CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
+ CallbackVH(const Value *P) : CallbackVH(const_cast<Value *>(P)) {}
operator Value*() const {
return getValPtr();
@@ -557,6 +542,17 @@ template <typename T> struct DenseMapInfo<PoisoningVH<T>> {
return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
RHS.getRawValPtr());
}
+
+ // Allow lookup by T* via find_as(), without constructing a temporary
+ // value handle.
+
+ static unsigned getHashValue(const T *Val) {
+ return DenseMapInfo<Value *>::getHashValue(Val);
+ }
+
+ static bool isEqual(const T *LHS, const PoisoningVH<T> &RHS) {
+ return DenseMapInfo<Value *>::isEqual(LHS, RHS.getRawValPtr());
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/IR/ValueMap.h b/contrib/llvm-project/llvm/include/llvm/IR/ValueMap.h
index fb5440d5efe8..a5a06b76dbf6 100644
--- a/contrib/llvm-project/llvm/include/llvm/IR/ValueMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/IR/ValueMap.h
@@ -243,7 +243,7 @@ class ValueMapCallbackVH final : public CallbackVH {
friend struct DenseMapInfo<ValueMapCallbackVH>;
using ValueMapT = ValueMap<KeyT, ValueT, Config>;
- using KeySansPointerT = typename std::remove_pointer<KeyT>::type;
+ using KeySansPointerT = std::remove_pointer_t<KeyT>;
ValueMapT *Map;
diff --git a/contrib/llvm-project/llvm/include/llvm/IRReader/IRReader.h b/contrib/llvm-project/llvm/include/llvm/IRReader/IRReader.h
index 05171300b602..a14e46e2edc8 100644
--- a/contrib/llvm-project/llvm/include/llvm/IRReader/IRReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/IRReader/IRReader.h
@@ -14,18 +14,21 @@
#ifndef LLVM_IRREADER_IRREADER_H
#define LLVM_IRREADER_IRREADER_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include <memory>
namespace llvm {
-class StringRef;
class MemoryBuffer;
class MemoryBufferRef;
class Module;
class SMDiagnostic;
class LLVMContext;
+typedef llvm::function_ref<Optional<std::string>(StringRef)>
+ DataLayoutCallbackTy;
+
/// If the given MemoryBuffer holds a bitcode image, return a Module
/// for it which does lazy deserialization of function bodies. Otherwise,
/// attempt to parse it as LLVM Assembly and return a fully populated
@@ -48,26 +51,18 @@ getLazyIRFileModule(StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
/// If the given MemoryBuffer holds a bitcode image, return a Module
/// for it. Otherwise, attempt to parse it as LLVM Assembly and return
/// a Module for it.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-std::unique_ptr<Module> parseIR(MemoryBufferRef Buffer, SMDiagnostic &Err,
- LLVMContext &Context,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+/// \param DataLayoutCallback Override datalayout in the llvm assembly.
+std::unique_ptr<Module> parseIR(
+ MemoryBufferRef Buffer, SMDiagnostic &Err, LLVMContext &Context,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
/// If the given file holds a bitcode image, return a Module for it.
/// Otherwise, attempt to parse it as LLVM Assembly and return a Module
/// for it.
-/// \param UpgradeDebugInfo Run UpgradeDebugInfo, which runs the Verifier.
-/// This option should only be set to false by llvm-as
-/// for use inside the LLVM testuite!
-/// \param DataLayoutString Override datalayout in the llvm assembly.
-std::unique_ptr<Module> parseIRFile(StringRef Filename, SMDiagnostic &Err,
- LLVMContext &Context,
- bool UpgradeDebugInfo = true,
- StringRef DataLayoutString = "");
+/// \param DataLayoutCallback Override datalayout in the llvm assembly.
+std::unique_ptr<Module> parseIRFile(
+ StringRef Filename, SMDiagnostic &Err, LLVMContext &Context,
+ DataLayoutCallbackTy DataLayoutCallback = [](StringRef) { return None; });
}
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/InitializePasses.h b/contrib/llvm-project/llvm/include/llvm/InitializePasses.h
index a5e1310e28b9..06e8507036ac 100644
--- a/contrib/llvm-project/llvm/include/llvm/InitializePasses.h
+++ b/contrib/llvm-project/llvm/include/llvm/InitializePasses.h
@@ -71,10 +71,15 @@ void initializeAggressiveInstCombinerLegacyPassPass(PassRegistry&);
void initializeAliasSetPrinterPass(PassRegistry&);
void initializeAlignmentFromAssumptionsPass(PassRegistry&);
void initializeAlwaysInlinerLegacyPassPass(PassRegistry&);
+void initializeAssumeSimplifyPassLegacyPassPass(PassRegistry &);
+void initializeAssumeBuilderPassLegacyPassPass(PassRegistry &);
+void initializeOpenMPOptLegacyPassPass(PassRegistry &);
void initializeArgPromotionPass(PassRegistry&);
void initializeAssumptionCacheTrackerPass(PassRegistry&);
void initializeAtomicExpandPass(PassRegistry&);
void initializeAttributorLegacyPassPass(PassRegistry&);
+void initializeAttributorCGSCCLegacyPassPass(PassRegistry &);
+void initializeBBSectionsPreparePass(PassRegistry &);
void initializeBDCELegacyPassPass(PassRegistry&);
void initializeBarrierNoopPass(PassRegistry&);
void initializeBasicAAWrapperPassPass(PassRegistry&);
@@ -87,6 +92,7 @@ void initializeBranchRelaxationPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
void initializeBreakFalseDepsPass(PassRegistry&);
void initializeCanonicalizeAliasesLegacyPassPass(PassRegistry &);
+void initializeCanonicalizeFreezeInLoopsPass(PassRegistry &);
void initializeCFGOnlyPrinterLegacyPassPass(PassRegistry&);
void initializeCFGOnlyViewerLegacyPassPass(PassRegistry&);
void initializeCFGPrinterLegacyPassPass(PassRegistry&);
@@ -97,6 +103,7 @@ void initializeCFGViewerLegacyPassPass(PassRegistry&);
void initializeCFIInstrInserterPass(PassRegistry&);
void initializeCFLAndersAAWrapperPassPass(PassRegistry&);
void initializeCFLSteensAAWrapperPassPass(PassRegistry&);
+void initializeCGProfileLegacyPassPass(PassRegistry &);
void initializeCallGraphDOTPrinterPass(PassRegistry&);
void initializeCallGraphPrinterLegacyPassPass(PassRegistry&);
void initializeCallGraphViewerPass(PassRegistry&);
@@ -118,6 +125,7 @@ void initializeDSELegacyPassPass(PassRegistry&);
void initializeDataFlowSanitizerPass(PassRegistry&);
void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
+void initializeDebugifyMachineModulePass(PassRegistry &);
void initializeDelinearizationPass(PassRegistry&);
void initializeDemandedBitsWrapperPassPass(PassRegistry&);
void initializeDependenceAnalysisPass(PassRegistry&);
@@ -148,6 +156,8 @@ void initializeExternalAAWrapperPassPass(PassRegistry&);
void initializeFEntryInserterPass(PassRegistry&);
void initializeFinalizeISelPass(PassRegistry&);
void initializeFinalizeMachineBundlesPass(PassRegistry&);
+void initializeFixIrreduciblePass(PassRegistry &);
+void initializeFixupStatepointCallerSavedPass(PassRegistry&);
void initializeFlattenCFGPassPass(PassRegistry&);
void initializeFloat2IntLegacyPassPass(PassRegistry&);
void initializeForceFunctionAttrsLegacyPassPass(PassRegistry&);
@@ -175,6 +185,7 @@ void initializeIRCELegacyPassPass(PassRegistry&);
void initializeIRTranslatorPass(PassRegistry&);
void initializeIVUsersWrapperPassPass(PassRegistry&);
void initializeIfConverterPass(PassRegistry&);
+void initializeImmutableModuleSummaryIndexWrapperPassPass(PassRegistry&);
void initializeImplicitNullChecksPass(PassRegistry&);
void initializeIndVarSimplifyLegacyPassPass(PassRegistry&);
void initializeIndirectBrExpandPassPass(PassRegistry&);
@@ -298,6 +309,7 @@ void initializeModuloScheduleTestPass(PassRegistry&);
void initializeMustExecutePrinterPass(PassRegistry&);
void initializeMustBeExecutedContextPrinterPass(PassRegistry&);
void initializeNameAnonGlobalLegacyPassPass(PassRegistry&);
+void initializeUniqueInternalLinkageNamesLegacyPassPass(PassRegistry &);
void initializeNaryReassociateLegacyPassPass(PassRegistry&);
void initializeNewGVNLegacyPassPass(PassRegistry&);
void initializeObjCARCAAWrapperPassPass(PassRegistry&);
@@ -397,6 +409,7 @@ void initializeStraightLineStrengthReducePass(PassRegistry&);
void initializeStripDeadDebugInfoPass(PassRegistry&);
void initializeStripDeadPrototypesLegacyPassPass(PassRegistry&);
void initializeStripDebugDeclarePass(PassRegistry&);
+void initializeStripDebugMachineModulePass(PassRegistry &);
void initializeStripGCRelocatesPass(PassRegistry&);
void initializeStripNonDebugSymbolsPass(PassRegistry&);
void initializeStripNonLineTableDebugInfoPass(PassRegistry&);
@@ -412,9 +425,11 @@ void initializeTwoAddressInstructionPassPass(PassRegistry&);
void initializeTypeBasedAAWrapperPassPass(PassRegistry&);
void initializeTypePromotionPass(PassRegistry&);
void initializeUnifyFunctionExitNodesPass(PassRegistry&);
+void initializeUnifyLoopExitsPass(PassRegistry &);
void initializeUnpackMachineBundlesPass(PassRegistry&);
void initializeUnreachableBlockElimLegacyPassPass(PassRegistry&);
void initializeUnreachableMachineBlockElimPass(PassRegistry&);
+void initializeVectorCombineLegacyPassPass(PassRegistry&);
void initializeVerifierLegacyPassPass(PassRegistry&);
void initializeVirtRegMapPass(PassRegistry&);
void initializeVirtRegRewriterPass(PassRegistry&);
diff --git a/contrib/llvm-project/llvm/include/llvm/LTO/Config.h b/contrib/llvm-project/llvm/include/llvm/LTO/Config.h
index 50147300f7f7..0a3e52316460 100644
--- a/contrib/llvm-project/llvm/include/llvm/LTO/Config.h
+++ b/contrib/llvm-project/llvm/include/llvm/LTO/Config.h
@@ -41,6 +41,7 @@ struct Config {
std::string CPU;
TargetOptions Options;
std::vector<std::string> MAttrs;
+ std::vector<std::string> PassPlugins;
Optional<Reloc::Model> RelocModel = Reloc::PIC_;
Optional<CodeModel::Model> CodeModel = None;
CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default;
@@ -61,6 +62,15 @@ struct Config {
/// Run PGO context sensitive IR instrumentation.
bool RunCSIRInstr = false;
+ /// Asserts whether we can assume whole program visibility during the LTO
+ /// link.
+ bool HasWholeProgramVisibility = false;
+
+ /// Always emit a Regular LTO object even when it is empty because no Regular
+ /// LTO modules were linked. This option is useful for some build system which
+ /// want to know a priori all possible output files.
+ bool AlwaysEmitRegularLTOObj = false;
+
/// If this field is set, the set of passes run in the middle-end optimizer
/// will be the one specified by the string. Only works with the new pass
/// manager as the old one doesn't have this ability.
@@ -120,6 +130,15 @@ struct Config {
/// Statistics output file path.
std::string StatsFile;
+ /// Specific thinLTO modules to compile.
+ std::vector<std::string> ThinLTOModulesToCompile;
+
+ /// Time trace enabled.
+ bool TimeTraceEnabled = false;
+
+ /// Time trace granularity.
+ unsigned TimeTraceGranularity = 500;
+
bool ShouldDiscardValueNames = true;
DiagnosticHandlerFunction DiagHandler;
diff --git a/contrib/llvm-project/llvm/include/llvm/LTO/LTO.h b/contrib/llvm-project/llvm/include/llvm/LTO/LTO.h
index aa21f963d3a8..93456c0ae7ae 100644
--- a/contrib/llvm-project/llvm/include/llvm/LTO/LTO.h
+++ b/contrib/llvm-project/llvm/include/llvm/LTO/LTO.h
@@ -17,28 +17,24 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
-#include "llvm/IR/DiagnosticInfo.h"
+#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/IR/ModuleSummaryIndex.h"
-#include "llvm/IR/RemarkStreamer.h"
#include "llvm/LTO/Config.h"
-#include "llvm/Linker/IRMover.h"
#include "llvm/Object/IRSymtab.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/thread.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Transforms/IPO/FunctionImport.h"
namespace llvm {
-class BitcodeModule;
class Error;
+class IRMover;
class LLVMContext;
class MemoryBufferRef;
class Module;
-class Target;
class raw_pwrite_stream;
+class Target;
+class ToolOutputFile;
/// Resolve linkage for prevailing symbols in the \p Index. Linkage changes
/// recorded in the index and the ThinLTO backends must apply the changes to
@@ -87,9 +83,9 @@ std::string getThinLTOOutputFile(const std::string &Path,
/// Setup optimization remarks.
Expected<std::unique_ptr<ToolOutputFile>>
-setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
- StringRef RemarksPasses, StringRef RemarksFormat,
- bool RemarksWithHotness, int Count = -1);
+setupLLVMOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename,
+ StringRef RemarksPasses, StringRef RemarksFormat,
+ bool RemarksWithHotness, int Count = -1);
/// Setups the output file for saving statistics.
Expected<std::unique_ptr<ToolOutputFile>>
@@ -227,7 +223,8 @@ using ThinBackend = std::function<std::unique_ptr<ThinBackendProc>(
AddStreamFn AddStream, NativeObjectCache Cache)>;
/// This ThinBackend runs the individual backend jobs in-process.
-ThinBackend createInProcessThinBackend(unsigned ParallelismLevel);
+/// The default value means to use one job per hardware core (not hyper-thread).
+ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism);
/// This ThinBackend writes individual module indexes to files, instead of
/// running the individual backend jobs. This backend is for distributed builds
@@ -330,14 +327,20 @@ private:
std::vector<GlobalValue *> Keep;
};
std::vector<AddedModule> ModsWithSummaries;
+ bool EmptyCombinedModule = true;
} RegularLTO;
+ using ModuleMapType = MapVector<StringRef, BitcodeModule>;
+
struct ThinLTOState {
ThinLTOState(ThinBackend Backend);
ThinBackend Backend;
ModuleSummaryIndex CombinedIndex;
- MapVector<StringRef, BitcodeModule> ModuleMap;
+ // The full set of bitcode modules in input order.
+ ModuleMapType ModuleMap;
+ // The bitcode modules to compile, if specified by the LTO Config.
+ Optional<ModuleMapType> ModulesToCompile;
DenseMap<GlobalValue::GUID, StringRef> PrevailingModuleForGUID;
} ThinLTO;
diff --git a/contrib/llvm-project/llvm/include/llvm/LTO/LTOBackend.h b/contrib/llvm-project/llvm/include/llvm/LTO/LTOBackend.h
index de4fa308fde7..0226e4a3fbf5 100644
--- a/contrib/llvm-project/llvm/include/llvm/LTO/LTOBackend.h
+++ b/contrib/llvm-project/llvm/include/llvm/LTO/LTOBackend.h
@@ -45,6 +45,9 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream,
const FunctionImporter::ImportMapTy &ImportList,
const GVSummaryMapTy &DefinedGlobals,
MapVector<StringRef, BitcodeModule> &ModuleMap);
+
+Error finalizeOptimizationRemarks(
+ std::unique_ptr<ToolOutputFile> DiagOutputFile);
}
}
diff --git a/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h b/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
index 114ba85947a5..d7ccc0d5a6c5 100644
--- a/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
+++ b/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOCodeGenerator.h
@@ -92,8 +92,8 @@ struct LTOCodeGenerator {
/// The default is CGFT_ObjectFile.
void setFileType(CodeGenFileType FT) { FileType = FT; }
- void setCpu(StringRef MCpu) { this->MCpu = MCpu; }
- void setAttr(StringRef MAttr) { this->MAttr = MAttr; }
+ void setCpu(StringRef MCpu) { this->MCpu = std::string(MCpu); }
+ void setAttr(StringRef MAttr) { this->MAttr = std::string(MAttr); }
void setOptLevel(unsigned OptLevel);
void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
@@ -123,7 +123,7 @@ struct LTOCodeGenerator {
/// name is misleading). This function should be called before
/// LTOCodeGenerator::compilexxx(), and
/// LTOCodeGenerator::writeMergedModules().
- void setCodeGenDebugOptions(ArrayRef<const char *> Opts);
+ void setCodeGenDebugOptions(ArrayRef<StringRef> Opts);
/// Parse the options set in setCodeGenDebugOptions.
///
diff --git a/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOModule.h b/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOModule.h
index 84b9b8c02942..998a4557dd22 100644
--- a/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOModule.h
+++ b/contrib/llvm-project/llvm/include/llvm/LTO/legacy/LTOModule.h
@@ -165,6 +165,10 @@ public:
static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
+ Expected<uint32_t> getMachOCPUType() const;
+
+ Expected<uint32_t> getMachOCPUSubType() const;
+
private:
/// Parse metadata from the module
// FIXME: it only parses "llvm.linker.options" metadata at the moment
diff --git a/contrib/llvm-project/llvm/include/llvm/LinkAllPasses.h b/contrib/llvm-project/llvm/include/llvm/LinkAllPasses.h
index aa64296f9428..90e2e24294d4 100644
--- a/contrib/llvm-project/llvm/include/llvm/LinkAllPasses.h
+++ b/contrib/llvm-project/llvm/include/llvm/LinkAllPasses.h
@@ -71,6 +71,7 @@ namespace {
(void) llvm::createAggressiveDCEPass();
(void) llvm::createAggressiveInstCombinerPass();
(void) llvm::createBitTrackingDCEPass();
+ (void) llvm::createOpenMPOptLegacyPass();
(void) llvm::createArgumentPromotionPass();
(void) llvm::createAlignmentFromAssumptionsPass();
(void) llvm::createBasicAAWrapperPass();
@@ -192,6 +193,7 @@ namespace {
(void) llvm::createInstructionNamerPass();
(void) llvm::createMetaRenamerPass();
(void) llvm::createAttributorLegacyPass();
+ (void) llvm::createAttributorCGSCCLegacyPass();
(void) llvm::createPostOrderFunctionAttrsLegacyPass();
(void) llvm::createReversePostOrderFunctionAttrsPass();
(void) llvm::createMergeFunctionsPass();
@@ -211,6 +213,7 @@ namespace {
(void) llvm::createLoopVectorizePass();
(void) llvm::createSLPVectorizerPass();
(void) llvm::createLoadStoreVectorizerPass();
+ (void) llvm::createVectorCombinePass();
(void) llvm::createPartiallyInlineLibCallsPass();
(void) llvm::createScalarizerPass();
(void) llvm::createSeparateConstOffsetFromGEPPass();
@@ -226,7 +229,9 @@ namespace {
(void) llvm::createScalarizeMaskedMemIntrinPass();
(void) llvm::createWarnMissedTransformationsPass();
(void) llvm::createHardwareLoopsPass();
- (void)llvm::createInjectTLIMappingsLegacyPass();
+ (void) llvm::createInjectTLIMappingsLegacyPass();
+ (void) llvm::createUnifyLoopExitsPass();
+ (void) llvm::createFixIrreduciblePass();
(void)new llvm::IntervalPartition();
(void)new llvm::ScalarEvolutionWrapperPass();
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/ConstantPools.h b/contrib/llvm-project/llvm/include/llvm/MC/ConstantPools.h
index 2fe5ce252c94..9fe0cce8d68c 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/ConstantPools.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/ConstantPools.h
@@ -13,7 +13,6 @@
#ifndef LLVM_MC_CONSTANTPOOLS_H
#define LLVM_MC_CONSTANTPOOLS_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/SMLoc.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/LaneBitmask.h b/contrib/llvm-project/llvm/include/llvm/MC/LaneBitmask.h
index d5f69287a265..a467407f1706 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/LaneBitmask.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/LaneBitmask.h
@@ -38,9 +38,9 @@ namespace llvm {
struct LaneBitmask {
// When changing the underlying type, change the format string as well.
- using Type = unsigned;
+ using Type = uint64_t;
enum : unsigned { BitWidth = 8*sizeof(Type) };
- constexpr static const char *const FormatStr = "%08X";
+ constexpr static const char *const FormatStr = "%016llX";
constexpr LaneBitmask() = default;
explicit constexpr LaneBitmask(Type V) : Mask(V) {}
@@ -76,7 +76,7 @@ namespace llvm {
return countPopulation(Mask);
}
unsigned getHighestLane() const {
- return Log2_32(Mask);
+ return Log2_64(Mask);
}
static constexpr LaneBitmask getNone() { return LaneBitmask(0); }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h
index bf41420f2a5a..cc9f42023bc2 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h
@@ -11,7 +11,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCFragment.h"
@@ -24,15 +23,14 @@ class MCAsmLayout;
class MCAssembler;
class MCCFIInstruction;
struct MCFixupKindInfo;
-class MCFragment;
class MCInst;
class MCObjectStreamer;
class MCObjectTargetWriter;
class MCObjectWriter;
-class MCRelaxableFragment;
class MCSubtargetInfo;
class MCValue;
class raw_pwrite_stream;
+class StringRef;
/// Generic interface to target specific assembler backends.
class MCAsmBackend {
@@ -49,12 +47,16 @@ public:
/// Return true if this target might automatically pad instructions and thus
/// need to emit padding enable/disable directives around sensative code.
virtual bool allowAutoPadding() const { return false; }
+ /// Return true if this target allows an unrelaxable instruction to be
+ /// emitted into RelaxableFragment and then we can increase its size in a
+ /// tricky way for optimization.
+ virtual bool allowEnhancedRelaxation() const { return false; }
/// Give the target a chance to manipulate state related to instruction
- /// alignment (e.g. padding for optimization) before and after actually
- /// emitting the instruction.
- virtual void alignBranchesBegin(MCObjectStreamer &OS, const MCInst &Inst) {}
- virtual void alignBranchesEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
+ /// alignment (e.g. padding for optimization), instruction relaxablility, etc.
+ /// before and after actually emitting the instruction.
+ virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst) {}
+ virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
/// lifetime management
virtual void reset() {}
@@ -159,12 +161,11 @@ public:
/// Relax the instruction in the given fragment to the next wider instruction.
///
- /// \param Inst The instruction to relax, which may be the same as the
- /// output.
+ /// \param [out] Inst The instruction to relax, which is also the relaxed
+ /// instruction.
/// \param STI the subtarget information for the associated instruction.
- /// \param [out] Res On return, the relaxed instruction.
- virtual void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
- MCInst &Res) const = 0;
+ virtual void relaxInstruction(MCInst &Inst,
+ const MCSubtargetInfo &STI) const {};
/// @}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmInfo.h b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmInfo.h
index 5a6dff64caef..46c5a111c891 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmInfo.h
@@ -93,6 +93,10 @@ protected:
/// constants into comdat sections.
bool HasCOFFComdatConstants = false;
+ /// True if this is an XCOFF target that supports visibility attributes as
+ /// part of .global, .weak, .extern, and .comm. Default is false.
+ bool HasVisibilityOnlyWithLinkage = false;
+
/// This is the maximum possible length of an instruction, which is needed to
/// compute the size of an inline asm. Defaults to 4.
unsigned MaxInstLength = 4;
@@ -156,6 +160,10 @@ protected:
/// Defaults to false.
bool AllowAtInName = false;
+ /// This is true if the assembler allows $ @ ? characters at the start of
+ /// symbol names. Defaults to false.
+ bool AllowSymbolAtNameStart = false;
+
/// If this is true, symbol names with invalid characters will be printed in
/// quotes.
bool SupportsQuotedNames = true;
@@ -171,12 +179,17 @@ protected:
//===--- Data Emission Directives -------------------------------------===//
- /// This should be set to the directive used to get some number of zero bytes
- /// emitted to the current section. Common cases are "\t.zero\t" and
- /// "\t.space\t". If this is set to null, the Data*bitsDirective's will be
- /// used to emit zero bytes. Defaults to "\t.zero\t"
+ /// This should be set to the directive used to get some number of zero (and
+ /// non-zero if supported by the directive) bytes emitted to the current
+ /// section. Common cases are "\t.zero\t" and "\t.space\t". Defaults to
+ /// "\t.zero\t"
const char *ZeroDirective;
+ /// This should be set to true if the zero directive supports a value to emit
+ /// other than zero. If this is set to false, the Data*bitsDirective's will be
+ /// used to emit these bytes. Defaults to true.
+ bool ZeroDirectiveSupportsNonZeroValue = true;
+
/// This directive allows emission of an ascii string with the standard C
/// escape characters embedded into it. If a target doesn't support this, it
/// can be set to null. Defaults to "\t.ascii\t"
@@ -313,13 +326,10 @@ protected:
/// symbol that can be hidden (unexported). Defaults to false.
bool HasWeakDefCanBeHiddenDirective = false;
- /// True if we have a .linkonce directive. This is used on cygwin/mingw.
+ /// True if we should mark symbols as global instead of weak, for
+ /// weak*/linkonce*, if the symbol has a comdat.
/// Defaults to false.
- bool HasLinkOnceDirective = false;
-
- /// True if we have a .lglobl directive, which is used to emit the information
- /// of a static symbol into the symbol table. Defaults to false.
- bool HasDotLGloblDirective = false;
+ bool AvoidWeakIfComdat = false;
/// This attribute, if not MCSA_Invalid, is used to declare a symbol as having
/// hidden visibility. Defaults to MCSA_Hidden.
@@ -333,10 +343,6 @@ protected:
/// protected visibility. Defaults to MCSA_Protected
MCSymbolAttr ProtectedVisibilityAttr = MCSA_Protected;
- // This attribute is used to indicate symbols such as commons on AIX may have
- // a storage mapping class embedded in the name.
- bool SymbolsHaveSMC = false;
-
//===--- Dwarf Emission Directives -----------------------------------===//
/// True if target supports emission of debugging information. Defaults to
@@ -492,6 +498,9 @@ public:
bool hasMachoTBSSDirective() const { return HasMachoTBSSDirective; }
bool hasCOFFAssociativeComdats() const { return HasCOFFAssociativeComdats; }
bool hasCOFFComdatConstants() const { return HasCOFFComdatConstants; }
+ bool hasVisibilityOnlyWithLinkage() const {
+ return HasVisibilityOnlyWithLinkage;
+ }
/// Returns the maximum possible encoded instruction size in bytes. If \p STI
/// is null, this should be the maximum size for any subtarget.
@@ -532,6 +541,7 @@ public:
const char *getCode64Directive() const { return Code64Directive; }
unsigned getAssemblerDialect() const { return AssemblerDialect; }
bool doesAllowAtInName() const { return AllowAtInName; }
+ bool doesAllowSymbolAtNameStart() const { return AllowSymbolAtNameStart; }
bool supportsNameQuoting() const { return SupportsQuotedNames; }
bool doesSupportDataRegionDirectives() const {
@@ -543,6 +553,9 @@ public:
}
const char *getZeroDirective() const { return ZeroDirective; }
+ bool doesZeroDirectiveSupportNonZeroValue() const {
+ return ZeroDirectiveSupportsNonZeroValue;
+ }
const char *getAsciiDirective() const { return AsciiDirective; }
const char *getAscizDirective() const { return AscizDirective; }
bool getAlignmentIsInBytes() const { return AlignmentIsInBytes; }
@@ -577,9 +590,7 @@ public:
return HasWeakDefCanBeHiddenDirective;
}
- bool hasLinkOnceDirective() const { return HasLinkOnceDirective; }
-
- bool hasDotLGloblDirective() const { return HasDotLGloblDirective; }
+ bool avoidWeakIfComdat() const { return AvoidWeakIfComdat; }
MCSymbolAttr getHiddenVisibilityAttr() const { return HiddenVisibilityAttr; }
@@ -591,8 +602,6 @@ public:
return ProtectedVisibilityAttr;
}
- bool getSymbolsHaveSMC() const { return SymbolsHaveSMC; }
-
bool doesSupportDebugInformation() const { return SupportsDebugInformation; }
bool doesSupportExceptionHandling() const {
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmLayout.h b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmLayout.h
index 45ac96f0b81e..f95af210a28f 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCAsmLayout.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCAsmLayout.h
@@ -49,6 +49,10 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
+ /// \returns whether the offset of fragment \p F can be obtained via
+ /// getFragmentOffset.
+ bool canGetFragmentOffset(const MCFragment *F) const;
+
/// Invalidate the fragments starting with F because it has been
/// resized. The fragment's size should have already been updated, but
/// its bundle padding will be recomputed.
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCAssembler.h b/contrib/llvm-project/llvm/include/llvm/MC/MCAssembler.h
index 8c76f30222e5..b57439f02ca5 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCAssembler.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCAssembler.h
@@ -190,6 +190,9 @@ private:
/// if any offsets were adjusted.
bool layoutSectionOnce(MCAsmLayout &Layout, MCSection &Sec);
+ /// Perform relaxation on a single fragment - returns true if the fragment
+ /// changes as a result of relaxation.
+ bool relaxFragment(MCAsmLayout &Layout, MCFragment &F);
bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
bool relaxBoundaryAlign(MCAsmLayout &Layout, MCBoundaryAlignFragment &BF);
@@ -440,7 +443,7 @@ public:
void addFileName(StringRef FileName) {
if (!is_contained(FileNames, FileName))
- FileNames.push_back(FileName);
+ FileNames.push_back(std::string(FileName));
}
/// Write the necessary bundle padding to \p OS.
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCContext.h b/contrib/llvm-project/llvm/include/llvm/MC/MCContext.h
index b925f3218883..45be9bb3d225 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCContext.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCContext.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/BinaryFormat/ELF.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCAsmMacro.h"
#include "llvm/MC/MCDwarf.h"
@@ -56,6 +57,7 @@ namespace llvm {
class MCSymbol;
class MCSymbolELF;
class MCSymbolWasm;
+ class MCSymbolXCOFF;
class SMLoc;
class SourceMgr;
@@ -184,30 +186,39 @@ namespace llvm {
/// The maximum version of dwarf that we should emit.
uint16_t DwarfVersion = 4;
+ /// The format of dwarf that we emit.
+ dwarf::DwarfFormat DwarfFormat = dwarf::DWARF32;
+
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
bool AllowTemporaryLabels = true;
- bool UseNamesOnTempLabels = true;
+ bool UseNamesOnTempLabels = false;
/// The Compile Unit ID that we are currently processing.
unsigned DwarfCompileUnitID = 0;
+ // Sections are differentiated by the quadruple (section_name, group_name,
+ // unique_id, link_to_symbol_name). Sections sharing the same quadruple are
+ // combined into one section.
struct ELFSectionKey {
std::string SectionName;
StringRef GroupName;
+ StringRef LinkedToName;
unsigned UniqueID;
ELFSectionKey(StringRef SectionName, StringRef GroupName,
- unsigned UniqueID)
- : SectionName(SectionName), GroupName(GroupName), UniqueID(UniqueID) {
- }
+ StringRef LinkedToName, unsigned UniqueID)
+ : SectionName(SectionName), GroupName(GroupName),
+ LinkedToName(LinkedToName), UniqueID(UniqueID) {}
bool operator<(const ELFSectionKey &Other) const {
if (SectionName != Other.SectionName)
return SectionName < Other.SectionName;
if (GroupName != Other.GroupName)
return GroupName < Other.GroupName;
+ if (int O = LinkedToName.compare(Other.LinkedToName))
+ return O < 0;
return UniqueID < Other.UniqueID;
}
};
@@ -296,11 +307,45 @@ namespace llvm {
unsigned EntrySize,
const MCSymbolELF *Group,
unsigned UniqueID,
- const MCSymbolELF *Associated);
+ const MCSymbolELF *LinkedToSym);
+
+ MCSymbolXCOFF *createXCOFFSymbolImpl(const StringMapEntry<bool> *Name,
+ bool IsTemporary);
/// Map of currently defined macros.
StringMap<MCAsmMacro> MacroMap;
+ struct ELFEntrySizeKey {
+ std::string SectionName;
+ unsigned Flags;
+ unsigned EntrySize;
+
+ ELFEntrySizeKey(StringRef SectionName, unsigned Flags, unsigned EntrySize)
+ : SectionName(SectionName), Flags(Flags), EntrySize(EntrySize) {}
+
+ bool operator<(const ELFEntrySizeKey &Other) const {
+ if (SectionName != Other.SectionName)
+ return SectionName < Other.SectionName;
+ if ((Flags & ELF::SHF_STRINGS) != (Other.Flags & ELF::SHF_STRINGS))
+ return Other.Flags & ELF::SHF_STRINGS;
+ return EntrySize < Other.EntrySize;
+ }
+ };
+
+ // Symbols must be assigned to a section with a compatible entry
+ // size. This map is used to assign unique IDs to sections to
+ // distinguish between sections with identical names but incompatible entry
+ // sizes. This can occur when a symbol is explicitly assigned to a
+ // section, e.g. via __attribute__((section("myname"))).
+ std::map<ELFEntrySizeKey, unsigned> ELFEntrySizeMap;
+
+ // This set is used to record the generic mergeable section names seen.
+ // These are sections that are created as mergeable e.g. .debug_str. We need
+ // to avoid assigning non-mergeable symbols to these sections. It is used
+ // to prevent non-mergeable symbols being explicitly assigned to mergeable
+ // sections (e.g. via _attribute_((section("myname")))).
+ DenseSet<StringRef> ELFSeenGenericMergeableSections;
+
public:
explicit MCContext(const MCAsmInfo *MAI, const MCRegisterInfo *MRI,
const MCObjectFileInfo *MOFI,
@@ -429,25 +474,19 @@ namespace llvm {
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, ~0);
- }
-
- MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
- unsigned Flags, unsigned EntrySize,
- const Twine &Group, unsigned UniqueID) {
- return getELFSection(Section, Type, Flags, EntrySize, Group, UniqueID,
- nullptr);
+ return getELFSection(Section, Type, Flags, EntrySize, Group,
+ MCSection::NonUniqueID, nullptr);
}
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const Twine &Group, unsigned UniqueID,
- const MCSymbolELF *Associated);
+ const MCSymbolELF *LinkedToSym);
MCSectionELF *getELFSection(const Twine &Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
const MCSymbolELF *Group, unsigned UniqueID,
- const MCSymbolELF *Associated);
+ const MCSymbolELF *LinkedToSym);
/// Get a section with the provided group identifier. This section is
/// named by concatenating \p Prefix with '.' then \p Suffix. The \p Type
@@ -466,6 +505,17 @@ namespace llvm {
MCSectionELF *createELFGroupSection(const MCSymbolELF *Group);
+ void recordELFMergeableSectionInfo(StringRef SectionName, unsigned Flags,
+ unsigned UniqueID, unsigned EntrySize);
+
+ bool isELFImplicitMergeableSectionNamePrefix(StringRef Name);
+
+ bool isELFGenericMergeableSection(StringRef Name);
+
+ Optional<unsigned> getELFUniqueIDForEntsize(StringRef SectionName,
+ unsigned Flags,
+ unsigned EntrySize);
+
MCSectionCOFF *getCOFFSection(StringRef Section, unsigned Characteristics,
SectionKind Kind, StringRef COMDATSymName,
int Selection,
@@ -541,7 +591,7 @@ namespace llvm {
const std::string &getMainFileName() const { return MainFileName; }
/// Set the main file name and override the default.
- void setMainFileName(StringRef S) { MainFileName = S; }
+ void setMainFileName(StringRef S) { MainFileName = std::string(S); }
/// Creates an entry in the dwarf file and directory tables.
Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
@@ -651,10 +701,8 @@ namespace llvm {
void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
- dwarf::DwarfFormat getDwarfFormat() const {
- // TODO: Support DWARF64
- return dwarf::DWARF32;
- }
+ void setDwarfFormat(dwarf::DwarfFormat f) { DwarfFormat = f; }
+ dwarf::DwarfFormat getDwarfFormat() const { return DwarfFormat; }
void setDwarfVersion(uint16_t v) { DwarfVersion = v; }
uint16_t getDwarfVersion() const { return DwarfVersion; }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCDirectives.h b/contrib/llvm-project/llvm/include/llvm/MC/MCDirectives.h
index ea79e68674e5..51e57ad37021 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCDirectives.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCDirectives.h
@@ -16,34 +16,35 @@
namespace llvm {
enum MCSymbolAttr {
- MCSA_Invalid = 0, ///< Not a valid directive.
+ MCSA_Invalid = 0, ///< Not a valid directive.
// Various directives in alphabetical order.
- MCSA_Cold, ///< .cold (MachO)
- MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
- MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
- MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
- MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
- MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
- MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
+ MCSA_Cold, ///< .cold (MachO)
+ MCSA_ELF_TypeFunction, ///< .type _foo, STT_FUNC # aka @function
+ MCSA_ELF_TypeIndFunction, ///< .type _foo, STT_GNU_IFUNC
+ MCSA_ELF_TypeObject, ///< .type _foo, STT_OBJECT # aka @object
+ MCSA_ELF_TypeTLS, ///< .type _foo, STT_TLS # aka @tls_object
+ MCSA_ELF_TypeCommon, ///< .type _foo, STT_COMMON # aka @common
+ MCSA_ELF_TypeNoType, ///< .type _foo, STT_NOTYPE # aka @notype
MCSA_ELF_TypeGnuUniqueObject, /// .type _foo, @gnu_unique_object
- MCSA_Global, ///< .globl
- MCSA_LGlobal, ///< .lglobl (XCOFF)
- MCSA_Hidden, ///< .hidden (ELF)
- MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
- MCSA_Internal, ///< .internal (ELF)
- MCSA_LazyReference, ///< .lazy_reference (MachO)
- MCSA_Local, ///< .local (ELF)
- MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
- MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
- MCSA_AltEntry, ///< .alt_entry (MachO)
- MCSA_PrivateExtern, ///< .private_extern (MachO)
- MCSA_Protected, ///< .protected (ELF)
- MCSA_Reference, ///< .reference (MachO)
- MCSA_Weak, ///< .weak
- MCSA_WeakDefinition, ///< .weak_definition (MachO)
- MCSA_WeakReference, ///< .weak_reference (MachO)
- MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO)
+ MCSA_Global, ///< .globl
+ MCSA_LGlobal, ///< .lglobl (XCOFF)
+ MCSA_Extern, ///< .extern (XCOFF)
+ MCSA_Hidden, ///< .hidden (ELF)
+ MCSA_IndirectSymbol, ///< .indirect_symbol (MachO)
+ MCSA_Internal, ///< .internal (ELF)
+ MCSA_LazyReference, ///< .lazy_reference (MachO)
+ MCSA_Local, ///< .local (ELF)
+ MCSA_NoDeadStrip, ///< .no_dead_strip (MachO)
+ MCSA_SymbolResolver, ///< .symbol_resolver (MachO)
+ MCSA_AltEntry, ///< .alt_entry (MachO)
+ MCSA_PrivateExtern, ///< .private_extern (MachO)
+ MCSA_Protected, ///< .protected (ELF)
+ MCSA_Reference, ///< .reference (MachO)
+ MCSA_Weak, ///< .weak
+ MCSA_WeakDefinition, ///< .weak_definition (MachO)
+ MCSA_WeakReference, ///< .weak_reference (MachO)
+ MCSA_WeakDefAutoPrivate ///< .weak_def_can_be_hidden (MachO)
};
enum MCAssemblerFlag {
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h b/contrib/llvm-project/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
index 76c5215264bc..10037cd66ef1 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCDisassembler/MCDisassembler.h
@@ -9,14 +9,63 @@
#ifndef LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
#define LLVM_MC_MCDISASSEMBLER_MCDISASSEMBLER_H
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCDisassembler/MCSymbolizer.h"
#include <cstdint>
#include <memory>
+#include <vector>
namespace llvm {
+struct XCOFFSymbolInfo {
+ Optional<XCOFF::StorageMappingClass> StorageMappingClass;
+ Optional<uint32_t> Index;
+ bool IsLabel;
+ XCOFFSymbolInfo(Optional<XCOFF::StorageMappingClass> Smc,
+ Optional<uint32_t> Idx, bool Label)
+ : StorageMappingClass(Smc), Index(Idx), IsLabel(Label) {}
+
+ bool operator<(const XCOFFSymbolInfo &SymInfo) const;
+};
+
+struct SymbolInfoTy {
+ uint64_t Addr;
+ StringRef Name;
+ union {
+ uint8_t Type;
+ XCOFFSymbolInfo XCOFFSymInfo;
+ };
+
+private:
+ bool IsXCOFF;
+
+public:
+ SymbolInfoTy(uint64_t Addr, StringRef Name,
+ Optional<XCOFF::StorageMappingClass> Smc, Optional<uint32_t> Idx,
+ bool Label)
+ : Addr(Addr), Name(Name), XCOFFSymInfo(Smc, Idx, Label), IsXCOFF(true) {}
+ SymbolInfoTy(uint64_t Addr, StringRef Name, uint8_t Type)
+ : Addr(Addr), Name(Name), Type(Type), IsXCOFF(false) {}
+ bool isXCOFF() const { return IsXCOFF; }
+
+private:
+ friend bool operator<(const SymbolInfoTy &P1, const SymbolInfoTy &P2) {
+ assert(P1.IsXCOFF == P2.IsXCOFF &&
+ "P1.IsXCOFF should be equal to P2.IsXCOFF.");
+ if (P1.IsXCOFF)
+ return std::tie(P1.Addr, P1.XCOFFSymInfo, P1.Name) <
+ std::tie(P2.Addr, P2.XCOFFSymInfo, P2.Name);
+
+ return std::tie(P1.Addr, P1.Name, P1.Type) <
+ std::tie(P2.Addr, P2.Name, P2.Type);
+ }
+};
+
+using SectionSymbolsTy = std::vector<SymbolInfoTy>;
+
template <typename T> class ArrayRef;
-class StringRef;
class MCContext;
class MCInst;
class MCSubtargetInfo;
@@ -78,20 +127,40 @@ public:
ArrayRef<uint8_t> Bytes, uint64_t Address,
raw_ostream &CStream) const = 0;
- /// May parse any prelude that precedes instructions after the start of a
- /// symbol. Needed for some targets, e.g. WebAssembly.
+ /// Used to perform separate target specific disassembly for a particular
+ /// symbol. May parse any prelude that precedes instructions after the
+ /// start of a symbol, or the entire symbol.
+ /// This is used for example by WebAssembly to decode preludes.
+ ///
+ /// Base implementation returns None. So all targets by default ignore to
+ /// treat symbols separately.
///
- /// \param Name - The name of the symbol.
+ /// \param Symbol - The symbol.
/// \param Size - The number of bytes consumed.
/// \param Address - The address, in the memory space of region, of the first
/// byte of the symbol.
/// \param Bytes - A reference to the actual bytes at the symbol location.
/// \param CStream - The stream to print comments and annotations on.
- /// \return - MCDisassembler::Success if the bytes are valid,
- /// MCDisassembler::Fail if the bytes were invalid.
- virtual DecodeStatus onSymbolStart(StringRef Name, uint64_t &Size,
- ArrayRef<uint8_t> Bytes, uint64_t Address,
- raw_ostream &CStream) const;
+ /// \return - MCDisassembler::Success if bytes are decoded
+ /// successfully. Size must hold the number of bytes that
+ /// were decoded.
+ /// - MCDisassembler::Fail if the bytes are invalid. Size
+ /// must hold the number of bytes that were decoded before
+ /// failing. The target must print nothing. This can be
+ /// done by buffering the output if needed.
+ /// - None if the target doesn't want to handle the symbol
+ /// separately. Value of Size is ignored in this case.
+ virtual Optional<DecodeStatus>
+ onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size, ArrayRef<uint8_t> Bytes,
+ uint64_t Address, raw_ostream &CStream) const;
+ // TODO:
+ // Implement similar hooks that can be used at other points during
+ // disassembly. Something along the following lines:
+ // - onBeforeInstructionDecode()
+ // - onAfterInstructionDecode()
+ // - onSymbolEnd()
+ // It should help move much of the target specific code from llvm-objdump to
+ // respective target disassemblers.
private:
MCContext &Ctx;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h b/contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h
index b8ee585bb017..e3cea0ae64cf 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCDwarf.h
@@ -41,6 +41,11 @@ class raw_ostream;
class SMLoc;
class SourceMgr;
+namespace mcdwarf {
+// Emit the common part of the DWARF 5 range/locations list tables header.
+MCSymbol *emitListsTableHeaderStart(MCStreamer &S);
+} // namespace mcdwarf
+
/// Instances of this class represent the name of the dwarf .file directive and
/// its associated dwarf file number in the MC file. MCDwarfFile's are created
/// and uniqued by the MCContext class. In Dwarf 4 file numbers start from 1;
@@ -252,8 +257,8 @@ public:
void setRootFile(StringRef Directory, StringRef FileName,
Optional<MD5::MD5Result> Checksum,
Optional<StringRef> Source) {
- CompilationDir = Directory;
- RootFile.Name = FileName;
+ CompilationDir = std::string(Directory);
+ RootFile.Name = std::string(FileName);
RootFile.DirIndex = 0;
RootFile.Checksum = Checksum;
RootFile.Source = Source;
@@ -325,8 +330,8 @@ public:
void setRootFile(StringRef Directory, StringRef FileName,
Optional<MD5::MD5Result> Checksum, Optional<StringRef> Source) {
- Header.CompilationDir = Directory;
- Header.RootFile.Name = FileName;
+ Header.CompilationDir = std::string(Directory);
+ Header.RootFile.Name = std::string(FileName);
Header.RootFile.DirIndex = 0;
Header.RootFile.Checksum = Checksum;
Header.RootFile.Source = Source;
@@ -477,9 +482,9 @@ private:
public:
/// .cfi_def_cfa defines a rule for computing CFA as: take address from
/// Register and add Offset to it.
- static MCCFIInstruction createDefCfa(MCSymbol *L, unsigned Register,
- int Offset) {
- return MCCFIInstruction(OpDefCfa, L, Register, -Offset, "");
+ static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register,
+ int Offset) {
+ return MCCFIInstruction(OpDefCfa, L, Register, Offset, "");
}
/// .cfi_def_cfa_register modifies a rule for computing CFA. From now
@@ -491,8 +496,8 @@ public:
/// .cfi_def_cfa_offset modifies a rule for computing CFA. Register
/// remains the same, but offset is new. Note that it is the absolute offset
/// that will be added to a defined register to the compute CFA address.
- static MCCFIInstruction createDefCfaOffset(MCSymbol *L, int Offset) {
- return MCCFIInstruction(OpDefCfaOffset, L, 0, -Offset, "");
+ static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int Offset) {
+ return MCCFIInstruction(OpDefCfaOffset, L, 0, Offset, "");
}
/// .cfi_adjust_cfa_offset Same as .cfi_def_cfa_offset, but
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCELFObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCELFObjectWriter.h
index 2d441fdeee28..8f78b99d3794 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCELFObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCELFObjectWriter.h
@@ -65,7 +65,7 @@ protected:
public:
virtual ~MCELFObjectTargetWriter() = default;
- virtual Triple::ObjectFormatType getFormat() const { return Triple::ELF; }
+ Triple::ObjectFormatType getFormat() const override { return Triple::ELF; }
static bool classof(const MCObjectTargetWriter *W) {
return W->getFormat() == Triple::ELF;
}
@@ -130,14 +130,10 @@ public:
}
// N64 relocation type setting
- unsigned setRType(unsigned Value, unsigned Type) const {
- return ((Type & R_TYPE_MASK) | ((Value & 0xff) << R_TYPE_SHIFT));
- }
- unsigned setRType2(unsigned Value, unsigned Type) const {
- return (Type & R_TYPE2_MASK) | ((Value & 0xff) << R_TYPE2_SHIFT);
- }
- unsigned setRType3(unsigned Value, unsigned Type) const {
- return (Type & R_TYPE3_MASK) | ((Value & 0xff) << R_TYPE3_SHIFT);
+ static unsigned setRTypes(unsigned Value1, unsigned Value2, unsigned Value3) {
+ return ((Value1 & 0xff) << R_TYPE_SHIFT) |
+ ((Value2 & 0xff) << R_TYPE2_SHIFT) |
+ ((Value3 & 0xff) << R_TYPE3_SHIFT);
}
unsigned setRSsym(unsigned Value, unsigned Type) const {
return (Type & R_SSYM_MASK) | ((Value & 0xff) << R_SSYM_SHIFT);
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCELFStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCELFStreamer.h
index 85534ed6c085..f11629d94e90 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCELFStreamer.h
@@ -39,50 +39,50 @@ public:
/// @{
void InitSections(bool NoExecStack) override;
- void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
- void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- void EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
+ void changeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
uint64_t Offset) override;
- void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
- void EmitThumbFunc(MCSymbol *Func) override;
- void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
- bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
- void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void emitThumbFunc(MCSymbol *Func) override;
+ void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
void emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) override;
- void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0,
SMLoc L = SMLoc()) override;
- void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
- void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
- void EmitIdent(StringRef IdentString) override;
+ void emitIdent(StringRef IdentString) override;
- void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+ void emitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
void emitCGProfileEntry(const MCSymbolRefExpr *From,
const MCSymbolRefExpr *To, uint64_t Count) override;
- void FinishImpl() override;
+ void finishImpl() override;
- void EmitBundleAlignMode(unsigned AlignPow2) override;
- void EmitBundleLock(bool AlignToEnd) override;
- void EmitBundleUnlock() override;
+ void emitBundleAlignMode(unsigned AlignPow2) override;
+ void emitBundleLock(bool AlignToEnd) override;
+ void emitBundleUnlock() override;
private:
bool isBundleLocked() const;
- void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
- void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
void fixSymbolsInTLSFixups(const MCExpr *expr);
void finalizeCGProfileEntry(const MCSymbolRefExpr *&S);
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCExpr.h b/contrib/llvm-project/llvm/include/llvm/MC/MCExpr.h
index eb2786501f84..803c0d443bee 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCExpr.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCExpr.h
@@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
/// needed for parsing.
class MCExpr {
public:
- enum ExprKind {
+ enum ExprKind : uint8_t {
Binary, ///< Binary expressions.
Constant, ///< Constant expressions.
SymbolRef, ///< References to labels and assigned expressions.
@@ -43,7 +43,14 @@ public:
};
private:
+ static const unsigned NumSubclassDataBits = 24;
+ static_assert(
+ NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
+ "ExprKind and SubclassData together should take up one word");
+
ExprKind Kind;
+ /// Field reserved for use by MCExpr subclasses.
+ unsigned SubclassData : NumSubclassDataBits;
SMLoc Loc;
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
@@ -51,13 +58,19 @@ private:
const SectionAddrMap *Addrs, bool InSet) const;
protected:
- explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
+ explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
+ : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
+ assert(SubclassData < (1 << NumSubclassDataBits) &&
+ "Subclass data too large");
+ }
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet) const;
+ unsigned getSubclassData() const { return SubclassData; }
+
public:
MCExpr(const MCExpr &) = delete;
MCExpr &operator=(const MCExpr &) = delete;
@@ -130,29 +143,39 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
//// Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
int64_t Value;
- bool PrintInHex = false;
- explicit MCConstantExpr(int64_t Value)
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
+ // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
+ static const unsigned SizeInBytesBits = 8;
+ static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
+ static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
+
+ static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
+ assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
+ return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
+ }
- MCConstantExpr(int64_t Value, bool PrintInHex)
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value),
- PrintInHex(PrintInHex) {}
+ MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
+ : MCExpr(MCExpr::Constant, SMLoc(),
+ encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
public:
/// \name Construction
/// @{
static const MCConstantExpr *create(int64_t Value, MCContext &Ctx,
- bool PrintInHex = false);
+ bool PrintInHex = false,
+ unsigned SizeInBytes = 0);
/// @}
/// \name Accessors
/// @{
int64_t getValue() const { return Value; }
+ unsigned getSizeInBytes() const {
+ return getSubclassData() & SizeInBytesMask;
+ }
- bool useHexFormat() const { return PrintInHex; }
+ bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }
/// @}
@@ -175,6 +198,7 @@ public:
VK_GOT,
VK_GOTOFF,
VK_GOTREL,
+ VK_PCREL,
VK_GOTPCREL,
VK_GOTTPOFF,
VK_INDNTPOFF,
@@ -186,9 +210,9 @@ public:
VK_TLSLDM,
VK_TPOFF,
VK_DTPOFF,
- VK_TLSCALL, // symbol(tlscall)
- VK_TLSDESC, // symbol(tlsdesc)
- VK_TLVP, // Mach-O thread local variable relocations
+ VK_TLSCALL, // symbol(tlscall)
+ VK_TLSDESC, // symbol(tlsdesc)
+ VK_TLVP, // Mach-O thread local variable relocations
VK_TLVPPAGE,
VK_TLVPPAGEOFF,
VK_PAGE,
@@ -196,8 +220,8 @@ public:
VK_GOTPAGE,
VK_GOTPAGEOFF,
VK_SECREL,
- VK_SIZE, // symbol@SIZE
- VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+ VK_SIZE, // symbol@SIZE
+ VK_WEAKREF, // The link between the symbols in .weakref foo, bar
VK_X86_ABS8,
@@ -206,8 +230,8 @@ public:
VK_ARM_TARGET1,
VK_ARM_TARGET2,
VK_ARM_PREL31,
- VK_ARM_SBREL, // symbol(sbrel)
- VK_ARM_TLSLDO, // symbol(tlsldo)
+ VK_ARM_SBREL, // symbol(sbrel)
+ VK_ARM_TLSLDO, // symbol(tlsldo)
VK_ARM_TLSDESCSEQ,
VK_AVR_NONE,
@@ -218,68 +242,69 @@ public:
VK_AVR_DIFF16,
VK_AVR_DIFF32,
- VK_PPC_LO, // symbol@l
- VK_PPC_HI, // symbol@h
- VK_PPC_HA, // symbol@ha
- VK_PPC_HIGH, // symbol@high
- VK_PPC_HIGHA, // symbol@higha
- VK_PPC_HIGHER, // symbol@higher
- VK_PPC_HIGHERA, // symbol@highera
- VK_PPC_HIGHEST, // symbol@highest
- VK_PPC_HIGHESTA, // symbol@highesta
- VK_PPC_GOT_LO, // symbol@got@l
- VK_PPC_GOT_HI, // symbol@got@h
- VK_PPC_GOT_HA, // symbol@got@ha
- VK_PPC_TOCBASE, // symbol@tocbase
- VK_PPC_TOC, // symbol@toc
- VK_PPC_TOC_LO, // symbol@toc@l
- VK_PPC_TOC_HI, // symbol@toc@h
- VK_PPC_TOC_HA, // symbol@toc@ha
- VK_PPC_U, // symbol@u
- VK_PPC_L, // symbol@l
- VK_PPC_DTPMOD, // symbol@dtpmod
- VK_PPC_TPREL_LO, // symbol@tprel@l
- VK_PPC_TPREL_HI, // symbol@tprel@h
- VK_PPC_TPREL_HA, // symbol@tprel@ha
- VK_PPC_TPREL_HIGH, // symbol@tprel@high
- VK_PPC_TPREL_HIGHA, // symbol@tprel@higha
- VK_PPC_TPREL_HIGHER, // symbol@tprel@higher
- VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera
- VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest
- VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
- VK_PPC_DTPREL_LO, // symbol@dtprel@l
- VK_PPC_DTPREL_HI, // symbol@dtprel@h
- VK_PPC_DTPREL_HA, // symbol@dtprel@ha
- VK_PPC_DTPREL_HIGH, // symbol@dtprel@high
- VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha
- VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher
- VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
- VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
- VK_PPC_DTPREL_HIGHESTA,// symbol@dtprel@highesta
- VK_PPC_GOT_TPREL, // symbol@got@tprel
- VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l
- VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h
- VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha
- VK_PPC_GOT_DTPREL, // symbol@got@dtprel
- VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l
- VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h
- VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha
- VK_PPC_TLS, // symbol@tls
- VK_PPC_GOT_TLSGD, // symbol@got@tlsgd
- VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l
- VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
- VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
- VK_PPC_TLSGD, // symbol@tlsgd
- VK_PPC_GOT_TLSLD, // symbol@got@tlsld
- VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
- VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
- VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
- VK_PPC_TLSLD, // symbol@tlsld
- VK_PPC_LOCAL, // symbol@local
+ VK_PPC_LO, // symbol@l
+ VK_PPC_HI, // symbol@h
+ VK_PPC_HA, // symbol@ha
+ VK_PPC_HIGH, // symbol@high
+ VK_PPC_HIGHA, // symbol@higha
+ VK_PPC_HIGHER, // symbol@higher
+ VK_PPC_HIGHERA, // symbol@highera
+ VK_PPC_HIGHEST, // symbol@highest
+ VK_PPC_HIGHESTA, // symbol@highesta
+ VK_PPC_GOT_LO, // symbol@got@l
+ VK_PPC_GOT_HI, // symbol@got@h
+ VK_PPC_GOT_HA, // symbol@got@ha
+ VK_PPC_TOCBASE, // symbol@tocbase
+ VK_PPC_TOC, // symbol@toc
+ VK_PPC_TOC_LO, // symbol@toc@l
+ VK_PPC_TOC_HI, // symbol@toc@h
+ VK_PPC_TOC_HA, // symbol@toc@ha
+ VK_PPC_U, // symbol@u
+ VK_PPC_L, // symbol@l
+ VK_PPC_DTPMOD, // symbol@dtpmod
+ VK_PPC_TPREL_LO, // symbol@tprel@l
+ VK_PPC_TPREL_HI, // symbol@tprel@h
+ VK_PPC_TPREL_HA, // symbol@tprel@ha
+ VK_PPC_TPREL_HIGH, // symbol@tprel@high
+ VK_PPC_TPREL_HIGHA, // symbol@tprel@higha
+ VK_PPC_TPREL_HIGHER, // symbol@tprel@higher
+ VK_PPC_TPREL_HIGHERA, // symbol@tprel@highera
+ VK_PPC_TPREL_HIGHEST, // symbol@tprel@highest
+ VK_PPC_TPREL_HIGHESTA, // symbol@tprel@highesta
+ VK_PPC_DTPREL_LO, // symbol@dtprel@l
+ VK_PPC_DTPREL_HI, // symbol@dtprel@h
+ VK_PPC_DTPREL_HA, // symbol@dtprel@ha
+ VK_PPC_DTPREL_HIGH, // symbol@dtprel@high
+ VK_PPC_DTPREL_HIGHA, // symbol@dtprel@higha
+ VK_PPC_DTPREL_HIGHER, // symbol@dtprel@higher
+ VK_PPC_DTPREL_HIGHERA, // symbol@dtprel@highera
+ VK_PPC_DTPREL_HIGHEST, // symbol@dtprel@highest
+ VK_PPC_DTPREL_HIGHESTA, // symbol@dtprel@highesta
+ VK_PPC_GOT_TPREL, // symbol@got@tprel
+ VK_PPC_GOT_TPREL_LO, // symbol@got@tprel@l
+ VK_PPC_GOT_TPREL_HI, // symbol@got@tprel@h
+ VK_PPC_GOT_TPREL_HA, // symbol@got@tprel@ha
+ VK_PPC_GOT_DTPREL, // symbol@got@dtprel
+ VK_PPC_GOT_DTPREL_LO, // symbol@got@dtprel@l
+ VK_PPC_GOT_DTPREL_HI, // symbol@got@dtprel@h
+ VK_PPC_GOT_DTPREL_HA, // symbol@got@dtprel@ha
+ VK_PPC_TLS, // symbol@tls
+ VK_PPC_GOT_TLSGD, // symbol@got@tlsgd
+ VK_PPC_GOT_TLSGD_LO, // symbol@got@tlsgd@l
+ VK_PPC_GOT_TLSGD_HI, // symbol@got@tlsgd@h
+ VK_PPC_GOT_TLSGD_HA, // symbol@got@tlsgd@ha
+ VK_PPC_TLSGD, // symbol@tlsgd
+ VK_PPC_GOT_TLSLD, // symbol@got@tlsld
+ VK_PPC_GOT_TLSLD_LO, // symbol@got@tlsld@l
+ VK_PPC_GOT_TLSLD_HI, // symbol@got@tlsld@h
+ VK_PPC_GOT_TLSLD_HA, // symbol@got@tlsld@ha
+ VK_PPC_GOT_PCREL, // symbol@got@pcrel
+ VK_PPC_TLSLD, // symbol@tlsld
+ VK_PPC_LOCAL, // symbol@local
+ VK_PPC_NOTOC, // symbol@notoc
VK_COFF_IMGREL32, // symbol@imgrel (image-relative)
- VK_Hexagon_PCREL,
VK_Hexagon_LO16,
VK_Hexagon_HI16,
VK_Hexagon_GPREL,
@@ -302,22 +327,52 @@ public:
VK_AMDGPU_ABS32_LO, // symbol@abs32@lo
VK_AMDGPU_ABS32_HI, // symbol@abs32@hi
+ VK_VE_HI32, // symbol@hi
+ VK_VE_LO32, // symbol@lo
+ VK_VE_PC_HI32, // symbol@pc_hi
+ VK_VE_PC_LO32, // symbol@pc_lo
+ VK_VE_GOT_HI32, // symbol@got_hi
+ VK_VE_GOT_LO32, // symbol@got_lo
+ VK_VE_GOTOFF_HI32, // symbol@gotoff_hi
+ VK_VE_GOTOFF_LO32, // symbol@gotoff_lo
+ VK_VE_PLT_HI32, // symbol@plt_hi
+ VK_VE_PLT_LO32, // symbol@plt_lo
+ VK_VE_TLS_GD_HI32, // symbol@tls_gd_hi
+ VK_VE_TLS_GD_LO32, // symbol@tls_gd_lo
+ VK_VE_TPOFF_HI32, // symbol@tpoff_hi
+ VK_VE_TPOFF_LO32, // symbol@tpoff_lo
+
VK_TPREL,
VK_DTPREL
};
private:
- /// The symbol reference modifier.
- const VariantKind Kind;
+ /// The symbol being referenced.
+ const MCSymbol *Symbol;
+
+ // Subclass data stores VariantKind in bits 0..15, UseParensForSymbolVariant
+ // in bit 16 and HasSubsectionsViaSymbols in bit 17.
+ static const unsigned VariantKindBits = 16;
+ static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
/// Specifies how the variant kind should be printed.
- const unsigned UseParensForSymbolVariant : 1;
+ static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits;
// FIXME: Remove this bit.
- const unsigned HasSubsectionsViaSymbols : 1;
+ static const unsigned HasSubsectionsViaSymbolsBit =
+ 1 << (VariantKindBits + 1);
+
+ static unsigned encodeSubclassData(VariantKind Kind,
+ bool UseParensForSymbolVariant,
+ bool HasSubsectionsViaSymbols) {
+ return (unsigned)Kind |
+ (UseParensForSymbolVariant ? UseParensForSymbolVariantBit : 0) |
+ (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
+ }
- /// The symbol being referenced.
- const MCSymbol *Symbol;
+ bool useParensForSymbolVariant() const {
+ return (getSubclassData() & UseParensForSymbolVariantBit) != 0;
+ }
explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
@@ -341,11 +396,15 @@ public:
const MCSymbol &getSymbol() const { return *Symbol; }
- VariantKind getKind() const { return Kind; }
+ VariantKind getKind() const {
+ return (VariantKind)(getSubclassData() & VariantKindMask);
+ }
void printVariantKind(raw_ostream &OS) const;
- bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+ bool hasSubsectionsViaSymbols() const {
+ return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
+ }
/// @}
/// \name Static Utility Functions
@@ -373,11 +432,10 @@ public:
};
private:
- Opcode Op;
const MCExpr *Expr;
MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
- : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
+ : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
public:
/// \name Construction
@@ -407,7 +465,7 @@ public:
/// @{
/// Get the kind of this unary expression.
- Opcode getOpcode() const { return Op; }
+ Opcode getOpcode() const { return (Opcode)getSubclassData(); }
/// Get the child of this unary expression.
const MCExpr *getSubExpr() const { return Expr; }
@@ -449,12 +507,11 @@ public:
};
private:
- Opcode Op;
const MCExpr *LHS, *RHS;
MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
SMLoc Loc = SMLoc())
- : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
+ : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
public:
/// \name Construction
@@ -564,7 +621,7 @@ public:
/// @{
/// Get the kind of this binary expression.
- Opcode getOpcode() const { return Op; }
+ Opcode getOpcode() const { return (Opcode)getSubclassData(); }
/// Get the left-hand side expression of the binary operator.
const MCExpr *getLHS() const { return LHS; }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCFixup.h b/contrib/llvm-project/llvm/include/llvm/MC/MCFixup.h
index 29e321e2354c..affc846cbdd4 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCFixup.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCFixup.h
@@ -55,9 +55,14 @@ enum MCFixupKind {
FirstTargetFixupKind = 128,
- // Limit range of target fixups, in case we want to pack more efficiently
- // later.
- MaxTargetFixupKind = (1 << 8)
+ /// The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for
+ /// relocations coming from .reloc directive. Fixup kind
+ /// FirstLiteralRelocationKind+V represents the relocation type with number V.
+ FirstLiteralRelocationKind = 256,
+
+ /// Set limit to accommodate the highest reloc type in use for all Targets,
+ /// currently R_AARCH64_IRELATIVE at 1032, including room for expansion.
+ MaxFixupKind = FirstLiteralRelocationKind + 1032 + 32,
};
/// Encode information on a single operation to perform on a byte
@@ -92,7 +97,7 @@ class MCFixup {
public:
static MCFixup create(uint32_t Offset, const MCExpr *Value,
MCFixupKind Kind, SMLoc Loc = SMLoc()) {
- assert(Kind < MaxTargetFixupKind && "Kind out of range!");
+ assert(Kind <= MaxFixupKind && "Kind out of range!");
MCFixup FI;
FI.Value = Value;
FI.Offset = Offset;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCFragment.h b/contrib/llvm-project/llvm/include/llvm/MC/MCFragment.h
index ed237eb1e884..fb7166e82c09 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCFragment.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCFragment.h
@@ -65,6 +65,9 @@ private:
FragmentType Kind;
+ /// Whether fragment is being laid out.
+ bool IsBeingLaidOut;
+
protected:
bool HasInstructions;
@@ -259,6 +262,8 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
/// The instruction this is a fragment for.
MCInst Inst;
+ /// Can we auto pad the instruction?
+ bool AllowAutoPadding = false;
public:
MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
@@ -269,6 +274,9 @@ public:
const MCInst &getInst() const { return Inst; }
void setInst(const MCInst &Value) { Inst = Value; }
+ bool getAllowAutoPadding() const { return AllowAutoPadding; }
+ void setAllowAutoPadding(bool V) { AllowAutoPadding = V; }
+
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Relaxable;
}
@@ -523,31 +531,28 @@ public:
class MCBoundaryAlignFragment : public MCFragment {
/// The alignment requirement of the branch to be aligned.
Align AlignBoundary;
- /// Flag to indicate whether the branch is fused. Use in determining the
- /// region of fragments being aligned.
- bool Fused : 1;
- /// Flag to indicate whether NOPs should be emitted.
- bool EmitNops : 1;
+ /// The last fragment in the set of fragments to be aligned.
+ const MCFragment *LastFragment = nullptr;
/// The size of the fragment. The size is lazily set during relaxation, and
/// is not meaningful before that.
uint64_t Size = 0;
public:
- MCBoundaryAlignFragment(Align AlignBoundary, bool Fused = false,
- bool EmitNops = false, MCSection *Sec = nullptr)
- : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary),
- Fused(Fused), EmitNops(EmitNops) {}
+ MCBoundaryAlignFragment(Align AlignBoundary, MCSection *Sec = nullptr)
+ : MCFragment(FT_BoundaryAlign, false, Sec), AlignBoundary(AlignBoundary) {
+ }
uint64_t getSize() const { return Size; }
void setSize(uint64_t Value) { Size = Value; }
Align getAlignment() const { return AlignBoundary; }
+ void setAlignment(Align Value) { AlignBoundary = Value; }
- bool isFused() const { return Fused; }
- void setFused(bool Value) { Fused = Value; }
-
- bool canEmitNops() const { return EmitNops; }
- void setEmitNops(bool Value) { EmitNops = Value; }
+ const MCFragment *getLastFragment() const { return LastFragment; }
+ void setLastFragment(const MCFragment *F) {
+ assert(!F || getParent() == F->getParent());
+ LastFragment = F;
+ }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_BoundaryAlign;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h
index 97290e73c28f..71e049b92455 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCInstPrinter.h
@@ -58,6 +58,11 @@ protected:
/// Which style to use for printing hexadecimal values.
HexStyle::Style PrintHexStyle = HexStyle::C;
+ /// If true, a branch immediate (e.g. bl 4) will be printed as a hexadecimal
+ /// address (e.g. bl 0x20004). This is useful for a stream disassembler
+ /// (llvm-objdump -d).
+ bool PrintBranchImmAsAddress = false;
+
/// Utility function for printing annotations.
void printAnnotation(raw_ostream &OS, StringRef Annot);
@@ -79,6 +84,12 @@ public:
void setCommentStream(raw_ostream &OS) { CommentStream = &OS; }
/// Print the specified MCInst to the specified raw_ostream.
+ ///
+ /// \p Address the address of current instruction on most targets, used to
+ /// print a PC relative immediate as the target address. On targets where a PC
+ /// relative immediate is relative to the next instruction and the length of a
+ /// MCInst is difficult to measure (e.g. x86), this is the address of the next
+ /// instruction. If Address is 0, the immediate will be printed.
virtual void printInst(const MCInst *MI, uint64_t Address, StringRef Annot,
const MCSubtargetInfo &STI, raw_ostream &OS) = 0;
@@ -100,6 +111,10 @@ public:
void setPrintHexStyle(HexStyle::Style Value) { PrintHexStyle = Value; }
+ void setPrintBranchImmAsAddress(bool Value) {
+ PrintBranchImmAsAddress = Value;
+ }
+
/// Utility function to print immediates in decimal or hex.
format_object<int64_t> formatImm(int64_t Value) const {
return PrintImmHex ? formatHex(Value) : formatDec(Value);
@@ -129,14 +144,17 @@ struct AliasPattern {
struct AliasPatternCond {
enum CondKind : uint8_t {
- K_Feature, // Match only if a feature is enabled.
- K_NegFeature, // Match only if a feature is disabled.
- K_Ignore, // Match any operand.
- K_Reg, // Match a specific register.
- K_TiedReg, // Match another already matched register.
- K_Imm, // Match a specific immediate.
- K_RegClass, // Match registers in a class.
- K_Custom, // Call custom matcher by index.
+ K_Feature, // Match only if a feature is enabled.
+ K_NegFeature, // Match only if a feature is disabled.
+ K_OrFeature, // Match only if one of a set of features is enabled.
+ K_OrNegFeature, // Match only if one of a set of features is disabled.
+ K_EndOrFeatures, // Note end of list of K_Or(Neg)?Features.
+ K_Ignore, // Match any operand.
+ K_Reg, // Match a specific register.
+ K_TiedReg, // Match another already matched register.
+ K_Imm, // Match a specific immediate.
+ K_RegClass, // Match registers in a class.
+ K_Custom, // Call custom matcher by index.
};
CondKind Kind;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrDesc.h b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrDesc.h
index 506f2c09304c..17454e3134a2 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrDesc.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrDesc.h
@@ -19,9 +19,8 @@
#include <string>
namespace llvm {
- class MCInst;
- class MCSubtargetInfo;
- class FeatureBitset;
+
+class MCInst;
//===----------------------------------------------------------------------===//
// Machine Operand Flags and Description
@@ -197,15 +196,6 @@ public:
const MCPhysReg *ImplicitUses; // Registers implicitly read by this instr
const MCPhysReg *ImplicitDefs; // Registers implicitly defined by this instr
const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
- // Subtarget feature that this is deprecated on, if any
- // -1 implies this is not deprecated by any single feature. It may still be
- // deprecated due to a "complex" reason, below.
- int64_t DeprecatedFeature;
-
- // A complex method to determine if a certain instruction is deprecated or
- // not, and return the reason for deprecation.
- bool (*ComplexDeprecationInfo)(MCInst &, const MCSubtargetInfo &,
- std::string &);
/// Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
@@ -219,11 +209,6 @@ public:
return -1;
}
- /// Returns true if a certain instruction is deprecated and if so
- /// returns the reason in \p Info.
- bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
- std::string &Info) const;
-
/// Return the opcode number for this descriptor.
unsigned getOpcode() const { return Opcode; }
@@ -300,7 +285,7 @@ public:
/// Returns true if this is a conditional, unconditional, or
/// indirect branch. Predicates below can be used to discriminate between
- /// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
+ /// these cases, and the TargetInstrInfo::analyzeBranch method can be used to
/// get more information.
bool isBranch() const { return Flags & (1ULL << MCID::Branch); }
@@ -310,7 +295,7 @@ public:
/// Return true if this is a branch which may fall
/// through to the next instruction or may transfer control flow to some other
- /// block. The TargetInstrInfo::AnalyzeBranch method can be used to get more
+ /// block. The TargetInstrInfo::analyzeBranch method can be used to get more
/// information about this branch.
bool isConditionalBranch() const {
return isBranch() && !isBarrier() && !isIndirectBranch();
@@ -318,7 +303,7 @@ public:
/// Return true if this is a branch which always
/// transfers control flow to some other block. The
- /// TargetInstrInfo::AnalyzeBranch method can be used to get more information
+ /// TargetInstrInfo::analyzeBranch method can be used to get more information
/// about this branch.
bool isUnconditionalBranch() const {
return isBranch() && isBarrier() && !isIndirectBranch();
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrInfo.h b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrInfo.h
index 874b1e46795b..598e24257e5d 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrInfo.h
@@ -18,22 +18,40 @@
namespace llvm {
+class MCSubtargetInfo;
+
//---------------------------------------------------------------------------
/// Interface to description of machine instruction set.
class MCInstrInfo {
+public:
+ using ComplexDeprecationPredicate = bool (*)(MCInst &,
+ const MCSubtargetInfo &,
+ std::string &);
+
+private:
const MCInstrDesc *Desc; // Raw array to allow static init'n
const unsigned *InstrNameIndices; // Array for name indices in InstrNameData
const char *InstrNameData; // Instruction name string pool
+ // Subtarget feature that an instruction is deprecated on, if any
+ // -1 implies this is not deprecated by any single feature. It may still be
+ // deprecated due to a "complex" reason, below.
+ const uint8_t *DeprecatedFeatures;
+ // A complex method to determine if a certain instruction is deprecated or
+ // not, and return the reason for deprecation.
+ const ComplexDeprecationPredicate *ComplexDeprecationInfos;
unsigned NumOpcodes; // Number of entries in the desc array
public:
/// Initialize MCInstrInfo, called by TableGen auto-generated routines.
/// *DO NOT USE*.
void InitMCInstrInfo(const MCInstrDesc *D, const unsigned *NI, const char *ND,
- unsigned NO) {
+ const uint8_t *DF,
+ const ComplexDeprecationPredicate *CDI, unsigned NO) {
Desc = D;
InstrNameIndices = NI;
InstrNameData = ND;
+ DeprecatedFeatures = DF;
+ ComplexDeprecationInfos = CDI;
NumOpcodes = NO;
}
@@ -51,6 +69,11 @@ public:
assert(Opcode < NumOpcodes && "Invalid opcode!");
return StringRef(&InstrNameData[InstrNameIndices[Opcode]]);
}
+
+ /// Returns true if a certain instruction is deprecated and if so
+ /// returns the reason in \p Info.
+ bool getDeprecatedInfo(MCInst &MI, const MCSubtargetInfo &STI,
+ std::string &Info) const;
};
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrItineraries.h b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrItineraries.h
index 485aa663272e..652922feddc3 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCInstrItineraries.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCInstrItineraries.h
@@ -61,8 +61,11 @@ struct InstrStage {
Reserved = 1
};
+ /// Bitmask representing a set of functional units.
+ typedef uint64_t FuncUnits;
+
unsigned Cycles_; ///< Length of stage in machine cycles
- unsigned Units_; ///< Choice of functional units
+ FuncUnits Units_; ///< Choice of functional units
int NextCycles_; ///< Number of machine cycles to next stage
ReservationKinds Kind_; ///< Kind of the FU reservation
@@ -72,7 +75,7 @@ struct InstrStage {
}
/// Returns the choice of FUs.
- unsigned getUnits() const {
+ FuncUnits getUnits() const {
return Units_;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCMachObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCMachObjectWriter.h
index 853e5066f039..38ba68b78fe1 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCMachObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCMachObjectWriter.h
@@ -16,6 +16,7 @@
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/EndianStream.h"
#include <cstdint>
#include <memory>
#include <string>
@@ -44,7 +45,7 @@ protected:
public:
virtual ~MCMachObjectTargetWriter();
- virtual Triple::ObjectFormatType getFormat() const { return Triple::MachO; }
+ Triple::ObjectFormatType getFormat() const override { return Triple::MachO; }
static bool classof(const MCObjectTargetWriter *W) {
return W->getFormat() == Triple::MachO;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectFileInfo.h b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectFileInfo.h
index 2f7f5d64b466..ca04d8e8d3b6 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectFileInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectFileInfo.h
@@ -89,6 +89,7 @@ protected:
MCSection *DwarfARangesSection = nullptr;
MCSection *DwarfRangesSection = nullptr;
MCSection *DwarfMacinfoSection = nullptr;
+ MCSection *DwarfMacroSection = nullptr;
// The pubnames section is no longer generated by default. The generation
// can be enabled by a compiler flag.
MCSection *DwarfPubNamesSection = nullptr;
@@ -112,6 +113,7 @@ protected:
MCSection *DwarfLocDWOSection = nullptr;
MCSection *DwarfStrOffDWOSection = nullptr;
MCSection *DwarfMacinfoDWOSection = nullptr;
+ MCSection *DwarfMacroDWOSection = nullptr;
/// The DWARF v5 string offset and address table sections.
MCSection *DwarfStrOffSection = nullptr;
@@ -171,7 +173,6 @@ protected:
/// Section containing metadata on function stack sizes.
MCSection *StackSizesSection = nullptr;
- mutable DenseMap<const MCSymbol *, unsigned> StackSizesUniquing;
// ELF specific sections.
MCSection *DataRelROSection = nullptr;
@@ -216,9 +217,13 @@ protected:
MCSection *GFIDsSection = nullptr;
MCSection *GLJMPSection = nullptr;
+ // XCOFF specific sections
+ MCSection *TOCBaseSection = nullptr;
+
public:
void InitMCObjectFileInfo(const Triple &TT, bool PIC, MCContext &ctx,
bool LargeCodeModel = false);
+ MCContext &getContext() const { return *Ctx; }
bool getSupportsWeakOmittedEHFrame() const {
return SupportsWeakOmittedEHFrame;
@@ -272,6 +277,7 @@ public:
MCSection *getDwarfRnglistsSection() const { return DwarfRnglistsSection; }
MCSection *getDwarfLoclistsSection() const { return DwarfLoclistsSection; }
MCSection *getDwarfMacinfoSection() const { return DwarfMacinfoSection; }
+ MCSection *getDwarfMacroSection() const { return DwarfMacroSection; }
MCSection *getDwarfDebugNamesSection() const {
return DwarfDebugNamesSection;
@@ -304,6 +310,7 @@ public:
MCSection *getDwarfLoclistsDWOSection() const {
return DwarfLoclistsDWOSection;
}
+ MCSection *getDwarfMacroDWOSection() const { return DwarfMacroDWOSection; }
MCSection *getDwarfMacinfoDWOSection() const {
return DwarfMacinfoDWOSection;
}
@@ -391,6 +398,9 @@ public:
MCSection *getGFIDsSection() const { return GFIDsSection; }
MCSection *getGLJMPSection() const { return GLJMPSection; }
+ // XCOFF specific sections
+ MCSection *getTOCBaseSection() const { return TOCBaseSection; }
+
MCSection *getEHFrameSection() {
return EHFrameSection;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h
index 9e3f87565e26..c3f3ae5de921 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectStreamer.h
@@ -9,6 +9,7 @@
#ifndef LLVM_MC_MCOBJECTSTREAMER_H
#define LLVM_MC_MCOBJECTSTREAMER_H
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCSection.h"
@@ -38,7 +39,7 @@ class MCObjectStreamer : public MCStreamer {
bool EmitEHFrame;
bool EmitDebugFrame;
SmallVector<MCSymbol *, 2> PendingLabels;
- SmallVector<MCSection*, 2> PendingLabelSections;
+ SmallSetVector<MCSection *, 4> PendingLabelSections;
unsigned CurSubsectionIdx;
struct PendingMCFixup {
const MCSymbol *Sym;
@@ -49,11 +50,11 @@ class MCObjectStreamer : public MCStreamer {
};
SmallVector<PendingMCFixup, 2> PendingFixups;
- virtual void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
- void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
- void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
- MCSymbol *EmitCFILabel() override;
- void EmitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
+ virtual void emitInstToData(const MCInst &Inst, const MCSubtargetInfo&) = 0;
+ void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
+ void emitCFIEndProcImpl(MCDwarfFrameInfo &Frame) override;
+ MCSymbol *emitCFILabel() override;
+ void emitInstructionImpl(const MCInst &Inst, const MCSubtargetInfo &STI);
void resolvePendingFixups();
protected:
@@ -69,8 +70,8 @@ public:
/// Object streamers require the integrated assembler.
bool isIntegratedAssemblerRequired() const override { return true; }
- void EmitFrames(MCAsmBackend *MAB);
- void EmitCFISections(bool EH, bool Debug) override;
+ void emitFrames(MCAsmBackend *MAB);
+ void emitCFISections(bool EH, bool Debug) override;
MCFragment *getCurrentFragment() const;
@@ -113,78 +114,77 @@ public:
/// \name MCStreamer Interface
/// @{
- void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- virtual void EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ virtual void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCFragment *F,
uint64_t Offset);
- void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
- void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ void emitAssignment(MCSymbol *Symbol, const MCExpr *Value) override;
+ void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
- void EmitULEB128Value(const MCExpr *Value) override;
- void EmitSLEB128Value(const MCExpr *Value) override;
- void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
- void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
- void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+ void emitULEB128Value(const MCExpr *Value) override;
+ void emitSLEB128Value(const MCExpr *Value) override;
+ void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ void changeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
/// Emit an instruction to a special fragment, because this instruction
/// can change its size during relaxation.
- virtual void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
+ virtual void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &);
- void EmitBundleAlignMode(unsigned AlignPow2) override;
- void EmitBundleLock(bool AlignToEnd) override;
- void EmitBundleUnlock() override;
- void EmitBytes(StringRef Data) override;
- void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ void emitBundleAlignMode(unsigned AlignPow2) override;
+ void emitBundleLock(bool AlignToEnd) override;
+ void emitBundleUnlock() override;
+ void emitBytes(StringRef Data) override;
+ void emitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0) override;
- void EmitCodeAlignment(unsigned ByteAlignment,
+ void emitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0) override;
void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc) override;
- void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
- unsigned Column, unsigned Flags,
- unsigned Isa, unsigned Discriminator,
+ void emitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column,
+ unsigned Flags, unsigned Isa,
+ unsigned Discriminator,
StringRef FileName) override;
- void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
- const MCSymbol *Label,
- unsigned PointerSize);
- void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ void emitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel,
+ const MCSymbol *Label, unsigned PointerSize);
+ void emitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
const MCSymbol *Label);
- void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
+ void emitCVLocDirective(unsigned FunctionId, unsigned FileNo, unsigned Line,
unsigned Column, bool PrologueEnd, bool IsStmt,
StringRef FileName, SMLoc Loc) override;
- void EmitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
+ void emitCVLinetableDirective(unsigned FunctionId, const MCSymbol *Begin,
const MCSymbol *End) override;
- void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
+ void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
unsigned SourceFileId,
unsigned SourceLineNum,
const MCSymbol *FnStartSym,
const MCSymbol *FnEndSym) override;
- void EmitCVDefRangeDirective(
+ void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
StringRef FixedSizePortion) override;
- void EmitCVStringTableDirective() override;
- void EmitCVFileChecksumsDirective() override;
- void EmitCVFileChecksumOffsetDirective(unsigned FileNo) override;
- void EmitDTPRel32Value(const MCExpr *Value) override;
- void EmitDTPRel64Value(const MCExpr *Value) override;
- void EmitTPRel32Value(const MCExpr *Value) override;
- void EmitTPRel64Value(const MCExpr *Value) override;
- void EmitGPRel32Value(const MCExpr *Value) override;
- void EmitGPRel64Value(const MCExpr *Value) override;
- bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
- const MCExpr *Expr, SMLoc Loc,
- const MCSubtargetInfo &STI) override;
+ void emitCVStringTableDirective() override;
+ void emitCVFileChecksumsDirective() override;
+ void emitCVFileChecksumOffsetDirective(unsigned FileNo) override;
+ void emitDTPRel32Value(const MCExpr *Value) override;
+ void emitDTPRel64Value(const MCExpr *Value) override;
+ void emitTPRel32Value(const MCExpr *Value) override;
+ void emitTPRel64Value(const MCExpr *Value) override;
+ void emitGPRel32Value(const MCExpr *Value) override;
+ void emitGPRel64Value(const MCExpr *Value) override;
+ Optional<std::pair<bool, std::string>>
+ emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
+ SMLoc Loc, const MCSubtargetInfo &STI) override;
using MCStreamer::emitFill;
void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
SMLoc Loc = SMLoc()) override;
void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
SMLoc Loc = SMLoc()) override;
- void EmitFileDirective(StringRef Filename) override;
+ void emitFileDirective(StringRef Filename) override;
- void EmitAddrsig() override;
- void EmitAddrsigSym(const MCSymbol *Sym) override;
+ void emitAddrsig() override;
+ void emitAddrsigSym(const MCSymbol *Sym) override;
- void FinishImpl() override;
+ void finishImpl() override;
/// Emit the absolute difference between two symbols if possible.
///
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectWriter.h
index 2547b2b7c9c1..ddc2301c04c1 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCObjectWriter.h
@@ -9,13 +9,7 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/EndianStream.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cassert>
#include <cstdint>
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/AsmLexer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/AsmLexer.h
index b7294493b2f8..05b3695bc7a0 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/AsmLexer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/AsmLexer.h
@@ -30,6 +30,7 @@ class AsmLexer : public MCAsmLexer {
bool IsAtStartOfLine = true;
bool IsAtStartOfStatement = true;
bool IsPeeking = false;
+ bool EndStatementAtEOF = true;
protected:
/// LexToken - Read the next token and return its code.
@@ -41,7 +42,8 @@ public:
AsmLexer &operator=(const AsmLexer &) = delete;
~AsmLexer() override;
- void setBuffer(StringRef Buf, const char *ptr = nullptr);
+ void setBuffer(StringRef Buf, const char *ptr = nullptr,
+ bool EndStatementAtEOF = true);
StringRef LexUntilEndOfStatement() override;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParser.h b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParser.h
index da5653ee71d3..a68066e0f50b 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParser.h
@@ -165,8 +165,19 @@ public:
/// Run the parser on the input source buffer.
virtual bool Run(bool NoInitialTextSection, bool NoFinalize = false) = 0;
- virtual void setParsingInlineAsm(bool V) = 0;
- virtual bool isParsingInlineAsm() = 0;
+ virtual void setParsingMSInlineAsm(bool V) = 0;
+ virtual bool isParsingMSInlineAsm() = 0;
+
+ virtual bool isParsingMasm() const { return false; }
+
+ virtual bool lookUpField(StringRef Name, StringRef &Type,
+ unsigned &Offset) const {
+ return true;
+ }
+ virtual bool lookUpField(StringRef Base, StringRef Member, StringRef &Type,
+ unsigned &Offset) const {
+ return true;
+ }
/// Parse MS-style inline assembly.
virtual bool parseMSInlineAsm(
@@ -250,6 +261,10 @@ public:
/// characters and return the string contents.
virtual bool parseEscapedString(std::string &Data) = 0;
+ /// Parse an angle-bracket delimited string at the current position if one is
+ /// present, returning the string contents.
+ virtual bool parseAngleBracketString(std::string &Data) = 0;
+
/// Skip to the end of the current statement, for error recovery.
virtual void eatToEndOfStatement() = 0;
@@ -300,10 +315,14 @@ public:
SMLoc &EndLoc) = 0;
};
-/// Create an MCAsmParser instance.
+/// Create an MCAsmParser instance for parsing assembly similar to gas syntax
MCAsmParser *createMCAsmParser(SourceMgr &, MCContext &, MCStreamer &,
const MCAsmInfo &, unsigned CB = 0);
+/// Create an MCAsmParser instance for parsing Microsoft MASM-style assembly
+MCAsmParser *createMCMasmParser(SourceMgr &, MCContext &, MCStreamer &,
+ const MCAsmInfo &, unsigned CB = 0);
+
} // end namespace llvm
#endif // LLVM_MC_MCPARSER_MCASMPARSER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 5d2afe81a54b..c37889cfc509 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -98,6 +98,8 @@ public:
return getParser().parseOptionalToken(T);
}
+ bool ParseDirectiveCGProfile(StringRef, SMLoc);
+
bool check(bool P, const Twine &Msg) {
return getParser().check(P, Msg);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index 6e4821cbc7b9..1d10c66b4201 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -329,12 +329,12 @@ protected: // Can only create subclasses.
/// AvailableFeatures - The current set of available features.
FeatureBitset AvailableFeatures;
- /// ParsingInlineAsm - Are we parsing ms-style inline assembly?
- bool ParsingInlineAsm = false;
+ /// ParsingMSInlineAsm - Are we parsing ms-style inline assembly?
+ bool ParsingMSInlineAsm = false;
/// SemaCallback - The Sema callback implementation. Must be set when parsing
/// ms-style inline assembly.
- MCAsmParserSemaCallback *SemaCallback;
+ MCAsmParserSemaCallback *SemaCallback = nullptr;
/// Set of options which affects instrumentation of inline assembly.
MCTargetOptions MCOptions;
@@ -359,8 +359,8 @@ public:
AvailableFeatures = Value;
}
- bool isParsingInlineAsm () { return ParsingInlineAsm; }
- void setParsingInlineAsm (bool Value) { ParsingInlineAsm = Value; }
+ bool isParsingMSInlineAsm () { return ParsingMSInlineAsm; }
+ void setParsingMSInlineAsm (bool Value) { ParsingMSInlineAsm = Value; }
MCTargetOptions getTargetOptions() const { return MCOptions; }
@@ -376,6 +376,14 @@ public:
virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
SMLoc &EndLoc) = 0;
+ /// tryParseRegister - parse one register if possible
+ ///
+ /// Check whether a register specification can be parsed at the current
+ /// location, without failing the entire parse if it can't. Must not consume
+ /// tokens if the parse fails.
+ virtual OperandMatchResultTy
+ tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) = 0;
+
/// ParseInstruction - Parse one assembly instruction.
///
/// The parser is positioned following the instruction name. The target
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCRegister.h b/contrib/llvm-project/llvm/include/llvm/MC/MCRegister.h
index 8372947a4ba1..1f3c4b8494cc 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCRegister.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCRegister.h
@@ -23,7 +23,7 @@ class MCRegister {
unsigned Reg;
public:
- MCRegister(unsigned Val = 0): Reg(Val) {}
+ constexpr MCRegister(unsigned Val = 0): Reg(Val) {}
// Register numbers can represent physical registers, virtual registers, and
// sometimes stack slots. The unsigned values are divided into these ranges:
@@ -35,6 +35,12 @@ public:
//
// Further sentinels can be allocated from the small negative integers.
// DenseMapInfo<unsigned> uses -1u and -2u.
+ static_assert(std::numeric_limits<decltype(Reg)>::max() >= 0xFFFFFFFF,
+ "Reg isn't large enough to hold full range.");
+ static constexpr unsigned NoRegister = 0u;
+ static constexpr unsigned FirstPhysicalReg = 1u;
+ static constexpr unsigned FirstStackSlot = 1u << 30;
+ static constexpr unsigned VirtualRegFlag = 1u << 31;
/// This is the portion of the positive number space that is not a physical
/// register. StackSlot values do not exist in the MC layer, see
@@ -44,14 +50,15 @@ public:
/// slots, so if a variable may contains a stack slot, always check
/// isStackSlot() first.
static bool isStackSlot(unsigned Reg) {
- return int(Reg) >= (1 << 30);
+ return !(Reg & VirtualRegFlag) &&
+ uint32_t(Reg & ~VirtualRegFlag) >= FirstStackSlot;
}
/// Return true if the specified register number is in
/// the physical register namespace.
static bool isPhysicalRegister(unsigned Reg) {
assert(!isStackSlot(Reg) && "Not a register! Check isStackSlot() first.");
- return int(Reg) > 0;
+ return Reg >= FirstPhysicalReg && !(Reg & VirtualRegFlag);
}
/// Return true if the specified register number is in the physical register
@@ -60,7 +67,7 @@ public:
return isPhysicalRegister(Reg);
}
- operator unsigned() const {
+ constexpr operator unsigned() const {
return Reg;
}
@@ -68,9 +75,7 @@ public:
return Reg;
}
- bool isValid() const {
- return Reg != 0;
- }
+ bool isValid() const { return Reg != NoRegister; }
/// Comparisons between register objects
bool operator==(const MCRegister &Other) const { return Reg == Other.Reg; }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSchedule.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSchedule.h
index df3248ee6e86..66c5659af3a7 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSchedule.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSchedule.h
@@ -14,7 +14,6 @@
#ifndef LLVM_MC_MCSCHEDULE_H
#define LLVM_MC_MCSCHEDULE_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/DataTypes.h"
@@ -22,6 +21,7 @@
namespace llvm {
+template <typename T> class ArrayRef;
struct InstrItinerary;
class MCSubtargetInfo;
class MCInstrInfo;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSection.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSection.h
index d80cc5b086b3..a68e06e661be 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSection.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSection.h
@@ -38,6 +38,8 @@ template <> struct ilist_alloc_traits<MCFragment> {
/// current translation unit. The MCContext class uniques and creates these.
class MCSection {
public:
+ static constexpr unsigned NonUniqueID = ~0U;
+
enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO, SV_Wasm, SV_XCOFF };
/// Express the state of bundle locked groups while emitting code.
@@ -98,16 +100,19 @@ private:
SmallVector<PendingLabel, 2> PendingLabels;
protected:
+ // TODO Make Name private when possible.
+ StringRef Name;
SectionVariant Variant;
SectionKind Kind;
- MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin);
+ MCSection(SectionVariant V, StringRef Name, SectionKind K, MCSymbol *Begin);
~MCSection();
public:
MCSection(const MCSection &) = delete;
MCSection &operator=(const MCSection &) = delete;
+ StringRef getName() const { return Name; }
SectionKind getKind() const { return Kind; }
SectionVariant getVariant() const { return Variant; }
@@ -184,6 +189,8 @@ public:
/// file contents.
virtual bool isVirtualSection() const = 0;
+ virtual StringRef getVirtualSectionKind() const;
+
/// Add a pending label for the requested subsection. This label will be
/// associated with a fragment in flushPendingLabels()
void addPendingLabel(MCSymbol* label, unsigned Subsection = 0);
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionCOFF.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionCOFF.h
index 8be95e0f1de5..3ece6eb904bc 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionCOFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionCOFF.h
@@ -24,9 +24,6 @@ class MCSymbol;
/// This represents a section on Windows
class MCSectionCOFF final : public MCSection {
- // The memory for this string is stored in the same MCContext as *this.
- StringRef SectionName;
-
// FIXME: The following fields should not be mutable, but are for now so the
// asm parser can honor the .linkonce directive.
@@ -51,12 +48,12 @@ class MCSectionCOFF final : public MCSection {
private:
friend class MCContext;
- MCSectionCOFF(StringRef Section, unsigned Characteristics,
+ // The storage of Name is owned by MCContext's COFFUniquingMap.
+ MCSectionCOFF(StringRef Name, unsigned Characteristics,
MCSymbol *COMDATSymbol, int Selection, SectionKind K,
MCSymbol *Begin)
- : MCSection(SV_COFF, K, Begin), SectionName(Section),
- Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
- Selection(Selection) {
+ : MCSection(SV_COFF, Name, K, Begin), Characteristics(Characteristics),
+ COMDATSymbol(COMDATSymbol), Selection(Selection) {
assert((Characteristics & 0x00F00000) == 0 &&
"alignment must not be set upon section creation");
}
@@ -66,7 +63,6 @@ public:
/// section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
- StringRef getSectionName() const { return SectionName; }
unsigned getCharacteristics() const { return Characteristics; }
MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
int getSelection() const { return Selection; }
@@ -78,6 +74,7 @@ public:
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
+ StringRef getVirtualSectionKind() const override;
unsigned getOrAssignWinCFISectionID(unsigned *NextID) const {
if (WinCFISectionID == ~0U)
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionELF.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionELF.h
index fe6b2d7afc79..4136ea79de41 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionELF.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionELF.h
@@ -25,10 +25,6 @@ class MCSymbol;
/// This represents a section on linux, lots of unix variants and some bare
/// metal systems.
class MCSectionELF final : public MCSection {
- /// This is the name of the section. The referenced memory is owned by
- /// TargetLoweringObjectFileELF's ELFUniqueMap.
- StringRef SectionName;
-
/// This is the sh_type field of a section, drawn from the enums below.
unsigned Type;
@@ -44,30 +40,33 @@ class MCSectionELF final : public MCSection {
const MCSymbolELF *Group;
- /// sh_info for SHF_LINK_ORDER (can be null).
- const MCSymbol *AssociatedSymbol;
+ /// Used by SHF_LINK_ORDER. If non-null, the sh_link field will be set to the
+ /// section header index of the section where LinkedToSym is defined.
+ const MCSymbol *LinkedToSym;
private:
friend class MCContext;
- MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
+ // The storage of Name is owned by MCContext's ELFUniquingMap.
+ MCSectionELF(StringRef Name, unsigned type, unsigned flags, SectionKind K,
unsigned entrySize, const MCSymbolELF *group, unsigned UniqueID,
- MCSymbol *Begin, const MCSymbolELF *AssociatedSymbol)
- : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
- Flags(flags), UniqueID(UniqueID), EntrySize(entrySize), Group(group),
- AssociatedSymbol(AssociatedSymbol) {
+ MCSymbol *Begin, const MCSymbolELF *LinkedToSym)
+ : MCSection(SV_ELF, Name, K, Begin), Type(type), Flags(flags),
+ UniqueID(UniqueID), EntrySize(entrySize), Group(group),
+ LinkedToSym(LinkedToSym) {
if (Group)
Group->setIsSignature();
}
- void setSectionName(StringRef Name) { SectionName = Name; }
+ // TODO Delete after we stop supporting generation of GNU-style .zdebug_*
+ // sections.
+ void setSectionName(StringRef Name) { this->Name = Name; }
public:
/// Decides whether a '.section' directive should be printed before the
/// section name
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
- StringRef getSectionName() const { return SectionName; }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
@@ -79,12 +78,15 @@ public:
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
+ StringRef getVirtualSectionKind() const override;
- bool isUnique() const { return UniqueID != ~0U; }
+ bool isUnique() const { return UniqueID != NonUniqueID; }
unsigned getUniqueID() const { return UniqueID; }
- const MCSection *getAssociatedSection() const { return &AssociatedSymbol->getSection(); }
- const MCSymbol *getAssociatedSymbol() const { return AssociatedSymbol; }
+ const MCSection *getLinkedToSection() const {
+ return &LinkedToSym->getSection();
+ }
+ const MCSymbol *getLinkedToSymbol() const { return LinkedToSym; }
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionMachO.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionMachO.h
index 2c73661fb1fd..b67558551d97 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionMachO.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionMachO.h
@@ -23,7 +23,6 @@ namespace llvm {
/// system, these are also described in /usr/include/mach-o/loader.h.
class MCSectionMachO final : public MCSection {
char SegmentName[16]; // Not necessarily null terminated!
- char SectionName[16]; // Not necessarily null terminated!
/// This is the SECTION_TYPE and SECTION_ATTRIBUTES field of a section, drawn
/// from the enums below.
@@ -44,12 +43,6 @@ public:
return StringRef(SegmentName, 16);
return StringRef(SegmentName);
}
- StringRef getSectionName() const {
- // SectionName is not necessarily null terminated!
- if (SectionName[15])
- return StringRef(SectionName, 16);
- return StringRef(SectionName);
- }
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionWasm.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionWasm.h
index 2941a40f3b8c..6211afef71db 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionWasm.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionWasm.h
@@ -13,22 +13,17 @@
#ifndef LLVM_MC_MCSECTIONWASM_H
#define LLVM_MC_MCSECTIONWASM_H
-#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCSection.h"
-#include "llvm/MC/MCSymbolWasm.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
namespace llvm {
class MCSymbol;
+class MCSymbolWasm;
+class StringRef;
+class raw_ostream;
/// This represents a section on wasm.
class MCSectionWasm final : public MCSection {
- /// This is the name of the section. The referenced memory is owned by
- /// TargetLoweringObjectFileWasm's WasmUniqueMap.
- StringRef SectionName;
-
unsigned UniqueID;
const MCSymbolWasm *Group;
@@ -45,18 +40,17 @@ class MCSectionWasm final : public MCSection {
// Whether this data segment is passive
bool IsPassive = false;
+ // The storage of Name is owned by MCContext's WasmUniquingMap.
friend class MCContext;
- MCSectionWasm(StringRef Section, SectionKind K, const MCSymbolWasm *group,
+ MCSectionWasm(StringRef Name, SectionKind K, const MCSymbolWasm *group,
unsigned UniqueID, MCSymbol *Begin)
- : MCSection(SV_Wasm, K, Begin), SectionName(Section), UniqueID(UniqueID),
- Group(group) {}
+ : MCSection(SV_Wasm, Name, K, Begin), UniqueID(UniqueID), Group(group) {}
public:
/// Decides whether a '.section' directive should be printed before the
/// section name
bool shouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
- StringRef getSectionName() const { return SectionName; }
const MCSymbolWasm *getGroup() const { return Group; }
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionXCOFF.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionXCOFF.h
index 611eb69c1493..eed6b9c2609c 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSectionXCOFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSectionXCOFF.h
@@ -13,7 +13,6 @@
#ifndef LLVM_MC_MCSECTIONXCOFF_H
#define LLVM_MC_MCSECTIONXCOFF_H
-#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSymbolXCOFF.h"
@@ -33,24 +32,31 @@ namespace llvm {
class MCSectionXCOFF final : public MCSection {
friend class MCContext;
- StringRef Name;
XCOFF::StorageMappingClass MappingClass;
XCOFF::SymbolType Type;
XCOFF::StorageClass StorageClass;
MCSymbolXCOFF *const QualName;
+ StringRef SymbolTableName;
+ static constexpr unsigned DefaultAlignVal = 4;
- MCSectionXCOFF(StringRef Section, XCOFF::StorageMappingClass SMC,
+ MCSectionXCOFF(StringRef Name, XCOFF::StorageMappingClass SMC,
XCOFF::SymbolType ST, XCOFF::StorageClass SC, SectionKind K,
- MCSymbolXCOFF *QualName, MCSymbol *Begin)
- : MCSection(SV_XCOFF, K, Begin), Name(Section), MappingClass(SMC),
- Type(ST), StorageClass(SC), QualName(QualName) {
+ MCSymbolXCOFF *QualName, MCSymbol *Begin,
+ StringRef SymbolTableName)
+ : MCSection(SV_XCOFF, Name, K, Begin), MappingClass(SMC), Type(ST),
+ StorageClass(SC), QualName(QualName), SymbolTableName(SymbolTableName) {
assert((ST == XCOFF::XTY_SD || ST == XCOFF::XTY_CM || ST == XCOFF::XTY_ER) &&
"Invalid or unhandled type for csect.");
assert(QualName != nullptr && "QualName is needed.");
QualName->setStorageClass(SC);
- QualName->setContainingCsect(this);
+ QualName->setRepresentedCsect(this);
+ // A csect is 4 byte aligned by default, except for undefined symbol csects.
+ if (Type != XCOFF::XTY_ER)
+ setAlignment(Align(DefaultAlignVal));
}
+ void printCsectDirective(raw_ostream &OS) const;
+
public:
~MCSectionXCOFF();
@@ -58,7 +64,6 @@ public:
return S->getVariant() == SV_XCOFF;
}
- StringRef getSectionName() const { return Name; }
XCOFF::StorageMappingClass getMappingClass() const { return MappingClass; }
XCOFF::StorageClass getStorageClass() const { return StorageClass; }
XCOFF::SymbolType getCSectType() const { return Type; }
@@ -69,6 +74,7 @@ public:
const MCExpr *Subsection) const override;
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
+ StringRef getSymbolTableName() const { return SymbolTableName; }
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCStreamer.h
index ba1649d33d12..484c62538366 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCStreamer.h
@@ -40,7 +40,6 @@ class AssemblerConstantPools;
class formatted_raw_ostream;
class MCAsmBackend;
class MCCodeEmitter;
-struct MCCodePaddingContext;
class MCContext;
struct MCDwarfFrameInfo;
class MCExpr;
@@ -155,7 +154,7 @@ public:
StringRef StringValue = "");
virtual void emitFPU(unsigned FPU);
virtual void emitArch(ARM::ArchKind Arch);
- virtual void emitArchExtension(unsigned ArchExt);
+ virtual void emitArchExtension(uint64_t ArchExt);
virtual void emitObjectArch(ARM::ArchKind Arch);
void emitTargetAttributes(const MCSubtargetInfo &STI);
virtual void finishAttributeSection();
@@ -233,8 +232,8 @@ class MCStreamer {
protected:
MCStreamer(MCContext &Ctx);
- virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
- virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
+ virtual void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame);
+ virtual void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame);
WinEH::FrameInfo *getCurrentWinFrameInfo() {
return CurrentWinFrameInfo;
@@ -242,7 +241,7 @@ protected:
virtual void EmitWindowsUnwindTables();
- virtual void EmitRawTextImpl(StringRef String);
+ virtual void emitRawTextImpl(StringRef String);
/// Returns true if the the .cv_loc directive is in the right section.
bool checkCVLocSection(unsigned FuncId, unsigned FileNo, SMLoc Loc);
@@ -279,7 +278,7 @@ public:
/// When emitting an object file, create and emit a real label. When emitting
/// textual assembly, this should do nothing to avoid polluting our output.
- virtual MCSymbol *EmitCFILabel();
+ virtual MCSymbol *emitCFILabel();
/// Retreive the current frame info if one is available and it is not yet
/// closed. Otherwise, issue an error and return null.
@@ -378,7 +377,7 @@ public:
///
/// This is called by PopSection and SwitchSection, if the current
/// section changes.
- virtual void ChangeSection(MCSection *, const MCExpr *);
+ virtual void changeSection(MCSection *, const MCExpr *);
/// Save the current and previous section on the section stack.
void PushSection() {
@@ -387,7 +386,7 @@ public:
}
/// Restore the current and previous section from the section stack.
- /// Calls ChangeSection as needed.
+ /// Calls changeSection as needed.
///
/// Returns false if the stack was empty.
bool PopSection() {
@@ -399,8 +398,8 @@ public:
--I;
MCSectionSubPair NewSection = I->first;
- if (OldSection != NewSection)
- ChangeSection(NewSection.first, NewSection.second);
+ if (NewSection.first && OldSection != NewSection)
+ changeSection(NewSection.first, NewSection.second);
SectionStack.pop_back();
return true;
}
@@ -422,7 +421,7 @@ public:
/// Set the current section where code is being emitted to \p Section.
/// This is required to update CurSection. This version does not call
- /// ChangeSection.
+ /// changeSection.
void SwitchSectionNoChange(MCSection *Section,
const MCExpr *Subsection = nullptr) {
assert(Section && "Cannot switch to a null section!");
@@ -453,37 +452,37 @@ public:
/// used in an assignment.
// FIXME: These emission are non-const because we mutate the symbol to
// add the section we're emitting it to later.
- virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc());
+ virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc());
- virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
+ virtual void emitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol);
/// Note in the output the specified \p Flag.
- virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
+ virtual void emitAssemblerFlag(MCAssemblerFlag Flag);
/// Emit the given list \p Options of strings as linker
/// options into the output.
- virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
+ virtual void emitLinkerOptions(ArrayRef<std::string> Kind) {}
/// Note in the output the specified region \p Kind.
- virtual void EmitDataRegion(MCDataRegionType Kind) {}
+ virtual void emitDataRegion(MCDataRegionType Kind) {}
/// Specify the Mach-O minimum deployment target version.
- virtual void EmitVersionMin(MCVersionMinType Type, unsigned Major,
+ virtual void emitVersionMin(MCVersionMinType Type, unsigned Major,
unsigned Minor, unsigned Update,
VersionTuple SDKVersion) {}
/// Emit/Specify Mach-O build version command.
/// \p Platform should be one of MachO::PlatformType.
- virtual void EmitBuildVersion(unsigned Platform, unsigned Major,
+ virtual void emitBuildVersion(unsigned Platform, unsigned Major,
unsigned Minor, unsigned Update,
VersionTuple SDKVersion) {}
- void EmitVersionForTarget(const Triple &Target,
+ void emitVersionForTarget(const Triple &Target,
const VersionTuple &SDKVersion);
/// Note in the output that the specified \p Func is a Thumb mode
/// function (ARM target only).
- virtual void EmitThumbFunc(MCSymbol *Func);
+ virtual void emitThumbFunc(MCSymbol *Func);
/// Emit an assignment of \p Value to \p Symbol.
///
@@ -496,7 +495,7 @@ public:
///
/// \param Symbol - The symbol being assigned to.
/// \param Value - The value for the symbol.
- virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
+ virtual void emitAssignment(MCSymbol *Symbol, const MCExpr *Value);
/// Emit an weak reference from \p Alias to \p Symbol.
///
@@ -505,17 +504,17 @@ public:
///
/// \param Alias - The alias that is being created.
/// \param Symbol - The symbol being aliased.
- virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
+ virtual void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
/// Add the given \p Attribute to \p Symbol.
- virtual bool EmitSymbolAttribute(MCSymbol *Symbol,
+ virtual bool emitSymbolAttribute(MCSymbol *Symbol,
MCSymbolAttr Attribute) = 0;
/// Set the \p DescValue for the \p Symbol.
///
/// \param Symbol - The symbol to have its n_desc field set.
/// \param DescValue - The value to set into the n_desc field.
- virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
+ virtual void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
/// Start emitting COFF symbol definition
///
@@ -562,10 +561,29 @@ public:
/// \param CsectSym - Csect name for the block of storage.
/// \param ByteAlignment - The alignment of the symbol in bytes. Must be a
/// power of 2.
- virtual void EmitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
+ virtual void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
MCSymbol *CsectSym,
unsigned ByteAlignment);
+ /// Emit a symbol's linkage and visibilty with a linkage directive for XCOFF.
+ ///
+ /// \param Symbol - The symbol to emit.
+ /// \param Linkage - The linkage of the symbol to emit.
+ /// \param Visibility - The visibility of the symbol to emit or MCSA_Invalid
+ /// if the symbol does not have an explicit visibility.
+ virtual void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
+ MCSymbolAttr Linkage,
+ MCSymbolAttr Visibility);
+
+ /// Emit a XCOFF .rename directive which creates a synonym for an illegal or
+ /// undesirable name.
+ ///
+ /// \param Name - The name used internally in the assembly for references to
+ /// the symbol.
+ /// \param Rename - The value to which the Name parameter is
+ /// changed at the end of assembly.
+ virtual void emitXCOFFRenameDirective(const MCSymbol *Name, StringRef Rename);
+
/// Emit an ELF .size directive.
///
/// This corresponds to an assembler statement such as:
@@ -583,7 +601,7 @@ public:
/// Emit a Linker Optimization Hint (LOH) directive.
/// \param Args - Arguments of the LOH.
- virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
+ virtual void emitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}
/// Emit a common symbol.
///
@@ -591,7 +609,7 @@ public:
/// \param Size - The size of the common symbol.
/// \param ByteAlignment - The alignment of the symbol if
/// non-zero. This must be a power of 2.
- virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) = 0;
/// Emit a local common (.lcomm) symbol.
@@ -599,7 +617,7 @@ public:
/// \param Symbol - The common symbol to emit.
/// \param Size - The size of the common symbol.
/// \param ByteAlignment - The alignment of the common symbol in bytes.
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ virtual void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment);
/// Emit the zerofill section and an optional symbol.
@@ -609,7 +627,7 @@ public:
/// \param Size - The size of the zerofill symbol.
/// \param ByteAlignment - The alignment of the zerofill symbol if
/// non-zero. This must be a power of 2 on some targets.
- virtual void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ virtual void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0,
SMLoc Loc = SMLoc()) = 0;
@@ -620,7 +638,7 @@ public:
/// \param Size - The size of the symbol.
/// \param ByteAlignment - The alignment of the thread local common symbol
/// if non-zero. This must be a power of 2 on some targets.
- virtual void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
+ virtual void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment = 0);
/// @}
@@ -631,11 +649,11 @@ public:
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data);
+ virtual void emitBytes(StringRef Data);
/// Functionally identical to EmitBytes. When emitting textual assembly, this
/// method uses .byte directives instead of .ascii or .asciz for readability.
- virtual void EmitBinaryData(StringRef Data);
+ virtual void emitBinaryData(StringRef Data);
/// Emit the expression \p Value into the output as a native
/// integer of the given \p Size bytes.
@@ -647,37 +665,49 @@ public:
/// \param Size - The size of the integer (in bytes) to emit. This must
/// match a native machine width.
/// \param Loc - The location of the expression for error reporting.
- virtual void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ virtual void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc());
- void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc());
+ void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc());
/// Special case of EmitValue that avoids the client having
/// to pass in a MCExpr for constant integers.
- virtual void EmitIntValue(uint64_t Value, unsigned Size);
+ virtual void emitIntValue(uint64_t Value, unsigned Size);
/// Special case of EmitValue that avoids the client having to pass
/// in a MCExpr for constant integers & prints in Hex format for certain
/// modes.
- virtual void EmitIntValueInHex(uint64_t Value, unsigned Size) {
- EmitIntValue(Value, Size);
+ virtual void emitIntValueInHex(uint64_t Value, unsigned Size) {
+ emitIntValue(Value, Size);
+ }
+
+ void emitInt8(uint64_t Value) { emitIntValue(Value, 1); }
+ void emitInt16(uint64_t Value) { emitIntValue(Value, 2); }
+ void emitInt32(uint64_t Value) { emitIntValue(Value, 4); }
+ void emitInt64(uint64_t Value) { emitIntValue(Value, 8); }
+
+ /// Special case of EmitValue that avoids the client having to pass
+ /// in a MCExpr for constant integers & prints in Hex format for certain
+ /// modes, pads the field with leading zeros to Size width
+ virtual void emitIntValueInHexWithPadding(uint64_t Value, unsigned Size) {
+ emitIntValue(Value, Size);
}
- virtual void EmitULEB128Value(const MCExpr *Value);
+ virtual void emitULEB128Value(const MCExpr *Value);
- virtual void EmitSLEB128Value(const MCExpr *Value);
+ virtual void emitSLEB128Value(const MCExpr *Value);
/// Special case of EmitULEB128Value that avoids the client having to
/// pass in a MCExpr for constant integers.
- void EmitULEB128IntValue(uint64_t Value, unsigned PadTo = 0);
+ void emitULEB128IntValue(uint64_t Value, unsigned PadTo = 0);
/// Special case of EmitSLEB128Value that avoids the client having to
/// pass in a MCExpr for constant integers.
- void EmitSLEB128IntValue(int64_t Value);
+ void emitSLEB128IntValue(int64_t Value);
/// Special case of EmitValue that avoids the client having to pass in
/// a MCExpr for MCSymbols.
- void EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
+ void emitSymbolValue(const MCSymbol *Sym, unsigned Size,
bool IsSectionRelative = false);
/// Emit the expression \p Value into the output as a dtprel
@@ -685,42 +715,42 @@ public:
///
/// This is used to implement assembler directives such as .dtpreldword on
/// targets that support them.
- virtual void EmitDTPRel64Value(const MCExpr *Value);
+ virtual void emitDTPRel64Value(const MCExpr *Value);
/// Emit the expression \p Value into the output as a dtprel
/// (32-bit DTP relative) value.
///
/// This is used to implement assembler directives such as .dtprelword on
/// targets that support them.
- virtual void EmitDTPRel32Value(const MCExpr *Value);
+ virtual void emitDTPRel32Value(const MCExpr *Value);
/// Emit the expression \p Value into the output as a tprel
/// (64-bit TP relative) value.
///
/// This is used to implement assembler directives such as .tpreldword on
/// targets that support them.
- virtual void EmitTPRel64Value(const MCExpr *Value);
+ virtual void emitTPRel64Value(const MCExpr *Value);
/// Emit the expression \p Value into the output as a tprel
/// (32-bit TP relative) value.
///
/// This is used to implement assembler directives such as .tprelword on
/// targets that support them.
- virtual void EmitTPRel32Value(const MCExpr *Value);
+ virtual void emitTPRel32Value(const MCExpr *Value);
/// Emit the expression \p Value into the output as a gprel64 (64-bit
/// GP relative) value.
///
/// This is used to implement assembler directives such as .gpdword on
/// targets that support them.
- virtual void EmitGPRel64Value(const MCExpr *Value);
+ virtual void emitGPRel64Value(const MCExpr *Value);
/// Emit the expression \p Value into the output as a gprel32 (32-bit
/// GP relative) value.
///
/// This is used to implement assembler directives such as .gprel32 on
/// targets that support them.
- virtual void EmitGPRel32Value(const MCExpr *Value);
+ virtual void emitGPRel32Value(const MCExpr *Value);
/// Emit NumBytes bytes worth of the value specified by FillValue.
/// This implements directives such as '.space'.
@@ -749,7 +779,7 @@ public:
/// Emit NumBytes worth of zeros.
/// This function properly handles data in virtual sections.
- void EmitZeros(uint64_t NumBytes);
+ void emitZeros(uint64_t NumBytes);
/// Emit some number of copies of \p Value until the byte alignment \p
/// ByteAlignment is reached.
@@ -768,7 +798,7 @@ public:
/// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
- virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
+ virtual void emitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0,
unsigned ValueSize = 1,
unsigned MaxBytesToEmit = 0);
@@ -782,7 +812,7 @@ public:
/// \param MaxBytesToEmit - The maximum numbers of bytes to emit, or 0. If
/// the alignment cannot be reached in this many bytes, no bytes are
/// emitted.
- virtual void EmitCodeAlignment(unsigned ByteAlignment,
+ virtual void emitCodeAlignment(unsigned ByteAlignment,
unsigned MaxBytesToEmit = 0);
/// Emit some number of copies of \p Value until the byte offset \p
@@ -796,25 +826,19 @@ public:
virtual void emitValueToOffset(const MCExpr *Offset, unsigned char Value,
SMLoc Loc);
- virtual void
- EmitCodePaddingBasicBlockStart(const MCCodePaddingContext &Context) {}
-
- virtual void
- EmitCodePaddingBasicBlockEnd(const MCCodePaddingContext &Context) {}
-
/// @}
/// Switch to a new logical file. This is used to implement the '.file
/// "foo.c"' assembler directive.
- virtual void EmitFileDirective(StringRef Filename);
+ virtual void emitFileDirective(StringRef Filename);
/// Emit the "identifiers" directive. This implements the
/// '.ident "version foo"' assembler directive.
- virtual void EmitIdent(StringRef IdentString) {}
+ virtual void emitIdent(StringRef IdentString) {}
/// Associate a filename with a specified logical file number. This
/// implements the DWARF2 '.file 4 "foo.c"' assembler directive.
- unsigned EmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
+ unsigned emitDwarfFileDirective(unsigned FileNo, StringRef Directory,
StringRef Filename,
Optional<MD5::MD5Result> Checksum = None,
Optional<StringRef> Source = None,
@@ -840,11 +864,11 @@ public:
Optional<StringRef> Source,
unsigned CUID = 0);
- virtual void EmitCFIBKeyFrame();
+ virtual void emitCFIBKeyFrame();
/// This implements the DWARF2 '.loc fileno lineno ...' assembler
/// directive.
- virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
+ virtual void emitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa, unsigned Discriminator,
StringRef FileName);
@@ -866,19 +890,19 @@ public:
unsigned IACol, SMLoc Loc);
/// This implements the CodeView '.cv_loc' assembler directive.
- virtual void EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
+ virtual void emitCVLocDirective(unsigned FunctionId, unsigned FileNo,
unsigned Line, unsigned Column,
bool PrologueEnd, bool IsStmt,
StringRef FileName, SMLoc Loc);
/// This implements the CodeView '.cv_linetable' assembler directive.
- virtual void EmitCVLinetableDirective(unsigned FunctionId,
+ virtual void emitCVLinetableDirective(unsigned FunctionId,
const MCSymbol *FnStart,
const MCSymbol *FnEnd);
/// This implements the CodeView '.cv_inline_linetable' assembler
/// directive.
- virtual void EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
+ virtual void emitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
unsigned SourceFileId,
unsigned SourceLineNum,
const MCSymbol *FnStartSym,
@@ -886,35 +910,35 @@ public:
/// This implements the CodeView '.cv_def_range' assembler
/// directive.
- virtual void EmitCVDefRangeDirective(
+ virtual void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
StringRef FixedSizePortion);
- virtual void EmitCVDefRangeDirective(
+ virtual void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
codeview::DefRangeRegisterRelHeader DRHdr);
- virtual void EmitCVDefRangeDirective(
+ virtual void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
codeview::DefRangeSubfieldRegisterHeader DRHdr);
- virtual void EmitCVDefRangeDirective(
+ virtual void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
codeview::DefRangeRegisterHeader DRHdr);
- virtual void EmitCVDefRangeDirective(
+ virtual void emitCVDefRangeDirective(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
codeview::DefRangeFramePointerRelHeader DRHdr);
/// This implements the CodeView '.cv_stringtable' assembler directive.
- virtual void EmitCVStringTableDirective() {}
+ virtual void emitCVStringTableDirective() {}
/// This implements the CodeView '.cv_filechecksums' assembler directive.
- virtual void EmitCVFileChecksumsDirective() {}
+ virtual void emitCVFileChecksumsDirective() {}
/// This implements the CodeView '.cv_filechecksumoffset' assembler
/// directive.
- virtual void EmitCVFileChecksumOffsetDirective(unsigned FileNo) {}
+ virtual void emitCVFileChecksumOffsetDirective(unsigned FileNo) {}
/// This implements the CodeView '.cv_fpo_data' assembler directive.
virtual void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc Loc = {}) {}
@@ -930,29 +954,29 @@ public:
const MCSymbol *Lo);
virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
- virtual void EmitCFISections(bool EH, bool Debug);
- void EmitCFIStartProc(bool IsSimple, SMLoc Loc = SMLoc());
- void EmitCFIEndProc();
- virtual void EmitCFIDefCfa(int64_t Register, int64_t Offset);
- virtual void EmitCFIDefCfaOffset(int64_t Offset);
- virtual void EmitCFIDefCfaRegister(int64_t Register);
- virtual void EmitCFIOffset(int64_t Register, int64_t Offset);
- virtual void EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
- virtual void EmitCFILsda(const MCSymbol *Sym, unsigned Encoding);
- virtual void EmitCFIRememberState();
- virtual void EmitCFIRestoreState();
- virtual void EmitCFISameValue(int64_t Register);
- virtual void EmitCFIRestore(int64_t Register);
- virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
- virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
- virtual void EmitCFIEscape(StringRef Values);
- virtual void EmitCFIReturnColumn(int64_t Register);
- virtual void EmitCFIGnuArgsSize(int64_t Size);
- virtual void EmitCFISignalFrame();
- virtual void EmitCFIUndefined(int64_t Register);
- virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
- virtual void EmitCFIWindowSave();
- virtual void EmitCFINegateRAState();
+ virtual void emitCFISections(bool EH, bool Debug);
+ void emitCFIStartProc(bool IsSimple, SMLoc Loc = SMLoc());
+ void emitCFIEndProc();
+ virtual void emitCFIDefCfa(int64_t Register, int64_t Offset);
+ virtual void emitCFIDefCfaOffset(int64_t Offset);
+ virtual void emitCFIDefCfaRegister(int64_t Register);
+ virtual void emitCFIOffset(int64_t Register, int64_t Offset);
+ virtual void emitCFIPersonality(const MCSymbol *Sym, unsigned Encoding);
+ virtual void emitCFILsda(const MCSymbol *Sym, unsigned Encoding);
+ virtual void emitCFIRememberState();
+ virtual void emitCFIRestoreState();
+ virtual void emitCFISameValue(int64_t Register);
+ virtual void emitCFIRestore(int64_t Register);
+ virtual void emitCFIRelOffset(int64_t Register, int64_t Offset);
+ virtual void emitCFIAdjustCfaOffset(int64_t Adjustment);
+ virtual void emitCFIEscape(StringRef Values);
+ virtual void emitCFIReturnColumn(int64_t Register);
+ virtual void emitCFIGnuArgsSize(int64_t Size);
+ virtual void emitCFISignalFrame();
+ virtual void emitCFIUndefined(int64_t Register);
+ virtual void emitCFIRegister(int64_t Register1, int64_t Register2);
+ virtual void emitCFIWindowSave();
+ virtual void emitCFINegateRAState();
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
@@ -988,44 +1012,43 @@ public:
/// Get the .xdata section used for the given section.
MCSection *getAssociatedXDataSection(const MCSection *TextSec);
- virtual void EmitSyntaxDirective();
+ virtual void emitSyntaxDirective();
- /// Emit a .reloc directive.
- /// Returns true if the relocation could not be emitted because Name is not
- /// known.
- virtual bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
- const MCExpr *Expr, SMLoc Loc,
- const MCSubtargetInfo &STI) {
- return true;
+ /// Record a relocation described by the .reloc directive. Return None if
+ /// succeeded. Otherwise, return a pair (Name is invalid, error message).
+ virtual Optional<std::pair<bool, std::string>>
+ emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr,
+ SMLoc Loc, const MCSubtargetInfo &STI) {
+ return None;
}
- virtual void EmitAddrsig() {}
- virtual void EmitAddrsigSym(const MCSymbol *Sym) {}
+ virtual void emitAddrsig() {}
+ virtual void emitAddrsigSym(const MCSymbol *Sym) {}
/// Emit the given \p Instruction into the current section.
- virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
+ virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI);
/// Set the bundle alignment mode from now on in the section.
/// The argument is the power of 2 to which the alignment is set. The
/// value 0 means turn the bundle alignment off.
- virtual void EmitBundleAlignMode(unsigned AlignPow2);
+ virtual void emitBundleAlignMode(unsigned AlignPow2);
/// The following instructions are a bundle-locked group.
///
/// \param AlignToEnd - If true, the bundle-locked group will be aligned to
/// the end of a bundle.
- virtual void EmitBundleLock(bool AlignToEnd);
+ virtual void emitBundleLock(bool AlignToEnd);
/// Ends a bundle-locked group.
- virtual void EmitBundleUnlock();
+ virtual void emitBundleUnlock();
/// If this file is backed by a assembly streamer, this dumps the
/// specified string in the output .s file. This capability is indicated by
/// the hasRawTextSupport() predicate. By default this aborts.
- void EmitRawText(const Twine &String);
+ void emitRawText(const Twine &String);
/// Streamer specific finalization.
- virtual void FinishImpl();
+ virtual void finishImpl();
/// Finish emission of machine code.
void Finish();
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h
index 09130c4641ef..61cbb842502e 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSubtargetInfo.h
@@ -263,10 +263,17 @@ public:
///
virtual unsigned getMaxPrefetchIterationsAhead() const;
+ /// \return True if prefetching should also be done for writes.
+ ///
+ virtual bool enableWritePrefetching() const;
+
/// Return the minimum stride necessary to trigger software
/// prefetching.
///
- virtual unsigned getMinPrefetchStride() const;
+ virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
+ unsigned NumStridedMemAccesses,
+ unsigned NumPrefetches,
+ bool HasCall) const;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolWasm.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolWasm.h
index ba2068a46071..ffd8a7aad312 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolWasm.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolWasm.h
@@ -18,10 +18,11 @@ class MCSymbolWasm : public MCSymbol {
bool IsWeak = false;
bool IsHidden = false;
bool IsComdat = false;
+ mutable bool IsUsedInInitArray = false;
mutable bool IsUsedInGOT = false;
- Optional<std::string> ImportModule;
- Optional<std::string> ImportName;
- Optional<std::string> ExportName;
+ Optional<StringRef> ImportModule;
+ Optional<StringRef> ImportName;
+ Optional<StringRef> ExportName;
wasm::WasmSignature *Signature = nullptr;
Optional<wasm::WasmGlobalType> GlobalType;
Optional<wasm::WasmEventType> EventType;
@@ -31,8 +32,6 @@ class MCSymbolWasm : public MCSymbol {
const MCExpr *SymbolSize = nullptr;
public:
- // Use a module name of "env" for now, for compatibility with existing tools.
- // This is temporary, and may change, as the ABI is not yet stable.
MCSymbolWasm(const StringMapEntry<bool> *Name, bool isTemporary)
: MCSymbol(SymbolKindWasm, Name, isTemporary) {}
static bool classof(const MCSymbol *S) { return S->isWasm(); }
@@ -71,30 +70,36 @@ public:
bool isComdat() const { return IsComdat; }
void setComdat(bool isComdat) { IsComdat = isComdat; }
- const StringRef getImportModule() const {
- if (ImportModule.hasValue()) {
- return ImportModule.getValue();
- }
- return "env";
+ bool hasImportModule() const { return ImportModule.hasValue(); }
+ StringRef getImportModule() const {
+ if (ImportModule.hasValue())
+ return ImportModule.getValue();
+ // Use a default module name of "env" for now, for compatibility with
+ // existing tools.
+ // TODO(sbc): Find a way to specify a default value in the object format
+ // without picking a hardcoded value like this.
+ return "env";
}
void setImportModule(StringRef Name) { ImportModule = Name; }
bool hasImportName() const { return ImportName.hasValue(); }
- const StringRef getImportName() const {
- if (ImportName.hasValue()) {
- return ImportName.getValue();
- }
- return getName();
+ StringRef getImportName() const {
+ if (ImportName.hasValue())
+ return ImportName.getValue();
+ return getName();
}
void setImportName(StringRef Name) { ImportName = Name; }
bool hasExportName() const { return ExportName.hasValue(); }
- const StringRef getExportName() const { return ExportName.getValue(); }
+ StringRef getExportName() const { return ExportName.getValue(); }
void setExportName(StringRef Name) { ExportName = Name; }
void setUsedInGOT() const { IsUsedInGOT = true; }
bool isUsedInGOT() const { return IsUsedInGOT; }
+ void setUsedInInitArray() const { IsUsedInInitArray = true; }
+ bool isUsedInInitArray() const { return IsUsedInInitArray; }
+
const wasm::WasmSignature *getSignature() const { return Signature; }
void setSignature(wasm::WasmSignature *Sig) { Signature = Sig; }
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolXCOFF.h b/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolXCOFF.h
index 07dfb5d29977..d0379ec08b7d 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolXCOFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCSymbolXCOFF.h
@@ -24,6 +24,16 @@ public:
static bool classof(const MCSymbol *S) { return S->isXCOFF(); }
+ static StringRef getUnqualifiedName(StringRef Name) {
+ if (Name.back() == ']') {
+ StringRef Lhs, Rhs;
+ std::tie(Lhs, Rhs) = Name.rsplit('[');
+ assert(!Rhs.empty() && "Invalid SMC format in XCOFF symbol.");
+ return Lhs;
+ }
+ return Name;
+ }
+
void setStorageClass(XCOFF::StorageClass SC) {
assert((!StorageClass.hasValue() || StorageClass.getValue() == SC) &&
"Redefining StorageClass of XCOFF MCSymbol.");
@@ -36,35 +46,33 @@ public:
return StorageClass.getValue();
}
- void setContainingCsect(MCSectionXCOFF *C) {
- assert((!ContainingCsect || ContainingCsect == C) &&
- "Trying to set a containing csect that doesn't match the one that"
- "this symbol is already mapped to.");
- ContainingCsect = C;
- }
+ StringRef getUnqualifiedName() const { return getUnqualifiedName(getName()); }
- MCSectionXCOFF *getContainingCsect() const {
- assert(ContainingCsect &&
- "Trying to get containing csect but none was set.");
- return ContainingCsect;
- }
+ bool hasRepresentedCsectSet() const { return RepresentedCsect != nullptr; }
- bool hasContainingCsect() const { return ContainingCsect != nullptr; }
+ MCSectionXCOFF *getRepresentedCsect() const;
- StringRef getUnqualifiedName() const {
- const StringRef name = getName();
- if (name.back() == ']') {
- StringRef lhs, rhs;
- std::tie(lhs, rhs) = name.rsplit('[');
- assert(!rhs.empty() && "Invalid SMC format in XCOFF symbol.");
- return lhs;
- }
- return name;
+ void setRepresentedCsect(MCSectionXCOFF *C);
+
+ void setVisibilityType(XCOFF::VisibilityType SVT) { VisibilityType = SVT; };
+
+ XCOFF::VisibilityType getVisibilityType() const { return VisibilityType; }
+
+ bool hasRename() const { return !SymbolTableName.empty(); }
+
+ void setSymbolTableName(StringRef STN) { SymbolTableName = STN; }
+
+ StringRef getSymbolTableName() const {
+ if (hasRename())
+ return SymbolTableName;
+ return getUnqualifiedName();
}
private:
Optional<XCOFF::StorageClass> StorageClass;
- MCSectionXCOFF *ContainingCsect = nullptr;
+ MCSectionXCOFF *RepresentedCsect = nullptr;
+ XCOFF::VisibilityType VisibilityType = XCOFF::SYM_V_UNSPECIFIED;
+ StringRef SymbolTableName;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptions.h b/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptions.h
index 51a5fc9aa26a..4b786751dbd1 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptions.h
@@ -9,6 +9,7 @@
#ifndef LLVM_MC_MCTARGETOPTIONS_H
#define LLVM_MC_MCTARGETOPTIONS_H
+#include "llvm/ADT/ArrayRef.h"
#include <string>
#include <vector>
@@ -53,11 +54,16 @@ public:
/// Preserve Comments in Assembly.
bool PreserveAsmComments : 1;
+ bool Dwarf64 : 1;
int DwarfVersion = 0;
std::string ABIName;
+ std::string AssemblyLanguage;
std::string SplitDwarfFile;
+ const char *Argv0 = nullptr;
+ ArrayRef<const char *> CommandLineArgs;
+
/// Additional paths to search for `.include` directives when using the
/// integrated assembler.
std::vector<std::string> IASSearchPaths;
@@ -68,6 +74,11 @@ public:
/// textual name of the ABI that we want the backend to use, e.g. o32, or
/// aapcs-linux.
StringRef getABIName() const;
+
+ /// getAssemblyLanguage - If this returns a non-empty string this represents
+ /// the textual name of the assembly language that we will use for this
+ /// target, e.g. masm.
+ StringRef getAssemblyLanguage() const;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
new file mode 100644
index 000000000000..6d3c477e4b73
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -0,0 +1,57 @@
+//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains machine code-specific flags that are shared between
+// different command line tools.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
+
+#include "llvm/ADT/Optional.h"
+#include <string>
+
+namespace llvm {
+
+class MCTargetOptions;
+
+namespace mc {
+
+bool getRelaxAll();
+Optional<bool> getExplicitRelaxAll();
+
+bool getIncrementalLinkerCompatible();
+
+int getDwarfVersion();
+
+bool getDwarf64();
+
+bool getShowMCInst();
+
+bool getFatalWarnings();
+
+bool getNoWarn();
+
+bool getNoDeprecatedWarn();
+
+std::string getABIName();
+
+/// Create this object with static storage to register mc-related command
+/// line options.
+struct RegisterMCTargetOptionsFlags {
+ RegisterMCTargetOptionsFlags();
+};
+
+MCTargetOptions InitMCTargetOptionsFromFlags();
+
+} // namespace mc
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc b/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc
deleted file mode 100644
index 93e21b626eac..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.inc
+++ /dev/null
@@ -1,65 +0,0 @@
-//===-- MCTargetOptionsCommandFlags.h --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains machine code-specific flags that are shared between
-// different command line tools.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
-#define LLVM_MC_MCTARGETOPTIONSCOMMANDFLAGS_H
-
-#include "llvm/MC/MCTargetOptions.h"
-#include "llvm/Support/CommandLine.h"
-using namespace llvm;
-
-static cl::opt<bool> RelaxAll("mc-relax-all",
- cl::desc("When used with filetype=obj, "
- "relax all fixups in the emitted object file"));
-
-static cl::opt<bool> IncrementalLinkerCompatible(
- "incremental-linker-compatible",
- cl::desc(
- "When used with filetype=obj, "
- "emit an object file which can be used with an incremental linker"));
-
-static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
- cl::init(0));
-
-static cl::opt<bool> ShowMCInst("asm-show-inst",
- cl::desc("Emit internal instruction representation to "
- "assembly file"));
-
-static cl::opt<bool> FatalWarnings("fatal-warnings",
- cl::desc("Treat warnings as errors"));
-
-static cl::opt<bool> NoWarn("no-warn", cl::desc("Suppress all warnings"));
-static cl::alias NoWarnW("W", cl::desc("Alias for --no-warn"), cl::aliasopt(NoWarn));
-
-static cl::opt<bool> NoDeprecatedWarn("no-deprecated-warn",
- cl::desc("Suppress all deprecated warnings"));
-
-static cl::opt<std::string>
-ABIName("target-abi", cl::Hidden,
- cl::desc("The name of the ABI to be targeted from the backend."),
- cl::init(""));
-
-static MCTargetOptions InitMCTargetOptionsFromFlags() {
- MCTargetOptions Options;
- Options.MCRelaxAll = RelaxAll;
- Options.MCIncrementalLinkerCompatible = IncrementalLinkerCompatible;
- Options.DwarfVersion = DwarfVersion;
- Options.ShowMCInst = ShowMCInst;
- Options.ABIName = ABIName;
- Options.MCFatalWarnings = FatalWarnings;
- Options.MCNoWarn = NoWarn;
- Options.MCNoDeprecatedWarn = NoDeprecatedWarn;
- return Options;
-}
-
-#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCValue.h b/contrib/llvm-project/llvm/include/llvm/MC/MCValue.h
index 0be7ce7055c5..37feee4c9ea8 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCValue.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCValue.h
@@ -14,12 +14,10 @@
#define LLVM_MC_MCVALUE_H
#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
namespace llvm {
-class MCAsmInfo;
class raw_ostream;
/// This represents an "assembler immediate".
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCWasmObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCWasmObjectWriter.h
index fbb68549b503..382818ad6867 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCWasmObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCWasmObjectWriter.h
@@ -28,7 +28,7 @@ protected:
public:
virtual ~MCWasmObjectTargetWriter();
- virtual Triple::ObjectFormatType getFormat() const { return Triple::Wasm; }
+ Triple::ObjectFormatType getFormat() const override { return Triple::Wasm; }
static bool classof(const MCObjectTargetWriter *W) {
return W->getFormat() == Triple::Wasm;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCWasmStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCWasmStreamer.h
index 2d7f2b9975c9..61075e7a5732 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCWasmStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCWasmStreamer.h
@@ -11,18 +11,14 @@
#include "MCAsmBackend.h"
#include "MCCodeEmitter.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCObjectStreamer.h"
#include "llvm/MC/MCObjectWriter.h"
-#include "llvm/MC/SectionKind.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
-class MCAssembler;
class MCExpr;
class MCInst;
-class raw_ostream;
class MCWasmStreamer : public MCObjectStreamer {
public:
@@ -44,37 +40,37 @@ public:
/// \name MCStreamer Interface
/// @{
- void ChangeSection(MCSection *Section, const MCExpr *Subsection) override;
- void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
- void EmitThumbFunc(MCSymbol *Func) override;
- void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
- bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
- void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void changeSection(MCSection *Section, const MCExpr *Subsection) override;
+ void emitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void emitThumbFunc(MCSymbol *Func) override;
+ void emitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override;
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
void emitELFSize(MCSymbol *Symbol, const MCExpr *Value) override;
- void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0,
SMLoc Loc = SMLoc()) override;
- void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment = 0) override;
- void EmitValueImpl(const MCExpr *Value, unsigned Size,
+ void emitValueImpl(const MCExpr *Value, unsigned Size,
SMLoc Loc = SMLoc()) override;
- void EmitIdent(StringRef IdentString) override;
+ void emitIdent(StringRef IdentString) override;
- void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
+ void emitValueToAlignment(unsigned, int64_t, unsigned, unsigned) override;
- void FinishImpl() override;
+ void finishImpl() override;
private:
- void EmitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
- void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
/// Merge the content of the fragment \p EF into the fragment \p DF.
void mergeFragment(MCDataFragment *, MCDataFragment *);
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
index 3fe124fd7f1c..3015efe7389e 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFObjectWriter.h
@@ -31,7 +31,7 @@ class raw_pwrite_stream;
public:
virtual ~MCWinCOFFObjectTargetWriter() = default;
- virtual Triple::ObjectFormatType getFormat() const { return Triple::COFF; }
+ Triple::ObjectFormatType getFormat() const override { return Triple::COFF; }
static bool classof(const MCObjectTargetWriter *W) {
return W->getFormat() == Triple::COFF;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFStreamer.h
index c1c1ec56cb48..1236304b9e5d 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCWinCOFFStreamer.h
@@ -40,11 +40,11 @@ public:
/// \{
void InitSections(bool NoExecStack) override;
- void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
- void EmitAssemblerFlag(MCAssemblerFlag Flag) override;
- void EmitThumbFunc(MCSymbol *Func) override;
- bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
+ void emitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
+ void emitAssemblerFlag(MCAssemblerFlag Flag) override;
+ void emitThumbFunc(MCSymbol *Func) override;
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void emitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) override;
void BeginCOFFSymbolDef(MCSymbol const *Symbol) override;
void EmitCOFFSymbolStorageClass(int StorageClass) override;
void EmitCOFFSymbolType(int Type) override;
@@ -54,24 +54,29 @@ public:
void EmitCOFFSectionIndex(MCSymbol const *Symbol) override;
void EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) override;
void EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) override;
- void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ void emitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment, SMLoc Loc = SMLoc()) override;
- void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
+ void emitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitIdent(StringRef IdentString) override;
+ void emitIdent(StringRef IdentString) override;
void EmitWinEHHandlerData(SMLoc Loc) override;
- void FinishImpl() override;
+ void emitCGProfileEntry(const MCSymbolRefExpr *From,
+ const MCSymbolRefExpr *To, uint64_t Count) override;
+ void finishImpl() override;
/// \}
protected:
const MCSymbol *CurSymbol;
- void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+
+ void finalizeCGProfileEntry(const MCSymbolRefExpr *&S);
+ void finalizeCGProfile();
private:
void Error(const Twine &Msg) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFObjectWriter.h b/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFObjectWriter.h
index fe4087f70614..faad2ceb2691 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFObjectWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFObjectWriter.h
@@ -28,6 +28,13 @@ public:
}
bool is64Bit() const { return Is64Bit; }
+ // Returns relocation info such as type, sign and size.
+ // First element of the pair contains type,
+ // second element contains sign and size.
+ virtual std::pair<uint8_t, uint8_t>
+ getRelocTypeAndSignSize(const MCValue &Target, const MCFixup &Fixup,
+ bool IsPCRel) const = 0;
+
private:
bool Is64Bit;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFStreamer.h b/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFStreamer.h
index f6f8e56977d3..5fc2efbe5284 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFStreamer.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/MCXCOFFStreamer.h
@@ -19,16 +19,24 @@ public:
std::unique_ptr<MCObjectWriter> OW,
std::unique_ptr<MCCodeEmitter> Emitter);
- bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
- void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override;
+ void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
unsigned ByteAlignment) override;
- void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
+ void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
uint64_t Size = 0, unsigned ByteAlignment = 0,
SMLoc Loc = SMLoc()) override;
- void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
- void EmitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
+ void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override;
+ void emitXCOFFLocalCommonSymbol(MCSymbol *LabelSym, uint64_t Size,
MCSymbol *CsectSym,
unsigned ByteAlign) override;
+ void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
+ MCSymbolAttr Linkage,
+ MCSymbolAttr Visibility) override;
+ void emitXCOFFRenameDirective(const MCSymbol *Name,
+ StringRef Rename) override {
+ report_fatal_error("emitXCOFFRenameDirective is not implemented yet on "
+ "object generation path");
+ }
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/StringTableBuilder.h b/contrib/llvm-project/llvm/include/llvm/MC/StringTableBuilder.h
index c8d4c3bbc262..d8bfac03f7f2 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/StringTableBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/StringTableBuilder.h
@@ -59,6 +59,16 @@ public:
return getOffset(CachedHashStringRef(S));
}
+ /// Check if a string is contained in the string table. Since this class
+ /// doesn't store the string values, this function can be used to check if
+ /// storage needs to be done prior to adding the string.
+ bool contains(StringRef S) const {
+ return contains(CachedHashStringRef(S));
+ }
+ bool contains(CachedHashStringRef S) const {
+ return StringIndexMap.count(S);
+ }
+
size_t getSize() const { return Size; }
void clear();
diff --git a/contrib/llvm-project/llvm/include/llvm/MC/SubtargetFeature.h b/contrib/llvm-project/llvm/include/llvm/MC/SubtargetFeature.h
index defbc3c64720..01ea794a4bc3 100644
--- a/contrib/llvm-project/llvm/include/llvm/MC/SubtargetFeature.h
+++ b/contrib/llvm-project/llvm/include/llvm/MC/SubtargetFeature.h
@@ -214,7 +214,7 @@ public:
}
/// Return string stripped of flag.
- static std::string StripFlag(StringRef Feature) {
+ static StringRef StripFlag(StringRef Feature) {
return hasFlag(Feature) ? Feature.substr(1) : Feature;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/CodeEmitter.h b/contrib/llvm-project/llvm/include/llvm/MCA/CodeEmitter.h
index c8d222bd8c2f..edbadcc8fafa 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/CodeEmitter.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/CodeEmitter.h
@@ -20,11 +20,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCCodeEmitter.h"
-#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MCA/Instruction.h"
-#include "llvm/MCA/Support.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/LSUnit.h b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/LSUnit.h
index 34903794db4a..2f9b4ba8782d 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/LSUnit.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/LSUnit.h
@@ -24,8 +24,6 @@
namespace llvm {
namespace mca {
-class Scheduler;
-
/// A node of a memory dependency graph. A MemoryGroup describes a set of
/// instructions with same memory dependencies.
///
@@ -42,7 +40,10 @@ class MemoryGroup {
unsigned NumInstructions;
unsigned NumExecuting;
unsigned NumExecuted;
- SmallVector<MemoryGroup *, 4> Succ;
+ // Successors that are in a order dependency with this group.
+ SmallVector<MemoryGroup *, 4> OrderSucc;
+ // Successors that are in a data dependency with this group.
+ SmallVector<MemoryGroup *, 4> DataSucc;
CriticalDependency CriticalPredecessor;
InstRef CriticalMemoryInstruction;
@@ -57,8 +58,9 @@ public:
NumExecuted(0), CriticalPredecessor(), CriticalMemoryInstruction() {}
MemoryGroup(MemoryGroup &&) = default;
- ArrayRef<MemoryGroup *> getSuccessors() const { return Succ; }
- unsigned getNumSuccessors() const { return Succ.size(); }
+ size_t getNumSuccessors() const {
+ return OrderSucc.size() + DataSucc.size();
+ }
unsigned getNumPredecessors() const { return NumPredecessors; }
unsigned getNumExecutingPredecessors() const {
return NumExecutingPredecessors;
@@ -77,12 +79,22 @@ public:
return CriticalPredecessor;
}
- void addSuccessor(MemoryGroup *Group) {
+ void addSuccessor(MemoryGroup *Group, bool IsDataDependent) {
+ // Do not need to add a dependency if there is no data
+ // dependency and all instructions from this group have been
+ // issued already.
+ if (!IsDataDependent && isExecuting())
+ return;
+
Group->NumPredecessors++;
assert(!isExecuted() && "Should have been removed!");
if (isExecuting())
- Group->onGroupIssued(CriticalMemoryInstruction);
- Succ.emplace_back(Group);
+ Group->onGroupIssued(CriticalMemoryInstruction, IsDataDependent);
+
+ if (IsDataDependent)
+ DataSucc.emplace_back(Group);
+ else
+ OrderSucc.emplace_back(Group);
}
bool isWaiting() const {
@@ -100,10 +112,13 @@ public:
}
bool isExecuted() const { return NumInstructions == NumExecuted; }
- void onGroupIssued(const InstRef &IR) {
+ void onGroupIssued(const InstRef &IR, bool ShouldUpdateCriticalDep) {
assert(!isReady() && "Unexpected group-start event!");
NumExecutingPredecessors++;
+ if (!ShouldUpdateCriticalDep)
+ return;
+
unsigned Cycles = IR.getInstruction()->getCyclesLeft();
if (CriticalPredecessor.Cycles < Cycles) {
CriticalPredecessor.IID = IR.getSourceIndex();
@@ -135,8 +150,14 @@ public:
return;
// Notify successors that this group started execution.
- for (MemoryGroup *MG : Succ)
- MG->onGroupIssued(CriticalMemoryInstruction);
+ for (MemoryGroup *MG : OrderSucc) {
+ MG->onGroupIssued(CriticalMemoryInstruction, false);
+ // Release the order dependency with this group.
+ MG->onGroupExecuted();
+ }
+
+ for (MemoryGroup *MG : DataSucc)
+ MG->onGroupIssued(CriticalMemoryInstruction, true);
}
void onInstructionExecuted() {
@@ -147,8 +168,8 @@ public:
if (!isExecuted())
return;
- // Notify successors that this group has finished execution.
- for (MemoryGroup *MG : Succ)
+ // Notify data dependent successors that this group has finished execution.
+ for (MemoryGroup *MG : DataSucc)
MG->onGroupExecuted();
}
@@ -414,6 +435,7 @@ class LSUnit : public LSUnitBase {
unsigned CurrentLoadGroupID;
unsigned CurrentLoadBarrierGroupID;
unsigned CurrentStoreGroupID;
+ unsigned CurrentStoreBarrierGroupID;
public:
LSUnit(const MCSchedModel &SM)
@@ -422,7 +444,8 @@ public:
: LSUnit(SM, LQ, SQ, /* NoAlias */ false) {}
LSUnit(const MCSchedModel &SM, unsigned LQ, unsigned SQ, bool AssumeNoAlias)
: LSUnitBase(SM, LQ, SQ, AssumeNoAlias), CurrentLoadGroupID(0),
- CurrentLoadBarrierGroupID(0), CurrentStoreGroupID(0) {}
+ CurrentLoadBarrierGroupID(0), CurrentStoreGroupID(0),
+ CurrentStoreBarrierGroupID(0) {}
/// Returns LSU_AVAILABLE if there are enough load/store queue entries to
/// accomodate instruction IR.
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h
index cd7718d98744..e8ca34854295 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/RegisterFile.h
@@ -22,7 +22,6 @@
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MCA/HardwareUnits/HardwareUnit.h"
-#include "llvm/Support/Error.h"
namespace llvm {
namespace mca {
@@ -84,7 +83,7 @@ class RegisterFile : public HardwareUnit {
// the target name).
//
// Users can limit the number of physical registers that are available in
- // regsiter file #0 specifying command line flag `-register-file-size=<uint>`.
+ // register file #0 specifying command line flag `-register-file-size=<uint>`.
SmallVector<RegisterMappingTracker, 4> RegisterFiles;
// This type is used to propagate information about the owner of a register,
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
index 917af3750044..b6d4e345da2c 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/HardwareUnits/ResourceManager.h
@@ -15,7 +15,6 @@
#ifndef LLVM_MCA_RESOURCE_MANAGER_H
#define LLVM_MCA_RESOURCE_MANAGER_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCSchedule.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/Pipeline.h b/contrib/llvm-project/llvm/include/llvm/MCA/Pipeline.h
index 935033f67f8b..0ac988c52dc1 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/Pipeline.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/Pipeline.h
@@ -15,8 +15,6 @@
#ifndef LLVM_MCA_PIPELINE_H
#define LLVM_MCA_PIPELINE_H
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/MCA/HardwareUnits/Scheduler.h"
#include "llvm/MCA/Stages/Stage.h"
#include "llvm/Support/Error.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/MCA/Stages/DispatchStage.h b/contrib/llvm-project/llvm/include/llvm/MCA/Stages/DispatchStage.h
index d80ededeaca1..597f7312448d 100644
--- a/contrib/llvm-project/llvm/include/llvm/MCA/Stages/DispatchStage.h
+++ b/contrib/llvm-project/llvm/include/llvm/MCA/Stages/DispatchStage.h
@@ -20,7 +20,6 @@
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/MCA/HWEventListener.h"
#include "llvm/MCA/HardwareUnits/RegisterFile.h"
#include "llvm/MCA/HardwareUnits/RetireControlUnit.h"
#include "llvm/MCA/Instruction.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ArchiveWriter.h b/contrib/llvm-project/llvm/include/llvm/Object/ArchiveWriter.h
index 9e6daf2da36e..274ffd90c05a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ArchiveWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ArchiveWriter.h
@@ -13,10 +13,7 @@
#ifndef LLVM_OBJECT_ARCHIVEWRITER_H
#define LLVM_OBJECT_ARCHIVEWRITER_H
-#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Archive.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/Binary.h b/contrib/llvm-project/llvm/include/llvm/Object/Binary.h
index aa5e718f5e9b..e95516f30a40 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/Binary.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/Binary.h
@@ -160,14 +160,14 @@ public:
return Triple::UnknownObjectFormat;
}
- static std::error_code checkOffset(MemoryBufferRef M, uintptr_t Addr,
- const uint64_t Size) {
+ static Error checkOffset(MemoryBufferRef M, uintptr_t Addr,
+ const uint64_t Size) {
if (Addr + Size < Addr || Addr + Size < Size ||
Addr + Size > uintptr_t(M.getBufferEnd()) ||
Addr < uintptr_t(M.getBufferStart())) {
- return object_error::unexpected_eof;
+ return errorCodeToError(object_error::unexpected_eof);
}
- return std::error_code();
+ return Error::success();
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/COFF.h b/contrib/llvm-project/llvm/include/llvm/Object/COFF.h
index b91ee5887fec..8aef00a8809d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/COFF.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/COFF.h
@@ -764,6 +764,8 @@ struct debug_h_header {
class COFFObjectFile : public ObjectFile {
private:
+ COFFObjectFile(MemoryBufferRef Object);
+
friend class ImportDirectoryEntryRef;
friend class ExportDirectoryEntryRef;
const coff_file_header *COFFHeader;
@@ -787,22 +789,28 @@ private:
// Either coff_load_configuration32 or coff_load_configuration64.
const void *LoadConfig = nullptr;
- std::error_code getString(uint32_t offset, StringRef &Res) const;
+ Expected<StringRef> getString(uint32_t offset) const;
template <typename coff_symbol_type>
const coff_symbol_type *toSymb(DataRefImpl Symb) const;
const coff_section *toSec(DataRefImpl Sec) const;
const coff_relocation *toRel(DataRefImpl Rel) const;
- std::error_code initSymbolTablePtr();
- std::error_code initImportTablePtr();
- std::error_code initDelayImportTablePtr();
- std::error_code initExportTablePtr();
- std::error_code initBaseRelocPtr();
- std::error_code initDebugDirectoryPtr();
- std::error_code initLoadConfigPtr();
+ // Finish initializing the object and return success or an error.
+ Error initialize();
+
+ Error initSymbolTablePtr();
+ Error initImportTablePtr();
+ Error initDelayImportTablePtr();
+ Error initExportTablePtr();
+ Error initBaseRelocPtr();
+ Error initDebugDirectoryPtr();
+ Error initLoadConfigPtr();
public:
+ static Expected<std::unique_ptr<COFFObjectFile>>
+ create(MemoryBufferRef Object);
+
uintptr_t getSymbolTable() const {
if (SymbolTable16)
return reinterpret_cast<uintptr_t>(SymbolTable16);
@@ -878,6 +886,8 @@ public:
return getRawNumberOfSymbols();
}
+ uint32_t getStringTableSize() const { return StringTableSize; }
+
const coff_load_configuration32 *getLoadConfig32() const {
assert(!is64());
return reinterpret_cast<const coff_load_configuration32 *>(LoadConfig);
@@ -896,7 +906,7 @@ protected:
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
void moveSectionNext(DataRefImpl &Sec) const override;
@@ -912,6 +922,7 @@ protected:
bool isSectionData(DataRefImpl Sec) const override;
bool isSectionBSS(DataRefImpl Sec) const override;
bool isSectionVirtual(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
@@ -923,8 +934,6 @@ protected:
SmallVectorImpl<char> &Result) const override;
public:
- COFFObjectFile(MemoryBufferRef Object, std::error_code &EC);
-
basic_symbol_iterator symbol_begin() const override;
basic_symbol_iterator symbol_end() const override;
section_iterator section_begin() const override;
@@ -980,49 +989,30 @@ public:
const pe32_header *getPE32Header() const { return PE32Header; }
const pe32plus_header *getPE32PlusHeader() const { return PE32PlusHeader; }
- std::error_code getDataDirectory(uint32_t index,
- const data_directory *&Res) const;
- std::error_code getSection(int32_t index, const coff_section *&Res) const;
- std::error_code getSection(StringRef SectionName,
- const coff_section *&Res) const;
-
- template <typename coff_symbol_type>
- std::error_code getSymbol(uint32_t Index,
- const coff_symbol_type *&Res) const {
- if (Index >= getNumberOfSymbols())
- return object_error::parse_failed;
+ const data_directory *getDataDirectory(uint32_t index) const;
+ Expected<const coff_section *> getSection(int32_t index) const;
- Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index;
- return std::error_code();
- }
Expected<COFFSymbolRef> getSymbol(uint32_t index) const {
- if (SymbolTable16) {
- const coff_symbol16 *Symb = nullptr;
- if (std::error_code EC = getSymbol(index, Symb))
- return errorCodeToError(EC);
- return COFFSymbolRef(Symb);
- }
- if (SymbolTable32) {
- const coff_symbol32 *Symb = nullptr;
- if (std::error_code EC = getSymbol(index, Symb))
- return errorCodeToError(EC);
- return COFFSymbolRef(Symb);
- }
+ if (index >= getNumberOfSymbols())
+ return errorCodeToError(object_error::parse_failed);
+ if (SymbolTable16)
+ return COFFSymbolRef(SymbolTable16 + index);
+ if (SymbolTable32)
+ return COFFSymbolRef(SymbolTable32 + index);
return errorCodeToError(object_error::parse_failed);
}
template <typename T>
- std::error_code getAuxSymbol(uint32_t index, const T *&Res) const {
+ Error getAuxSymbol(uint32_t index, const T *&Res) const {
Expected<COFFSymbolRef> S = getSymbol(index);
if (Error E = S.takeError())
- return errorToErrorCode(std::move(E));
+ return E;
Res = reinterpret_cast<const T *>(S->getRawPtr());
- return std::error_code();
+ return Error::success();
}
- std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const;
- std::error_code getSymbolName(const coff_symbol_generic *Symbol,
- StringRef &Res) const;
+ Expected<StringRef> getSymbolName(COFFSymbolRef Symbol) const;
+ Expected<StringRef> getSymbolName(const coff_symbol_generic *Symbol) const;
ArrayRef<uint8_t> getSymbolAuxData(COFFSymbolRef Symbol) const;
@@ -1044,29 +1034,29 @@ public:
ArrayRef<uint8_t> &Res) const;
uint64_t getImageBase() const;
- std::error_code getVaPtr(uint64_t VA, uintptr_t &Res) const;
- std::error_code getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
+ Error getVaPtr(uint64_t VA, uintptr_t &Res) const;
+ Error getRvaPtr(uint32_t Rva, uintptr_t &Res) const;
/// Given an RVA base and size, returns a valid array of bytes or an error
/// code if the RVA and size is not contained completely within a valid
/// section.
- std::error_code getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
- ArrayRef<uint8_t> &Contents) const;
+ Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
+ ArrayRef<uint8_t> &Contents) const;
- std::error_code getHintName(uint32_t Rva, uint16_t &Hint,
+ Error getHintName(uint32_t Rva, uint16_t &Hint,
StringRef &Name) const;
/// Get PDB information out of a codeview debug directory entry.
- std::error_code getDebugPDBInfo(const debug_directory *DebugDir,
- const codeview::DebugInfo *&Info,
- StringRef &PDBFileName) const;
+ Error getDebugPDBInfo(const debug_directory *DebugDir,
+ const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
/// Get PDB information from an executable. If the information is not present,
/// Info will be set to nullptr and PDBFileName will be empty. An error is
/// returned only on corrupt object files. Convenience accessor that can be
/// used if the debug directory is not already handy.
- std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info,
- StringRef &PDBFileName) const;
+ Error getDebugPDBInfo(const codeview::DebugInfo *&Info,
+ StringRef &PDBFileName) const;
bool isRelocatableObject() const override;
bool is64() const { return PE32PlusHeader; }
@@ -1095,11 +1085,11 @@ public:
imported_symbol_iterator lookup_table_end() const;
iterator_range<imported_symbol_iterator> lookup_table_symbols() const;
- std::error_code getName(StringRef &Result) const;
- std::error_code getImportLookupTableRVA(uint32_t &Result) const;
- std::error_code getImportAddressTableRVA(uint32_t &Result) const;
+ Error getName(StringRef &Result) const;
+ Error getImportLookupTableRVA(uint32_t &Result) const;
+ Error getImportAddressTableRVA(uint32_t &Result) const;
- std::error_code
+ Error
getImportTableEntry(const coff_import_directory_table_entry *&Result) const;
private:
@@ -1122,10 +1112,10 @@ public:
imported_symbol_iterator imported_symbol_end() const;
iterator_range<imported_symbol_iterator> imported_symbols() const;
- std::error_code getName(StringRef &Result) const;
- std::error_code getDelayImportTable(
+ Error getName(StringRef &Result) const;
+ Error getDelayImportTable(
const delay_import_directory_table_entry *&Result) const;
- std::error_code getImportAddress(int AddrIndex, uint64_t &Result) const;
+ Error getImportAddress(int AddrIndex, uint64_t &Result) const;
private:
const delay_import_directory_table_entry *Table;
@@ -1144,14 +1134,14 @@ public:
bool operator==(const ExportDirectoryEntryRef &Other) const;
void moveNext();
- std::error_code getDllName(StringRef &Result) const;
- std::error_code getOrdinalBase(uint32_t &Result) const;
- std::error_code getOrdinal(uint32_t &Result) const;
- std::error_code getExportRVA(uint32_t &Result) const;
- std::error_code getSymbolName(StringRef &Result) const;
+ Error getDllName(StringRef &Result) const;
+ Error getOrdinalBase(uint32_t &Result) const;
+ Error getOrdinal(uint32_t &Result) const;
+ Error getExportRVA(uint32_t &Result) const;
+ Error getSymbolName(StringRef &Result) const;
- std::error_code isForwarder(bool &Result) const;
- std::error_code getForwardTo(StringRef &Result) const;
+ Error isForwarder(bool &Result) const;
+ Error getForwardTo(StringRef &Result) const;
private:
const export_directory_table_entry *ExportTable;
@@ -1172,10 +1162,10 @@ public:
bool operator==(const ImportedSymbolRef &Other) const;
void moveNext();
- std::error_code getSymbolName(StringRef &Result) const;
- std::error_code isOrdinal(bool &Result) const;
- std::error_code getOrdinal(uint16_t &Result) const;
- std::error_code getHintNameRVA(uint32_t &Result) const;
+ Error getSymbolName(StringRef &Result) const;
+ Error isOrdinal(bool &Result) const;
+ Error getOrdinal(uint16_t &Result) const;
+ Error getHintNameRVA(uint32_t &Result) const;
private:
const import_lookup_table_entry32 *Entry32;
@@ -1194,8 +1184,8 @@ public:
bool operator==(const BaseRelocRef &Other) const;
void moveNext();
- std::error_code getType(uint8_t &Type) const;
- std::error_code getRVA(uint32_t &Result) const;
+ Error getType(uint8_t &Type) const;
+ Error getRVA(uint32_t &Result) const;
private:
const coff_base_reloc_block_header *Header;
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/COFFImportFile.h b/contrib/llvm-project/llvm/include/llvm/Object/COFFImportFile.h
index 5aa836411118..f38bd898a444 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/COFFImportFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/COFFImportFile.h
@@ -43,7 +43,7 @@ public:
return Error::success();
}
- uint32_t getSymbolFlags(DataRefImpl Symb) const override {
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override {
return SymbolRef::SF_Global;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ELF.h b/contrib/llvm-project/llvm/include/llvm/Object/ELF.h
index 42c5b67ac3fa..b44dd3f48661 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ELF.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ELF.h
@@ -64,6 +64,17 @@ std::string getSecIndexForError(const ELFFile<ELFT> *Obj,
return "[unknown index]";
}
+template <class ELFT>
+std::string getPhdrIndexForError(const ELFFile<ELFT> *Obj,
+ const typename ELFT::Phdr *Phdr) {
+ auto Headers = Obj->program_headers();
+ if (Headers)
+ return ("[index " + Twine(Phdr - &Headers->front()) + "]").str();
+ // See comment in the getSecIndexForError() above.
+ llvm::consumeError(Headers.takeError());
+ return "[unknown index]";
+}
+
static inline Error defaultWarningHandler(const Twine &Msg) {
return createError(Msg);
}
@@ -194,16 +205,18 @@ public:
if (getHeader()->e_phnum && getHeader()->e_phentsize != sizeof(Elf_Phdr))
return createError("invalid e_phentsize: " +
Twine(getHeader()->e_phentsize));
- if (getHeader()->e_phoff +
- (getHeader()->e_phnum * getHeader()->e_phentsize) >
- getBufSize())
+
+ uint64_t HeadersSize =
+ (uint64_t)getHeader()->e_phnum * getHeader()->e_phentsize;
+ uint64_t PhOff = getHeader()->e_phoff;
+ if (PhOff + HeadersSize < PhOff || PhOff + HeadersSize > getBufSize())
return createError("program headers are longer than binary of size " +
Twine(getBufSize()) + ": e_phoff = 0x" +
Twine::utohexstr(getHeader()->e_phoff) +
", e_phnum = " + Twine(getHeader()->e_phnum) +
", e_phentsize = " + Twine(getHeader()->e_phentsize));
- auto *Begin =
- reinterpret_cast<const Elf_Phdr *>(base() + getHeader()->e_phoff);
+
+ auto *Begin = reinterpret_cast<const Elf_Phdr *>(base() + PhOff);
return makeArrayRef(Begin, Begin + getHeader()->e_phnum);
}
@@ -299,6 +312,7 @@ public:
template <typename T>
Expected<ArrayRef<T>> getSectionContentsAsArray(const Elf_Shdr *Sec) const;
Expected<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *Sec) const;
+ Expected<ArrayRef<uint8_t>> getSegmentContents(const Elf_Phdr *Phdr) const;
};
using ELF32LEFile = ELFFile<ELF32LE>;
@@ -424,6 +438,26 @@ ELFFile<ELFT>::getSectionContentsAsArray(const Elf_Shdr *Sec) const {
template <class ELFT>
Expected<ArrayRef<uint8_t>>
+ELFFile<ELFT>::getSegmentContents(const Elf_Phdr *Phdr) const {
+ uintX_t Offset = Phdr->p_offset;
+ uintX_t Size = Phdr->p_filesz;
+
+ if (std::numeric_limits<uintX_t>::max() - Offset < Size)
+ return createError("program header " + getPhdrIndexForError(this, Phdr) +
+ " has a p_offset (0x" + Twine::utohexstr(Offset) +
+ ") + p_filesz (0x" + Twine::utohexstr(Size) +
+ ") that cannot be represented");
+ if (Offset + Size > Buf.size())
+ return createError("program header " + getPhdrIndexForError(this, Phdr) +
+ " has a p_offset (0x" + Twine::utohexstr(Offset) +
+ ") + p_filesz (0x" + Twine::utohexstr(Size) +
+ ") that is greater than the file size (0x" +
+ Twine::utohexstr(Buf.size()) + ")");
+ return makeArrayRef(base() + Offset, Size);
+}
+
+template <class ELFT>
+Expected<ArrayRef<uint8_t>>
ELFFile<ELFT>::getSectionContents(const Elf_Shdr *Sec) const {
return getSectionContentsAsArray<uint8_t>(Sec);
}
@@ -484,8 +518,17 @@ Expected<StringRef>
ELFFile<ELFT>::getSectionStringTable(Elf_Shdr_Range Sections,
WarningHandler WarnHandler) const {
uint32_t Index = getHeader()->e_shstrndx;
- if (Index == ELF::SHN_XINDEX)
+ if (Index == ELF::SHN_XINDEX) {
+ // If the section name string table section index is greater than
+ // or equal to SHN_LORESERVE, then the actual index of the section name
+ // string table section is contained in the sh_link field of the section
+ // header at index 0.
+ if (Sections.empty())
+ return createError(
+ "e_shstrndx == SHN_XINDEX, but the section header table is empty");
+
Index = Sections[0].sh_link;
+ }
if (!Index) // no section string table.
return "";
@@ -573,7 +616,7 @@ Expected<const T *> ELFFile<ELFT>::getEntry(const Elf_Shdr *Section,
return createError("section " + getSecIndexForError(this, Section) +
" has invalid sh_entsize: expected " + Twine(sizeof(T)) +
", but got " + Twine(Section->sh_entsize));
- size_t Pos = Section->sh_offset + Entry * sizeof(T);
+ uint64_t Pos = Section->sh_offset + (uint64_t)Entry * sizeof(T);
if (Pos + sizeof(T) > Buf.size())
return createError("unable to access section " +
getSecIndexForError(this, Section) + " data at 0x" +
@@ -670,7 +713,6 @@ ELFFile<ELFT>::getStringTableForSymtab(const Elf_Shdr &Sec,
Elf_Shdr_Range Sections) const {
if (Sec.sh_type != ELF::SHT_SYMTAB && Sec.sh_type != ELF::SHT_DYNSYM)
- // TODO: this error is untested.
return createError(
"invalid sh_type for symbol table, expected SHT_SYMTAB or SHT_DYNSYM");
auto SectionOrErr = object::getSection<ELFT>(Sections, Sec.sh_link);
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ELFObjectFile.h b/contrib/llvm-project/llvm/include/llvm/Object/ELFObjectFile.h
index 8a68e49477fd..62ecd8b5a7e5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ELFObjectFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ELFObjectFile.h
@@ -28,8 +28,8 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/ARMAttributeParser.h"
-#include "llvm/Support/ARMBuildAttributes.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/ELFAttributes.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
@@ -64,7 +64,7 @@ protected:
virtual uint64_t getSectionOffset(DataRefImpl Sec) const = 0;
virtual Expected<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0;
- virtual Error getBuildAttributes(ARMAttributeParser &Attributes) const = 0;
+ virtual Error getBuildAttributes(ELFAttributeParser &Attributes) const = 0;
public:
using elf_symbol_iterator_range = iterator_range<elf_symbol_iterator>;
@@ -261,7 +261,7 @@ protected:
uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
uint8_t getSymbolBinding(DataRefImpl Symb) const override;
uint8_t getSymbolOther(DataRefImpl Symb) const override;
uint8_t getSymbolELFType(DataRefImpl Symb) const override;
@@ -285,6 +285,7 @@ protected:
bool isSectionVirtual(DataRefImpl Sec) const override;
bool isBerkeleyText(DataRefImpl Sec) const override;
bool isBerkeleyData(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
std::vector<SectionRef> dynamic_relocation_sections() const override;
@@ -365,22 +366,24 @@ protected:
(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_PROTECTED));
}
- Error getBuildAttributes(ARMAttributeParser &Attributes) const override {
+ Error getBuildAttributes(ELFAttributeParser &Attributes) const override {
auto SectionsOrErr = EF.sections();
if (!SectionsOrErr)
return SectionsOrErr.takeError();
for (const Elf_Shdr &Sec : *SectionsOrErr) {
- if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES) {
+ if (Sec.sh_type == ELF::SHT_ARM_ATTRIBUTES ||
+ Sec.sh_type == ELF::SHT_RISCV_ATTRIBUTES) {
auto ErrorOrContents = EF.getSectionContents(&Sec);
if (!ErrorOrContents)
return ErrorOrContents.takeError();
auto Contents = ErrorOrContents.get();
- if (Contents[0] != ARMBuildAttrs::Format_Version || Contents.size() == 1)
+ if (Contents[0] != ELFAttrs::Format_Version || Contents.size() == 1)
return Error::success();
- Attributes.Parse(Contents, ELFT::TargetEndianness == support::little);
+ if (Error E = Attributes.parse(Contents, ELFT::TargetEndianness))
+ return E;
break;
}
}
@@ -513,7 +516,12 @@ uint64_t ELFObjectFile<ELFT>::getSymbolValueImpl(DataRefImpl Symb) const {
template <class ELFT>
Expected<uint64_t>
ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb) const {
- uint64_t Result = getSymbolValue(Symb);
+ Expected<uint64_t> SymbolValueOrErr = getSymbolValue(Symb);
+ if (!SymbolValueOrErr)
+ // TODO: Test this error.
+ return SymbolValueOrErr.takeError();
+
+ uint64_t Result = *SymbolValueOrErr;
const Elf_Sym *ESym = getSymbol(Symb);
switch (ESym->st_shndx) {
case ELF::SHN_COMMON:
@@ -606,7 +614,7 @@ ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb) const {
}
template <class ELFT>
-uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
+Expected<uint32_t> ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
const Elf_Sym *ESym = getSymbol(Sym);
uint32_t Result = SymbolRef::SF_None;
@@ -623,12 +631,23 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const {
if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION)
Result |= SymbolRef::SF_FormatSpecific;
- auto DotSymtabSecSyms = EF.symbols(DotSymtabSec);
- if (DotSymtabSecSyms && ESym == (*DotSymtabSecSyms).begin())
- Result |= SymbolRef::SF_FormatSpecific;
- auto DotDynSymSecSyms = EF.symbols(DotDynSymSec);
- if (DotDynSymSecSyms && ESym == (*DotDynSymSecSyms).begin())
- Result |= SymbolRef::SF_FormatSpecific;
+ if (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotSymtabSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
+
+ if (Expected<typename ELFT::SymRange> SymbolsOrErr =
+ EF.symbols(DotDynSymSec)) {
+ // Set the SF_FormatSpecific flag for the 0-index null symbol.
+ if (ESym == SymbolsOrErr->begin())
+ Result |= SymbolRef::SF_FormatSpecific;
+ } else
+ // TODO: Test this error.
+ return SymbolsOrErr.takeError();
if (EF.getHeader()->e_machine == ELF::EM_ARM) {
if (Expected<StringRef> NameOrErr = getSymbolName(Sym)) {
@@ -725,10 +744,10 @@ ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec) const {
const Elf_Shdr *EShdr = getSection(Sec);
if (EShdr->sh_type == ELF::SHT_NOBITS)
return makeArrayRef((const uint8_t *)base(), 0);
- if (std::error_code EC =
+ if (Error E =
checkOffset(getMemoryBufferRef(),
(uintptr_t)base() + EShdr->sh_offset, EShdr->sh_size))
- return errorCodeToError(EC);
+ return std::move(E);
return makeArrayRef((const uint8_t *)base() + EShdr->sh_offset,
EShdr->sh_size);
}
@@ -812,6 +831,12 @@ bool ELFObjectFile<ELFT>::isBerkeleyData(DataRefImpl Sec) const {
}
template <class ELFT>
+bool ELFObjectFile<ELFT>::isDebugSection(StringRef SectionName) const {
+ return SectionName.startswith(".debug") ||
+ SectionName.startswith(".zdebug") || SectionName == ".gdb_index";
+}
+
+template <class ELFT>
relocation_iterator
ELFObjectFile<ELFT>::section_rel_begin(DataRefImpl Sec) const {
DataRefImpl RelData;
@@ -1018,8 +1043,12 @@ basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end() const {
template <class ELFT>
elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const {
- DataRefImpl Sym = toDRI(DotDynSymSec, 0);
- return symbol_iterator(SymbolRef(Sym, this));
+ if (!DotDynSymSec || DotDynSymSec->sh_size < sizeof(Elf_Sym))
+ // Ignore errors here where the dynsym is empty or sh_size less than the
+ // size of one symbol. These should be handled elsewhere.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 0), this));
+ // Skip 0-index NULL symbol.
+ return symbol_iterator(SymbolRef(toDRI(DotDynSymSec, 1), this));
}
template <class ELFT>
@@ -1059,59 +1088,61 @@ StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
case ELF::ELFCLASS32:
switch (EF.getHeader()->e_machine) {
case ELF::EM_386:
- return "ELF32-i386";
+ return "elf32-i386";
case ELF::EM_IAMCU:
- return "ELF32-iamcu";
+ return "elf32-iamcu";
case ELF::EM_X86_64:
- return "ELF32-x86-64";
+ return "elf32-x86-64";
case ELF::EM_ARM:
- return (IsLittleEndian ? "ELF32-arm-little" : "ELF32-arm-big");
+ return (IsLittleEndian ? "elf32-littlearm" : "elf32-bigarm");
case ELF::EM_AVR:
- return "ELF32-avr";
+ return "elf32-avr";
case ELF::EM_HEXAGON:
- return "ELF32-hexagon";
+ return "elf32-hexagon";
case ELF::EM_LANAI:
- return "ELF32-lanai";
+ return "elf32-lanai";
case ELF::EM_MIPS:
- return "ELF32-mips";
+ return "elf32-mips";
case ELF::EM_MSP430:
- return "ELF32-msp430";
+ return "elf32-msp430";
case ELF::EM_PPC:
- return "ELF32-ppc";
+ return "elf32-powerpc";
case ELF::EM_RISCV:
- return "ELF32-riscv";
+ return "elf32-littleriscv";
case ELF::EM_SPARC:
case ELF::EM_SPARC32PLUS:
- return "ELF32-sparc";
+ return "elf32-sparc";
case ELF::EM_AMDGPU:
- return "ELF32-amdgpu";
+ return "elf32-amdgpu";
default:
- return "ELF32-unknown";
+ return "elf32-unknown";
}
case ELF::ELFCLASS64:
switch (EF.getHeader()->e_machine) {
case ELF::EM_386:
- return "ELF64-i386";
+ return "elf64-i386";
case ELF::EM_X86_64:
- return "ELF64-x86-64";
+ return "elf64-x86-64";
case ELF::EM_AARCH64:
- return (IsLittleEndian ? "ELF64-aarch64-little" : "ELF64-aarch64-big");
+ return (IsLittleEndian ? "elf64-littleaarch64" : "elf64-bigaarch64");
case ELF::EM_PPC64:
- return "ELF64-ppc64";
+ return (IsLittleEndian ? "elf64-powerpcle" : "elf64-powerpc");
case ELF::EM_RISCV:
- return "ELF64-riscv";
+ return "elf64-littleriscv";
case ELF::EM_S390:
- return "ELF64-s390";
+ return "elf64-s390";
case ELF::EM_SPARCV9:
- return "ELF64-sparc";
+ return "elf64-sparc";
case ELF::EM_MIPS:
- return "ELF64-mips";
+ return "elf64-mips";
case ELF::EM_AMDGPU:
- return "ELF64-amdgpu";
+ return "elf64-amdgpu";
case ELF::EM_BPF:
- return "ELF64-BPF";
+ return "elf64-bpf";
+ case ELF::EM_VE:
+ return "elf64-ve";
default:
- return "ELF64-unknown";
+ return "elf64-unknown";
}
default:
// FIXME: Proper error handling.
@@ -1188,6 +1219,8 @@ template <class ELFT> Triple::ArchType ELFObjectFile<ELFT>::getArch() const {
case ELF::EM_BPF:
return IsLittleEndian ? Triple::bpfel : Triple::bpfeb;
+ case ELF::EM_VE:
+ return Triple::ve;
default:
return Triple::UnknownArch;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ELFTypes.h b/contrib/llvm-project/llvm/include/llvm/Object/ELFTypes.h
index 7d1ade4d5437..5e85e6cc4653 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ELFTypes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ELFTypes.h
@@ -53,7 +53,7 @@ public:
static const endianness TargetEndianness = E;
static const bool Is64Bits = Is64;
- using uint = typename std::conditional<Is64, uint64_t, uint32_t>::type;
+ using uint = std::conditional_t<Is64, uint64_t, uint32_t>;
using Ehdr = Elf_Ehdr_Impl<ELFType<E, Is64>>;
using Shdr = Elf_Shdr_Impl<ELFType<E, Is64>>;
using Sym = Elf_Sym_Impl<ELFType<E, Is64>>;
@@ -346,10 +346,8 @@ template <class ELFT>
struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
using Elf_Dyn_Base<ELFT>::d_tag;
using Elf_Dyn_Base<ELFT>::d_un;
- using intX_t = typename std::conditional<ELFT::Is64Bits,
- int64_t, int32_t>::type;
- using uintX_t = typename std::conditional<ELFT::Is64Bits,
- uint64_t, uint32_t>::type;
+ using intX_t = std::conditional_t<ELFT::Is64Bits, int64_t, int32_t>;
+ using uintX_t = std::conditional_t<ELFT::Is64Bits, uint64_t, uint32_t>;
intX_t getTag() const { return d_tag; }
uintX_t getVal() const { return d_un.d_val; }
uintX_t getPtr() const { return d_un.d_ptr; }
@@ -541,6 +539,7 @@ struct Elf_GnuHash_Impl {
}
ArrayRef<Elf_Word> values(unsigned DynamicSymCount) const {
+ assert(DynamicSymCount >= symndx);
return ArrayRef<Elf_Word>(buckets().end(), DynamicSymCount - symndx);
}
};
@@ -617,6 +616,12 @@ public:
Nhdr.n_descsz);
}
+ /// Get the note's descriptor as StringRef
+ StringRef getDescAsStringRef() const {
+ ArrayRef<uint8_t> Desc = getDesc();
+ return StringRef(reinterpret_cast<const char *>(Desc.data()), Desc.size());
+ }
+
/// Get the note's type.
Elf_Word getType() const { return Nhdr.n_type; }
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/Error.h b/contrib/llvm-project/llvm/include/llvm/Object/Error.h
index b7bbf06fc86d..07744188444a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/Error.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/Error.h
@@ -13,11 +13,13 @@
#ifndef LLVM_OBJECT_ERROR_H
#define LLVM_OBJECT_ERROR_H
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
#include <system_error>
namespace llvm {
+
+class Twine;
+
namespace object {
class Binary;
@@ -49,7 +51,7 @@ inline std::error_code make_error_code(object_error e) {
/// Currently inherits from ECError for easy interoperability with
/// std::error_code, but this will be removed in the future.
class BinaryError : public ErrorInfo<BinaryError, ECError> {
- virtual void anchor();
+ void anchor() override;
public:
static char ID;
BinaryError() {
@@ -65,8 +67,8 @@ public:
class GenericBinaryError : public ErrorInfo<GenericBinaryError, BinaryError> {
public:
static char ID;
- GenericBinaryError(Twine Msg);
- GenericBinaryError(Twine Msg, object_error ECOverride);
+ GenericBinaryError(const Twine &Msg);
+ GenericBinaryError(const Twine &Msg, object_error ECOverride);
const std::string &getMessage() const { return Msg; }
void log(raw_ostream &OS) const override;
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/IRObjectFile.h b/contrib/llvm-project/llvm/include/llvm/Object/IRObjectFile.h
index 08b92f1bae50..338b1941eca1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/IRObjectFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/IRObjectFile.h
@@ -38,7 +38,7 @@ public:
~IRObjectFile() override;
void moveSymbolNext(DataRefImpl &Symb) const override;
Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
basic_symbol_iterator symbol_begin() const override;
basic_symbol_iterator symbol_end() const override;
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/IRSymtab.h b/contrib/llvm-project/llvm/include/llvm/Object/IRSymtab.h
index 0bbfc932493c..4ee32fca81bb 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/IRSymtab.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/IRSymtab.h
@@ -28,6 +28,7 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include <cassert>
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/MachO.h b/contrib/llvm-project/llvm/include/llvm/Object/MachO.h
index c3ecdd93563f..f48e0f1dcd58 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/MachO.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/MachO.h
@@ -65,7 +65,7 @@ using dice_iterator = content_iterator<DiceRef>;
/// ExportEntry encapsulates the current-state-of-the-walk used when doing a
/// non-recursive walk of the trie data structure. This allows you to iterate
/// across all exported symbols using:
-/// Error Err;
+/// Error Err = Error::success();
/// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) {
/// }
/// if (Err) { report error ...
@@ -160,7 +160,7 @@ private:
/// MachORebaseEntry encapsulates the current state in the decompression of
/// rebasing opcodes. This allows you to iterate through the compressed table of
/// rebasing using:
-/// Error Err;
+/// Error Err = Error::success();
/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
/// }
/// if (Err) { report error ...
@@ -204,7 +204,7 @@ using rebase_iterator = content_iterator<MachORebaseEntry>;
/// MachOBindEntry encapsulates the current state in the decompression of
/// binding opcodes. This allows you to iterate through the compressed table of
/// bindings using:
-/// Error Err;
+/// Error Err = Error::success();
/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
/// }
/// if (Err) { report error ...
@@ -287,7 +287,7 @@ public:
uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
unsigned getSymbolSectionID(SymbolRef Symb) const;
unsigned getSectionID(SectionRef Sec) const;
@@ -309,6 +309,7 @@ public:
bool isSectionBSS(DataRefImpl Sec) const override;
bool isSectionVirtual(DataRefImpl Sec) const override;
bool isSectionBitcode(DataRefImpl Sec) const override;
+ bool isDebugSection(StringRef SectionName) const override;
/// When dsymutil generates the companion file, it strips all unnecessary
/// sections (e.g. everything in the _TEXT segment) by omitting their body
@@ -644,7 +645,7 @@ public:
Version = utostr(major) + "." + utostr(minor);
if (update != 0)
Version += "." + utostr(update);
- return Version.str();
+ return std::string(std::string(Version.str()));
}
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/MachOUniversal.h b/contrib/llvm-project/llvm/include/llvm/Object/MachOUniversal.h
index eb45aff4480b..5e006fd87318 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/MachOUniversal.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/MachOUniversal.h
@@ -90,25 +90,14 @@ public:
else // Parent->getMagic() == MachO::FAT_MAGIC_64
return Header64.reserved;
}
+ Triple getTriple() const {
+ return MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType());
+ }
std::string getArchFlagName() const {
const char *McpuDefault, *ArchFlag;
- if (Parent->getMagic() == MachO::FAT_MAGIC) {
- Triple T =
- MachOObjectFile::getArchTriple(Header.cputype, Header.cpusubtype,
- &McpuDefault, &ArchFlag);
- } else { // Parent->getMagic() == MachO::FAT_MAGIC_64
- Triple T =
- MachOObjectFile::getArchTriple(Header64.cputype,
- Header64.cpusubtype,
- &McpuDefault, &ArchFlag);
- }
- if (ArchFlag) {
- std::string ArchFlagName(ArchFlag);
- return ArchFlagName;
- } else {
- std::string ArchFlagName("");
- return ArchFlagName;
- }
+ MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType(),
+ &McpuDefault, &ArchFlag);
+ return ArchFlag ? ArchFlag : std::string();
}
Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const;
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ModuleSymbolTable.h b/contrib/llvm-project/llvm/include/llvm/Object/ModuleSymbolTable.h
index 4c582fbcda81..1134b98c2247 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ModuleSymbolTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ModuleSymbolTable.h
@@ -28,6 +28,7 @@
namespace llvm {
class GlobalValue;
+class Module;
class ModuleSymbolTable {
public:
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/ObjectFile.h b/contrib/llvm-project/llvm/include/llvm/Object/ObjectFile.h
index 2f1493457605..8e8937201716 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/ObjectFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/ObjectFile.h
@@ -18,13 +18,11 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/BinaryFormat/Magic.h"
-#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/SymbolicFile.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cassert>
#include <cstdint>
@@ -34,6 +32,7 @@
namespace llvm {
class ARMAttributeParser;
+class SubtargetFeatures;
namespace object {
@@ -123,6 +122,9 @@ public:
/// contains data (e.g. PROGBITS), but is not text.
bool isBerkeleyData() const;
+ /// Whether this section is a debug section.
+ bool isDebugSection(StringRef SectionName) const;
+
bool containsSymbol(SymbolRef S) const;
relocation_iterator relocation_begin() const;
@@ -185,7 +187,7 @@ public:
/// Return the value of the symbol depending on the object this can be an
/// offset or a virtual address.
- uint64_t getValue() const;
+ Expected<uint64_t> getValue() const;
/// Get the alignment of this symbol as the actual value (not log 2).
uint32_t getAlignment() const;
@@ -272,6 +274,7 @@ protected:
virtual bool isSectionStripped(DataRefImpl Sec) const;
virtual bool isBerkeleyText(DataRefImpl Sec) const;
virtual bool isBerkeleyData(DataRefImpl Sec) const;
+ virtual bool isDebugSection(StringRef SectionName) const;
virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0;
virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0;
virtual Expected<section_iterator> getRelocatedSection(DataRefImpl Sec) const;
@@ -285,14 +288,18 @@ protected:
virtual void getRelocationTypeName(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const = 0;
- uint64_t getSymbolValue(DataRefImpl Symb) const;
+ Expected<uint64_t> getSymbolValue(DataRefImpl Symb) const;
public:
ObjectFile() = delete;
ObjectFile(const ObjectFile &other) = delete;
uint64_t getCommonSymbolSize(DataRefImpl Symb) const {
- assert(getSymbolFlags(Symb) & SymbolRef::SF_Common);
+ Expected<uint32_t> SymbolFlagsOrErr = getSymbolFlags(Symb);
+ if (!SymbolFlagsOrErr)
+ // TODO: Actually report errors helpfully.
+ report_fatal_error(SymbolFlagsOrErr.takeError());
+ assert(*SymbolFlagsOrErr & SymbolRef::SF_Common);
return getCommonSymbolSizeImpl(Symb);
}
@@ -382,7 +389,7 @@ inline Expected<uint64_t> SymbolRef::getAddress() const {
return getObject()->getSymbolAddress(getRawDataRefImpl());
}
-inline uint64_t SymbolRef::getValue() const {
+inline Expected<uint64_t> SymbolRef::getValue() const {
return getObject()->getSymbolValue(getRawDataRefImpl());
}
@@ -495,6 +502,10 @@ inline bool SectionRef::isBerkeleyData() const {
return OwningObject->isBerkeleyData(SectionPimpl);
}
+inline bool SectionRef::isDebugSection(StringRef SectionName) const {
+ return OwningObject->isDebugSection(SectionName);
+}
+
inline relocation_iterator SectionRef::relocation_begin() const {
return OwningObject->section_rel_begin(SectionPimpl);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/SymbolicFile.h b/contrib/llvm-project/llvm/include/llvm/Object/SymbolicFile.h
index 1398fa134c81..a0d8b7225598 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/SymbolicFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/SymbolicFile.h
@@ -18,7 +18,6 @@
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cinttypes>
@@ -129,7 +128,7 @@ public:
Error printName(raw_ostream &OS) const;
/// Get symbol flags (bitwise OR of SymbolRef::Flags)
- uint32_t getFlags() const;
+ Expected<uint32_t> getFlags() const;
DataRefImpl getRawDataRefImpl() const;
const SymbolicFile *getObject() const;
@@ -147,7 +146,7 @@ public:
virtual Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const = 0;
- virtual uint32_t getSymbolFlags(DataRefImpl Symb) const = 0;
+ virtual Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const = 0;
virtual basic_symbol_iterator symbol_begin() const = 0;
@@ -196,7 +195,7 @@ inline Error BasicSymbolRef::printName(raw_ostream &OS) const {
return OwningObject->printSymbolName(OS, SymbolPimpl);
}
-inline uint32_t BasicSymbolRef::getFlags() const {
+inline Expected<uint32_t> BasicSymbolRef::getFlags() const {
return OwningObject->getSymbolFlags(SymbolPimpl);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/TapiFile.h b/contrib/llvm-project/llvm/include/llvm/Object/TapiFile.h
index bc2e04e1cc96..ab99690ff2fa 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/TapiFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/TapiFile.h
@@ -33,7 +33,7 @@ public:
Error printSymbolName(raw_ostream &OS, DataRefImpl DRI) const override;
- uint32_t getSymbolFlags(DataRefImpl DRI) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl DRI) const override;
basic_symbol_iterator symbol_begin() const override;
@@ -41,6 +41,8 @@ public:
static bool classof(const Binary *v) { return v->isTapiFile(); }
+ bool is64Bit() { return MachO::is64Bit(Arch); }
+
private:
struct Symbol {
StringRef Prefix;
@@ -52,6 +54,7 @@ private:
};
std::vector<Symbol> Symbols;
+ MachO::Architecture Arch;
};
} // end namespace object.
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/TapiUniversal.h b/contrib/llvm-project/llvm/include/llvm/Object/TapiUniversal.h
index 4931183852ad..0f494fcfac42 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/TapiUniversal.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/TapiUniversal.h
@@ -41,18 +41,26 @@ public:
uint32_t getCPUType() const {
auto Result =
- MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+ MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
return Result.first;
}
uint32_t getCPUSubType() const {
auto Result =
- MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+ MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
return Result.second;
}
- std::string getArchFlagName() const {
- return MachO::getArchitectureName(Parent->Architectures[Index]);
+ StringRef getArchFlagName() const {
+ return MachO::getArchitectureName(Parent->Libraries[Index].Arch);
+ }
+
+ std::string getInstallName() const {
+ return std::string(Parent->Libraries[Index].InstallName);
+ }
+
+ bool isTopLevelLib() const {
+ return Parent->ParsedFile->getInstallName() == getInstallName();
}
Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
@@ -86,21 +94,25 @@ public:
object_iterator begin_objects() const { return ObjectForArch(this, 0); }
object_iterator end_objects() const {
- return ObjectForArch(this, Architectures.size());
+ return ObjectForArch(this, Libraries.size());
}
iterator_range<object_iterator> objects() const {
return make_range(begin_objects(), end_objects());
}
- uint32_t getNumberOfObjects() const { return Architectures.size(); }
+ uint32_t getNumberOfObjects() const { return Libraries.size(); }
- // Cast methods.
static bool classof(const Binary *v) { return v->isTapiUniversal(); }
private:
+ struct Library {
+ StringRef InstallName;
+ MachO::Architecture Arch;
+ };
+
std::unique_ptr<MachO::InterfaceFile> ParsedFile;
- std::vector<MachO::Architecture> Architectures;
+ std::vector<Library> Libraries;
};
} // end namespace object.
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/Wasm.h b/contrib/llvm-project/llvm/include/llvm/Object/Wasm.h
index 8af94c4963b6..dc90c891ab95 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/Wasm.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/Wasm.h
@@ -17,7 +17,6 @@
#define LLVM_OBJECT_WASM_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Config/llvm-config.h"
@@ -152,9 +151,10 @@ public:
uint32_t getNumImportedGlobals() const { return NumImportedGlobals; }
uint32_t getNumImportedFunctions() const { return NumImportedFunctions; }
uint32_t getNumImportedEvents() const { return NumImportedEvents; }
+ uint32_t getNumSections() const { return Sections.size(); }
void moveSymbolNext(DataRefImpl &Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
basic_symbol_iterator symbol_begin() const override;
@@ -168,6 +168,7 @@ public:
uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
+ uint32_t getSymbolSectionId(SymbolRef Sym) const;
// Overrides from SectionRef.
void moveSectionNext(DataRefImpl &Sec) const override;
@@ -183,7 +184,6 @@ public:
bool isSectionData(DataRefImpl Sec) const override;
bool isSectionBSS(DataRefImpl Sec) const override;
bool isSectionVirtual(DataRefImpl Sec) const override;
- bool isSectionBitcode(DataRefImpl Sec) const override;
relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
@@ -229,6 +229,7 @@ private:
const WasmSection &getWasmSection(DataRefImpl Ref) const;
const wasm::WasmRelocation &getWasmRelocation(DataRefImpl Ref) const;
+ uint32_t getSymbolSectionIdImpl(const WasmSymbol &Symb) const;
Error parseSection(WasmSection &Sec);
Error parseCustomSection(WasmSection &Sec, ReadContext &Ctx);
@@ -239,8 +240,8 @@ private:
Error parseFunctionSection(ReadContext &Ctx);
Error parseTableSection(ReadContext &Ctx);
Error parseMemorySection(ReadContext &Ctx);
- Error parseGlobalSection(ReadContext &Ctx);
Error parseEventSection(ReadContext &Ctx);
+ Error parseGlobalSection(ReadContext &Ctx);
Error parseExportSection(ReadContext &Ctx);
Error parseStartSection(ReadContext &Ctx);
Error parseElemSection(ReadContext &Ctx);
@@ -287,8 +288,8 @@ private:
uint32_t NumImportedEvents = 0;
uint32_t CodeSection = 0;
uint32_t DataSection = 0;
- uint32_t GlobalSection = 0;
uint32_t EventSection = 0;
+ uint32_t GlobalSection = 0;
};
class WasmSectionOrderChecker {
@@ -304,8 +305,8 @@ public:
WASM_SEC_ORDER_FUNCTION,
WASM_SEC_ORDER_TABLE,
WASM_SEC_ORDER_MEMORY,
- WASM_SEC_ORDER_GLOBAL,
WASM_SEC_ORDER_EVENT,
+ WASM_SEC_ORDER_GLOBAL,
WASM_SEC_ORDER_EXPORT,
WASM_SEC_ORDER_START,
WASM_SEC_ORDER_ELEM,
diff --git a/contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h b/contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h
index fcdbf7a8095c..9c2470736023 100644
--- a/contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Object/XCOFFObjectFile.h
@@ -15,6 +15,8 @@
#include "llvm/BinaryFormat/XCOFF.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Endian.h"
+#include <limits>
namespace llvm {
namespace object {
@@ -128,6 +130,10 @@ struct XCOFFStringTable {
};
struct XCOFFCsectAuxEnt32 {
+ static constexpr uint8_t SymbolTypeMask = 0x07;
+ static constexpr uint8_t SymbolAlignmentMask = 0xF8;
+ static constexpr size_t SymbolAlignmentBitOffset = 3;
+
support::ubig32_t
SectionOrLength; // If the symbol type is XTY_SD or XTY_CM, the csect
// length.
@@ -140,6 +146,17 @@ struct XCOFFCsectAuxEnt32 {
XCOFF::StorageMappingClass StorageMappingClass;
support::ubig32_t StabInfoIndex;
support::ubig16_t StabSectNum;
+
+ uint16_t getAlignmentLog2() const {
+ return (SymbolAlignmentAndType & SymbolAlignmentMask) >>
+ SymbolAlignmentBitOffset;
+ }
+
+ uint8_t getSymbolType() const {
+ return SymbolAlignmentAndType & SymbolTypeMask;
+ }
+
+ bool isLabel() const { return getSymbolType() == XCOFF::XTY_LD; }
};
struct XCOFFFileAuxEnt {
@@ -247,9 +264,12 @@ private:
void checkSectionAddress(uintptr_t Addr, uintptr_t TableAddr) const;
public:
+ static constexpr uint64_t InvalidRelocOffset =
+ std::numeric_limits<uint64_t>::max();
+
// Interface inherited from base classes.
void moveSymbolNext(DataRefImpl &Symb) const override;
- uint32_t getSymbolFlags(DataRefImpl Symb) const override;
+ Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override;
basic_symbol_iterator symbol_begin() const override;
basic_symbol_iterator symbol_end() const override;
@@ -278,6 +298,10 @@ public:
relocation_iterator section_rel_end(DataRefImpl Sec) const override;
void moveRelocationNext(DataRefImpl &Rel) const override;
+
+ /// \returns the relocation offset with the base address of the containing
+ /// section as zero, or InvalidRelocOffset on errors (such as a relocation
+ /// that does not refer to an address in any section).
uint64_t getRelocationOffset(DataRefImpl Rel) const override;
symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
uint64_t getRelocationType(DataRefImpl Rel) const override;
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
index 2ccc876d5023..0ec3f90e1686 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -28,21 +28,20 @@ namespace DWARFYAML {
struct Data;
struct PubSection;
-void EmitDebugAbbrev(raw_ostream &OS, const Data &DI);
-void EmitDebugStr(raw_ostream &OS, const Data &DI);
+Error emitDebugAbbrev(raw_ostream &OS, const Data &DI);
+Error emitDebugStr(raw_ostream &OS, const Data &DI);
-void EmitDebugAranges(raw_ostream &OS, const Data &DI);
-void EmitPubSection(raw_ostream &OS, const PubSection &Sect,
- bool IsLittleEndian);
-void EmitDebugInfo(raw_ostream &OS, const Data &DI);
-void EmitDebugLine(raw_ostream &OS, const Data &DI);
+Error emitDebugAranges(raw_ostream &OS, const Data &DI);
+Error emitDebugRanges(raw_ostream &OS, const Data &DI);
+Error emitPubSection(raw_ostream &OS, const PubSection &Sect,
+ bool IsLittleEndian, bool IsGNUPubSec = false);
+Error emitDebugInfo(raw_ostream &OS, const Data &DI);
+Error emitDebugLine(raw_ostream &OS, const Data &DI);
+Error emitDebugAddr(raw_ostream &OS, const Data &DI);
Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
-EmitDebugSections(StringRef YAMLString, bool ApplyFixups = false,
+emitDebugSections(StringRef YAMLString, bool ApplyFixups = false,
bool IsLittleEndian = sys::IsLittleEndianHost);
-StringMap<std::unique_ptr<MemoryBuffer>>
-EmitDebugSections(llvm::DWARFYAML::Data &DI, bool ApplyFixups);
-
} // end namespace DWARFYAML
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h
index 26dabfcf27fe..9f62a4a2be57 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -15,6 +15,7 @@
#ifndef LLVM_OBJECTYAML_DWARFYAML_H
#define LLVM_OBJECTYAML_DWARFYAML_H
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/Support/YAMLTraits.h"
@@ -51,7 +52,7 @@ struct AttributeAbbrev {
};
struct Abbrev {
- llvm::yaml::Hex32 Code;
+ Optional<yaml::Hex64> Code;
llvm::dwarf::Tag Tag;
llvm::dwarf::Constants Children;
std::vector<AttributeAbbrev> Attributes;
@@ -63,7 +64,8 @@ struct ARangeDescriptor {
};
struct ARange {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ uint64_t Length;
uint16_t Version;
uint32_t CuOffset;
uint8_t AddrSize;
@@ -71,6 +73,20 @@ struct ARange {
std::vector<ARangeDescriptor> Descriptors;
};
+/// Class that describes a range list entry, or a base address selection entry
+/// within a range list in the .debug_ranges section.
+struct RangeEntry {
+ llvm::yaml::Hex64 LowOffset;
+ llvm::yaml::Hex64 HighOffset;
+};
+
+/// Class that describes a single range list inside the .debug_ranges section.
+struct Ranges {
+ Optional<llvm::yaml::Hex64> Offset;
+ Optional<llvm::yaml::Hex8> AddrSize;
+ std::vector<RangeEntry> Entries;
+};
+
struct PubEntry {
llvm::yaml::Hex32 DieOffset;
llvm::yaml::Hex8 Descriptor;
@@ -82,7 +98,6 @@ struct PubSection {
uint16_t Version;
uint32_t UnitOffset;
uint32_t UnitSize;
- bool IsGNUStyle = false;
std::vector<PubEntry> Entries;
};
@@ -97,11 +112,18 @@ struct Entry {
std::vector<FormValue> Values;
};
+/// Class that contains helpful context information when mapping YAML into DWARF
+/// data structures.
+struct DWARFContext {
+ bool IsGNUPubSec = false;
+};
+
struct Unit {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ uint64_t Length;
uint16_t Version;
llvm::dwarf::UnitType Type; // Added in DWARF 5
- uint32_t AbbrOffset;
+ yaml::Hex64 AbbrOffset;
uint8_t AddrSize;
std::vector<Entry> Entries;
};
@@ -125,7 +147,8 @@ struct LineTableOpcode {
};
struct LineTable {
- InitialLength Length;
+ dwarf::DwarfFormat Format;
+ uint64_t Length;
uint16_t Version;
uint64_t PrologueLength;
uint8_t MinInstLength;
@@ -140,22 +163,41 @@ struct LineTable {
std::vector<LineTableOpcode> Opcodes;
};
+struct SegAddrPair {
+ yaml::Hex64 Segment;
+ yaml::Hex64 Address;
+};
+
+struct AddrTableEntry {
+ dwarf::DwarfFormat Format;
+ Optional<yaml::Hex64> Length;
+ yaml::Hex16 Version;
+ Optional<yaml::Hex8> AddrSize;
+ yaml::Hex8 SegSelectorSize;
+ std::vector<SegAddrPair> SegAddrPairs;
+};
+
struct Data {
bool IsLittleEndian;
+ bool Is64BitAddrSize;
std::vector<Abbrev> AbbrevDecls;
std::vector<StringRef> DebugStrings;
std::vector<ARange> ARanges;
- PubSection PubNames;
- PubSection PubTypes;
+ std::vector<Ranges> DebugRanges;
+ std::vector<AddrTableEntry> DebugAddr;
+ Optional<PubSection> PubNames;
+ Optional<PubSection> PubTypes;
- PubSection GNUPubNames;
- PubSection GNUPubTypes;
+ Optional<PubSection> GNUPubNames;
+ Optional<PubSection> GNUPubTypes;
std::vector<Unit> CompileUnits;
std::vector<LineTable> DebugLines;
bool isEmpty() const;
+
+ SetVector<StringRef> getUsedSectionNames() const;
};
} // end namespace DWARFYAML
@@ -165,6 +207,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RangeEntry)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Ranges)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue)
@@ -172,6 +216,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::File)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTable)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LineTableOpcode)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry)
namespace llvm {
namespace yaml {
@@ -193,7 +239,15 @@ template <> struct MappingTraits<DWARFYAML::ARangeDescriptor> {
};
template <> struct MappingTraits<DWARFYAML::ARange> {
- static void mapping(IO &IO, DWARFYAML::ARange &Range);
+ static void mapping(IO &IO, DWARFYAML::ARange &ARange);
+};
+
+template <> struct MappingTraits<DWARFYAML::RangeEntry> {
+ static void mapping(IO &IO, DWARFYAML::RangeEntry &Entry);
+};
+
+template <> struct MappingTraits<DWARFYAML::Ranges> {
+ static void mapping(IO &IO, DWARFYAML::Ranges &Ranges);
};
template <> struct MappingTraits<DWARFYAML::PubEntry> {
@@ -228,10 +282,25 @@ template <> struct MappingTraits<DWARFYAML::LineTable> {
static void mapping(IO &IO, DWARFYAML::LineTable &LineTable);
};
+template <> struct MappingTraits<DWARFYAML::SegAddrPair> {
+ static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair);
+};
+
+template <> struct MappingTraits<DWARFYAML::AddrTableEntry> {
+ static void mapping(IO &IO, DWARFYAML::AddrTableEntry &AddrTable);
+};
+
template <> struct MappingTraits<DWARFYAML::InitialLength> {
static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF);
};
+template <> struct ScalarEnumerationTraits<dwarf::DwarfFormat> {
+ static void enumeration(IO &IO, dwarf::DwarfFormat &Format) {
+ IO.enumCase(Format, "DWARF32", dwarf::DWARF32);
+ IO.enumCase(Format, "DWARF64", dwarf::DWARF64);
+ }
+};
+
#define HANDLE_DW_TAG(unused, name, unused2, unused3, unused4) \
io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name);
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h
index f87135e6a1b5..b1ffb20681ea 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -16,6 +16,7 @@
#define LLVM_OBJECTYAML_ELFYAML_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ObjectYAML/DWARFYAML.h"
#include "llvm/ObjectYAML/YAML.h"
#include "llvm/Support/YAMLTraits.h"
#include <cstdint>
@@ -26,6 +27,7 @@ namespace llvm {
namespace ELFYAML {
StringRef dropUniqueSuffix(StringRef S);
+std::string appendUniqueSuffix(StringRef Name, const Twine& Msg);
// These types are invariant across 32/64-bit ELF, so for simplicity just
// directly give them their exact sizes. We don't need to worry about
@@ -65,6 +67,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_ISA)
LLVM_YAML_STRONG_TYPEDEF(StringRef, YAMLFlowString)
+LLVM_YAML_STRONG_TYPEDEF(int64_t, YAMLIntUInt)
// For now, hardcode 64 bits everywhere that 32 or 64 would be needed
// since 64-bit can hold 32-bit values too.
@@ -78,31 +81,31 @@ struct FileHeader {
ELF_EF Flags;
llvm::yaml::Hex64 Entry;
- Optional<llvm::yaml::Hex16> SHEntSize;
- Optional<llvm::yaml::Hex64> SHOff;
- Optional<llvm::yaml::Hex16> SHNum;
- Optional<llvm::yaml::Hex16> SHStrNdx;
+ Optional<llvm::yaml::Hex64> EPhOff;
+ Optional<llvm::yaml::Hex16> EPhEntSize;
+ Optional<llvm::yaml::Hex16> EPhNum;
+ Optional<llvm::yaml::Hex16> EShEntSize;
+ Optional<llvm::yaml::Hex64> EShOff;
+ Optional<llvm::yaml::Hex16> EShNum;
+ Optional<llvm::yaml::Hex16> EShStrNdx;
};
-struct SectionName {
- StringRef Section;
+struct SectionHeader {
+ StringRef Name;
};
-struct ProgramHeader {
- ELF_PT Type;
- ELF_PF Flags;
- llvm::yaml::Hex64 VAddr;
- llvm::yaml::Hex64 PAddr;
- Optional<llvm::yaml::Hex64> Align;
- Optional<llvm::yaml::Hex64> FileSize;
- Optional<llvm::yaml::Hex64> MemSize;
- Optional<llvm::yaml::Hex64> Offset;
- std::vector<SectionName> Sections;
+struct SectionHeaderTable {
+ Optional<std::vector<SectionHeader>> Sections;
+ Optional<std::vector<SectionHeader>> Excluded;
+ Optional<bool> NoHeaders;
+};
+
+struct SectionName {
+ StringRef Section;
};
struct Symbol {
StringRef Name;
- Optional<uint32_t> NameIndex;
ELF_STT Type;
StringRef Section;
Optional<ELF_SHN> Index;
@@ -110,6 +113,8 @@ struct Symbol {
llvm::yaml::Hex64 Value;
llvm::yaml::Hex64 Size;
Optional<uint8_t> Other;
+
+ Optional<uint32_t> StName;
};
struct SectionOrType {
@@ -153,10 +158,12 @@ struct Chunk {
Fill,
LinkerOptions,
DependentLibraries,
+ CallGraphProfile
};
ChunkKind Kind;
StringRef Name;
+ Optional<llvm::yaml::Hex64> Offset;
Chunk(ChunkKind K) : Kind(K) {}
virtual ~Chunk();
@@ -165,7 +172,7 @@ struct Chunk {
struct Section : public Chunk {
ELF_SHT Type;
Optional<ELF_SHF> Flags;
- llvm::yaml::Hex64 Address;
+ Optional<llvm::yaml::Hex64> Address;
StringRef Link;
llvm::yaml::Hex64 AddressAlign;
Optional<llvm::yaml::Hex64> EntSize;
@@ -174,6 +181,9 @@ struct Section : public Chunk {
// When they are, this flag is used to signal about that.
bool IsImplicit;
+ // Holds the original section index.
+ unsigned OriginalSecNdx;
+
Section(ChunkKind Kind, bool IsImplicit = false)
: Chunk(Kind), IsImplicit(IsImplicit) {}
@@ -205,11 +215,6 @@ struct Fill : Chunk {
Optional<yaml::BinaryRef> Pattern;
llvm::yaml::Hex64 Size;
- // We have to remember the offset of the fill, because it does not have
- // a corresponding section header, unlike a section. We might need this
- // information when writing the output.
- uint64_t ShOffset;
-
Fill() : Chunk(ChunkKind::Fill) {}
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Fill; }
@@ -250,6 +255,9 @@ struct RawContentSection : Section {
static bool classof(const Chunk *S) {
return S->Kind == ChunkKind::RawContent;
}
+
+ // Is used when a content is read as an array of bytes.
+ Optional<std::vector<uint8_t>> ContentBuf;
};
struct NoBitsSection : Section {
@@ -276,6 +284,11 @@ struct HashSection : Section {
Optional<std::vector<uint32_t>> Bucket;
Optional<std::vector<uint32_t>> Chain;
+ // The following members are used to override section fields.
+ // This is useful for creating invalid objects.
+ Optional<llvm::yaml::Hex64> NBucket;
+ Optional<llvm::yaml::Hex64> NChain;
+
HashSection() : Section(ChunkKind::Hash) {}
static bool classof(const Chunk *S) { return S->Kind == ChunkKind::Hash; }
@@ -339,19 +352,10 @@ struct VerneedSection : Section {
}
};
-struct AddrsigSymbol {
- AddrsigSymbol(StringRef N) : Name(N), Index(None) {}
- AddrsigSymbol(llvm::yaml::Hex32 Ndx) : Name(None), Index(Ndx) {}
- AddrsigSymbol() : Name(None), Index(None) {}
-
- Optional<StringRef> Name;
- Optional<llvm::yaml::Hex32> Index;
-};
-
struct AddrsigSection : Section {
Optional<yaml::BinaryRef> Content;
Optional<llvm::yaml::Hex64> Size;
- Optional<std::vector<AddrsigSymbol>> Symbols;
+ Optional<std::vector<YAMLFlowString>> Symbols;
AddrsigSection() : Section(ChunkKind::Addrsig) {}
@@ -385,6 +389,27 @@ struct DependentLibrariesSection : Section {
}
};
+// Represents the call graph profile section entry.
+struct CallGraphEntry {
+ // The symbol of the source of the edge.
+ StringRef From;
+ // The symbol index of the destination of the edge.
+ StringRef To;
+ // The weight of the edge.
+ uint64_t Weight;
+};
+
+struct CallGraphProfileSection : Section {
+ Optional<std::vector<CallGraphEntry>> Entries;
+ Optional<yaml::BinaryRef> Content;
+
+ CallGraphProfileSection() : Section(ChunkKind::CallGraphProfile) {}
+
+ static bool classof(const Chunk *S) {
+ return S->Kind == ChunkKind::CallGraphProfile;
+ }
+};
+
struct SymverSection : Section {
std::vector<uint16_t> Entries;
@@ -425,7 +450,7 @@ struct Group : Section {
struct Relocation {
llvm::yaml::Hex64 Offset;
- int64_t Addend;
+ YAMLIntUInt Addend;
ELF_REL Type;
Optional<StringRef> Symbol;
};
@@ -483,8 +508,24 @@ struct MipsABIFlags : Section {
}
};
+struct ProgramHeader {
+ ELF_PT Type;
+ ELF_PF Flags;
+ llvm::yaml::Hex64 VAddr;
+ llvm::yaml::Hex64 PAddr;
+ Optional<llvm::yaml::Hex64> Align;
+ Optional<llvm::yaml::Hex64> FileSize;
+ Optional<llvm::yaml::Hex64> MemSize;
+ Optional<llvm::yaml::Hex64> Offset;
+
+ std::vector<SectionName> Sections;
+ // This vector is parallel to Sections and contains corresponding chunks.
+ std::vector<Chunk *> Chunks;
+};
+
struct Object {
FileHeader Header;
+ Optional<SectionHeaderTable> SectionHeaders;
std::vector<ProgramHeader> ProgramHeaders;
// An object might contain output section descriptions as well as
@@ -497,6 +538,7 @@ struct Object {
// being a single SHT_SYMTAB section are upheld.
Optional<std::vector<Symbol>> Symbols;
Optional<std::vector<Symbol>> DynamicSymbols;
+ Optional<DWARFYAML::Data> DWARF;
std::vector<Section *> getSections() {
std::vector<Section *> Ret;
@@ -510,12 +552,13 @@ struct Object {
} // end namespace ELFYAML
} // end namespace llvm
-LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::AddrsigSymbol)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::StackSizeEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::DynamicEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::LinkerOption)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::CallGraphEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::NoteEntry)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::ProgramHeader)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionHeader)
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Chunk>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::VerdefEntry)
@@ -528,6 +571,14 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::SectionName)
namespace llvm {
namespace yaml {
+template <> struct ScalarTraits<ELFYAML::YAMLIntUInt> {
+ static void output(const ELFYAML::YAMLIntUInt &Val, void *Ctx,
+ raw_ostream &Out);
+ static StringRef input(StringRef Scalar, void *Ctx,
+ ELFYAML::YAMLIntUInt &Val);
+ static QuotingType mustQuote(StringRef) { return QuotingType::None; }
+};
+
template <>
struct ScalarEnumerationTraits<ELFYAML::ELF_ET> {
static void enumeration(IO &IO, ELFYAML::ELF_ET &Value);
@@ -639,6 +690,15 @@ struct MappingTraits<ELFYAML::FileHeader> {
static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr);
};
+template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
+ static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
+ static StringRef validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
+};
+
+template <> struct MappingTraits<ELFYAML::SectionHeader> {
+ static void mapping(IO &IO, ELFYAML::SectionHeader &SHdr);
+};
+
template <> struct MappingTraits<ELFYAML::ProgramHeader> {
static void mapping(IO &IO, ELFYAML::ProgramHeader &FileHdr);
};
@@ -677,14 +737,14 @@ template <> struct MappingTraits<ELFYAML::VernauxEntry> {
static void mapping(IO &IO, ELFYAML::VernauxEntry &E);
};
-template <> struct MappingTraits<ELFYAML::AddrsigSymbol> {
- static void mapping(IO &IO, ELFYAML::AddrsigSymbol &Sym);
-};
-
template <> struct MappingTraits<ELFYAML::LinkerOption> {
static void mapping(IO &IO, ELFYAML::LinkerOption &Sym);
};
+template <> struct MappingTraits<ELFYAML::CallGraphEntry> {
+ static void mapping(IO &IO, ELFYAML::CallGraphEntry &E);
+};
+
template <> struct MappingTraits<ELFYAML::Relocation> {
static void mapping(IO &IO, ELFYAML::Relocation &Rel);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h
index 327c3b9f892b..fb6780b6d0ed 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/MachOYAML.h
@@ -27,6 +27,20 @@
namespace llvm {
namespace MachOYAML {
+struct Relocation {
+ // Offset in the section to what is being relocated.
+ llvm::yaml::Hex32 address;
+ // Symbol index if r_extern == 1 else section index.
+ uint32_t symbolnum;
+ bool is_pcrel;
+ // Real length = 2 ^ length.
+ uint8_t length;
+ bool is_extern;
+ uint8_t type;
+ bool is_scattered;
+ int32_t value;
+};
+
struct Section {
char sectname[16];
char segname[16];
@@ -41,6 +55,7 @@ struct Section {
llvm::yaml::Hex32 reserved2;
llvm::yaml::Hex32 reserved3;
Optional<llvm::yaml::BinaryRef> content;
+ std::vector<Relocation> relocations;
};
struct FileHeader {
@@ -143,6 +158,7 @@ struct UniversalBinary {
} // end namespace llvm
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Relocation)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::BindOpcode)
@@ -198,6 +214,10 @@ template <> struct MappingTraits<MachOYAML::ExportEntry> {
static void mapping(IO &IO, MachOYAML::ExportEntry &ExportEntry);
};
+template <> struct MappingTraits<MachOYAML::Relocation> {
+ static void mapping(IO &IO, MachOYAML::Relocation &R);
+};
+
template <> struct MappingTraits<MachOYAML::Section> {
static void mapping(IO &IO, MachOYAML::Section &Section);
static StringRef validate(IO &io, MachOYAML::Section &Section);
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h
index 15a8cc215020..bffb314e2d3b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/WasmYAML.h
@@ -107,8 +107,10 @@ struct Function {
struct Relocation {
RelocType Type;
uint32_t Index;
+ // TODO(wvo): this would strictly be better as Hex64, but that will change
+ // all existing obj2yaml output.
yaml::Hex32 Offset;
- int32_t Addend;
+ int64_t Addend;
};
struct DataSegment {
@@ -309,24 +311,24 @@ struct MemorySection : Section {
std::vector<Limits> Memories;
};
-struct GlobalSection : Section {
- GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
+struct EventSection : Section {
+ EventSection() : Section(wasm::WASM_SEC_EVENT) {}
static bool classof(const Section *S) {
- return S->Type == wasm::WASM_SEC_GLOBAL;
+ return S->Type == wasm::WASM_SEC_EVENT;
}
- std::vector<Global> Globals;
+ std::vector<Event> Events;
};
-struct EventSection : Section {
- EventSection() : Section(wasm::WASM_SEC_EVENT) {}
+struct GlobalSection : Section {
+ GlobalSection() : Section(wasm::WASM_SEC_GLOBAL) {}
static bool classof(const Section *S) {
- return S->Type == wasm::WASM_SEC_EVENT;
+ return S->Type == wasm::WASM_SEC_GLOBAL;
}
- std::vector<Event> Events;
+ std::vector<Global> Globals;
};
struct ExportSection : Section {
diff --git a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h
index 386551337d86..34def363a55b 100644
--- a/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h
+++ b/contrib/llvm-project/llvm/include/llvm/ObjectYAML/yaml2obj.h
@@ -11,14 +11,14 @@
#ifndef LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H
#define LLVM_TOOLS_YAML2OBJ_YAML2OBJ_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Error.h"
+#include "llvm/ADT/STLExtras.h"
#include <memory>
namespace llvm {
class raw_ostream;
template <typename T> class SmallVectorImpl;
-template <typename T> class Expected;
+class StringRef;
+class Twine;
namespace object {
class ObjectFile;
@@ -47,14 +47,15 @@ struct YamlObjectFile;
using ErrorHandler = llvm::function_ref<void(const Twine &Msg)>;
bool yaml2coff(COFFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
-bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
+bool yaml2elf(ELFYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH,
+ uint64_t MaxSize);
bool yaml2macho(YamlObjectFile &Doc, raw_ostream &Out, ErrorHandler EH);
bool yaml2minidump(MinidumpYAML::Object &Doc, raw_ostream &Out,
ErrorHandler EH);
bool yaml2wasm(WasmYAML::Object &Doc, raw_ostream &Out, ErrorHandler EH);
bool convertYAML(Input &YIn, raw_ostream &Out, ErrorHandler ErrHandler,
- unsigned DocNum = 1);
+ unsigned DocNum = 1, uint64_t MaxSize = UINT64_MAX);
/// Convenience function for tests.
std::unique_ptr<object::ObjectFile>
diff --git a/contrib/llvm-project/llvm/include/llvm/Option/OptParser.td b/contrib/llvm-project/llvm/include/llvm/Option/OptParser.td
index a68f17a8b10b..e32355444d7b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Option/OptParser.td
+++ b/contrib/llvm-project/llvm/include/llvm/Option/OptParser.td
@@ -97,6 +97,18 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
OptionGroup Group = ?;
Option Alias = ?;
list<string> AliasArgs = [];
+ string MarshallingKind = ?;
+ code KeyPath = ?;
+ code DefaultValue = ?;
+ bit ShouldAlwaysEmit = 0;
+ // Used by the Flag option kind.
+ bit IsPositive = 1;
+ // Used by the String option kind.
+ code NormalizerRetTy = ?;
+ code NormalizedValuesScope = "";
+ code Normalizer = "";
+ code Denormalizer = "";
+ list<code> NormalizedValues = ?;
}
// Helpers for defining options.
@@ -130,6 +142,37 @@ class MetaVarName<string name> { string MetaVarName = name; }
class Values<string value> { string Values = value; }
class ValuesCode<code valuecode> { code ValuesCode = valuecode; }
+// Helpers for defining marshalling information.
+
+class MarshallingInfo<code keypath, code defaultvalue> {
+ code KeyPath = keypath;
+ code DefaultValue = defaultvalue;
+}
+class MarshallingInfoString<code keypath, code defaultvalue, code normalizerretty>
+ : MarshallingInfo<keypath, defaultvalue> {
+ string MarshallingKind = "string";
+ code NormalizerRetTy = normalizerretty;
+}
+
+class MarshallingInfoFlag<code keypath, code defaultvalue>
+ : MarshallingInfo<keypath, defaultvalue> {
+ string MarshallingKind = "flag";
+}
+
+// Mixins for additional marshalling attributes.
+
+class IsNegative { bit IsPositive = 0; }
+class AlwaysEmit { bit ShouldAlwaysEmit = 1; }
+class Normalizer<code normalizer> { code Normalizer = normalizer; }
+class Denormalizer<code denormalizer> { code Denormalizer = denormalizer; }
+class NormalizedValuesScope<code scope> { code NormalizedValuesScope = scope; }
+class NormalizedValues<list<code> definitions> { list<code> NormalizedValues = definitions; }
+class DenormalizeString { code Denormalizer = "denormalizeString"; }
+class AutoNormalizeEnum {
+ code Normalizer = "normalizeSimpleEnum";
+ code Denormalizer = "denormalizeSimpleEnum";
+}
+
// Predefined options.
// FIXME: Have generator validate that these appear in correct position (and
diff --git a/contrib/llvm-project/llvm/include/llvm/Option/Option.h b/contrib/llvm-project/llvm/include/llvm/Option/Option.h
index 33813d28d274..73ee8e0073b8 100644
--- a/contrib/llvm-project/llvm/include/llvm/Option/Option.h
+++ b/contrib/llvm-project/llvm/include/llvm/Option/Option.h
@@ -130,11 +130,23 @@ public:
/// Get the name of this option with the default prefix.
std::string getPrefixedName() const {
- std::string Ret = getPrefix();
+ std::string Ret(getPrefix());
Ret += getName();
return Ret;
}
+ /// Get the help text for this option.
+ StringRef getHelpText() const {
+ assert(Info && "Must have a valid info!");
+ return Info->HelpText;
+ }
+
+ /// Get the meta-variable list for this option.
+ StringRef getMetaVar() const {
+ assert(Info && "Must have a valid info!");
+ return Info->MetaVar;
+ }
+
unsigned getNumArgs() const { return Info->Param; }
bool hasNoOptAsInput() const { return Info->Flags & RenderAsInput;}
diff --git a/contrib/llvm-project/llvm/include/llvm/Pass.h b/contrib/llvm-project/llvm/include/llvm/Pass.h
index 49419844e7ad..2fe7aee2e37e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Pass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Pass.h
@@ -28,14 +28,12 @@
#ifndef LLVM_PASS_H
#define LLVM_PASS_H
-#include "llvm/ADT/StringRef.h"
#include <string>
namespace llvm {
class AnalysisResolver;
class AnalysisUsage;
-class BasicBlock;
class Function;
class ImmutablePass;
class Module;
@@ -43,6 +41,7 @@ class PassInfo;
class PMDataManager;
class PMStack;
class raw_ostream;
+class StringRef;
// AnalysisID - Use the PassInfo to identify a pass...
using AnalysisID = const void *;
@@ -204,14 +203,17 @@ public:
template<typename AnalysisType>
AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
- template<typename AnalysisType>
- AnalysisType &getAnalysis(Function &F); // Defined in PassAnalysisSupport.h
+ template <typename AnalysisType>
+ AnalysisType &
+ getAnalysis(Function &F,
+ bool *Changed = nullptr); // Defined in PassAnalysisSupport.h
template<typename AnalysisType>
AnalysisType &getAnalysisID(AnalysisID PI) const;
- template<typename AnalysisType>
- AnalysisType &getAnalysisID(AnalysisID PI, Function &F);
+ template <typename AnalysisType>
+ AnalysisType &getAnalysisID(AnalysisID PI, Function &F,
+ bool *Changed = nullptr);
};
//===----------------------------------------------------------------------===//
diff --git a/contrib/llvm-project/llvm/include/llvm/PassAnalysisSupport.h b/contrib/llvm-project/llvm/include/llvm/PassAnalysisSupport.h
index 1228534deb95..84df171d38d8 100644
--- a/contrib/llvm-project/llvm/include/llvm/PassAnalysisSupport.h
+++ b/contrib/llvm-project/llvm/include/llvm/PassAnalysisSupport.h
@@ -15,13 +15,16 @@
//
//===----------------------------------------------------------------------===//
+#if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H)
+#error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead"
+#endif
+
#ifndef LLVM_PASSANALYSISSUPPORT_H
#define LLVM_PASSANALYSISSUPPORT_H
-#include "Pass.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
#include <cassert>
+#include <tuple>
#include <utility>
#include <vector>
@@ -30,6 +33,7 @@ namespace llvm {
class Function;
class Pass;
class PMDataManager;
+class StringRef;
//===----------------------------------------------------------------------===//
/// Represent the analysis usage information of a pass. This tracks analyses
@@ -164,7 +168,7 @@ public:
}
/// Find pass that is implementing PI. Initialize pass for Function F.
- Pass *findImplPass(Pass *P, AnalysisID PI, Function &F);
+ std::tuple<Pass *, bool> findImplPass(Pass *P, AnalysisID PI, Function &F);
void addAnalysisImplsPair(AnalysisID PI, Pass *P) {
if (findImplPass(PI) == P)
@@ -243,23 +247,33 @@ AnalysisType &Pass::getAnalysisID(AnalysisID PI) const {
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
/// to the analysis information that they claim to use by overriding the
-/// getAnalysisUsage function.
-template<typename AnalysisType>
-AnalysisType &Pass::getAnalysis(Function &F) {
+/// getAnalysisUsage function. If as part of the dependencies, an IR
+/// transformation is triggered (e.g. because the analysis requires
+/// BreakCriticalEdges), and Changed is non null, *Changed is updated.
+template <typename AnalysisType>
+AnalysisType &Pass::getAnalysis(Function &F, bool *Changed) {
assert(Resolver &&"Pass has not been inserted into a PassManager object!");
- return getAnalysisID<AnalysisType>(&AnalysisType::ID, F);
+ return getAnalysisID<AnalysisType>(&AnalysisType::ID, F, Changed);
}
-template<typename AnalysisType>
-AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F) {
+template <typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(AnalysisID PI, Function &F, bool *Changed) {
assert(PI && "getAnalysis for unregistered pass!");
assert(Resolver && "Pass has not been inserted into a PassManager object!");
// PI *must* appear in AnalysisImpls. Because the number of passes used
// should be a small number, we just do a linear search over a (dense)
// vector.
- Pass *ResultPass = Resolver->findImplPass(this, PI, F);
+ Pass *ResultPass;
+ bool LocalChanged;
+ std::tie(ResultPass, LocalChanged) = Resolver->findImplPass(this, PI, F);
+
assert(ResultPass && "Unable to find requested analysis info");
+ if (Changed)
+ *Changed |= LocalChanged;
+ else
+ assert(!LocalChanged &&
+ "A pass trigged a code update but the update status is lost");
// Because the AnalysisType may not be a subclass of pass (for
// AnalysisGroups), we use getAdjustedAnalysisPointer here to potentially
diff --git a/contrib/llvm-project/llvm/include/llvm/PassSupport.h b/contrib/llvm-project/llvm/include/llvm/PassSupport.h
index ab90217ce4a8..e95ed7a1d88f 100644
--- a/contrib/llvm-project/llvm/include/llvm/PassSupport.h
+++ b/contrib/llvm-project/llvm/include/llvm/PassSupport.h
@@ -17,6 +17,10 @@
//
//===----------------------------------------------------------------------===//
+#if !defined(LLVM_PASS_H) || defined(LLVM_PASSSUPPORT_H)
+#error "Do not include <PassSupport.h>; include <Pass.h> instead"
+#endif
+
#ifndef LLVM_PASSSUPPORT_H
#define LLVM_PASSSUPPORT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h b/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h
index e7db8fd421fe..0357e4a2fc05 100644
--- a/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h
@@ -19,6 +19,7 @@
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/Error.h"
+#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include <vector>
@@ -73,16 +74,15 @@ public:
/// can be set in the PassBuilder when using a LLVM as a library.
PipelineTuningOptions();
- /// Tuning option to set loop interleaving on/off. Its default value is that
- /// of the flag: `-interleave-loops`.
+ /// Tuning option to set loop interleaving on/off, set based on opt level.
bool LoopInterleaving;
- /// Tuning option to enable/disable loop vectorization. Its default value is
- /// that of the flag: `-vectorize-loops`.
+ /// Tuning option to enable/disable loop vectorization, set based on opt
+ /// level.
bool LoopVectorization;
- /// Tuning option to enable/disable slp loop vectorization. Its default value
- /// is that of the flag: `vectorize-slp`.
+ /// Tuning option to enable/disable slp loop vectorization, set based on opt
+ /// level.
bool SLPVectorization;
/// Tuning option to enable/disable loop unrolling. Its default value is true.
@@ -92,6 +92,12 @@ public:
/// is that of the flag: `-forget-scev-loop-unroll`.
bool ForgetAllSCEVInLoopUnroll;
+ /// Tuning option to enable/disable coroutine intrinsic lowering. Its default
+ /// value is false. Frontends such as Clang may enable this conditionally. For
+ /// example, Clang enables this option if the flags `-std=c++2a` or above, or
+ /// `-fcoroutines-ts`, have been specified.
+ bool Coroutines;
+
/// Tuning option to cap the number of calls to retrive clobbering accesses in
/// MemorySSA, in LICM.
unsigned LicmMssaOptCap;
@@ -99,6 +105,10 @@ public:
/// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
/// the number of access is too large.
unsigned LicmMssaNoAccForPromotionCap;
+
+ /// Tuning option to enable/disable call graph profile. Its default value is
+ /// that of the flag: `-enable-npm-call-graph-profile`.
+ bool CallGraphProfile;
};
/// This class provides access to building LLVM's passes.
@@ -143,11 +153,26 @@ public:
///
/// This enumerates the LLVM-provided high-level optimization levels. Each
/// level has a specific goal and rationale.
- enum OptimizationLevel {
+ class OptimizationLevel final {
+ unsigned SpeedLevel = 2;
+ unsigned SizeLevel = 0;
+ OptimizationLevel(unsigned SpeedLevel, unsigned SizeLevel)
+ : SpeedLevel(SpeedLevel), SizeLevel(SizeLevel) {
+ // Check that only valid combinations are passed.
+ assert(SpeedLevel <= 3 &&
+ "Optimization level for speed should be 0, 1, 2, or 3");
+ assert(SizeLevel <= 2 &&
+ "Optimization level for size should be 0, 1, or 2");
+ assert((SizeLevel == 0 || SpeedLevel == 2) &&
+ "Optimize for size should be encoded with speedup level == 2");
+ }
+
+ public:
+ OptimizationLevel() = default;
/// Disable as many optimizations as possible. This doesn't completely
/// disable the optimizer in all cases, for example always_inline functions
/// can be required to be inlined for correctness.
- O0,
+ static const OptimizationLevel O0;
/// Optimize quickly without destroying debuggability.
///
@@ -161,10 +186,9 @@ public:
///
/// As an example, complex loop transformations such as versioning,
/// vectorization, or fusion don't make sense here due to the degree to
- /// which the executed code differs from the source code, and the compile time
- /// cost.
- O1,
-
+ /// which the executed code differs from the source code, and the compile
+ /// time cost.
+ static const OptimizationLevel O1;
/// Optimize for fast execution as much as possible without triggering
/// significant incremental compile time or code size growth.
///
@@ -181,8 +205,7 @@ public:
///
/// This is expected to be a good default optimization level for the vast
/// majority of users.
- O2,
-
+ static const OptimizationLevel O2;
/// Optimize for fast execution as much as possible.
///
/// This mode is significantly more aggressive in trading off compile time
@@ -197,8 +220,7 @@ public:
/// order to make even significantly slower compile times at least scale
/// reasonably. This does not preclude very substantial constant factor
/// costs though.
- O3,
-
+ static const OptimizationLevel O3;
/// Similar to \c O2 but tries to optimize for small code size instead of
/// fast execution without triggering significant incremental execution
/// time slowdowns.
@@ -209,8 +231,7 @@ public:
/// A consequence of the different core goal is that this should in general
/// produce substantially smaller executables that still run in
/// a reasonable amount of time.
- Os,
-
+ static const OptimizationLevel Os;
/// A very specialized mode that will optimize for code size at any and all
/// costs.
///
@@ -218,7 +239,24 @@ public:
/// any effort taken to reduce the size is worth it regardless of the
/// execution time impact. You should expect this level to produce rather
/// slow, but very small, code.
- Oz
+ static const OptimizationLevel Oz;
+
+ bool isOptimizingForSpeed() const {
+ return SizeLevel == 0 && SpeedLevel > 0;
+ }
+
+ bool isOptimizingForSize() const { return SizeLevel > 0; }
+
+ bool operator==(const OptimizationLevel &Other) const {
+ return SizeLevel == Other.SizeLevel && SpeedLevel == Other.SpeedLevel;
+ }
+ bool operator!=(const OptimizationLevel &Other) const {
+ return SizeLevel != Other.SizeLevel || SpeedLevel != Other.SpeedLevel;
+ }
+
+ unsigned getSpeedupLevel() const { return SpeedLevel; }
+
+ unsigned getSizeLevel() const { return SizeLevel; }
};
explicit PassBuilder(TargetMachine *TM = nullptr,
@@ -306,6 +344,12 @@ public:
ThinLTOPhase Phase,
bool DebugLogging = false);
+ /// Construct the module pipeline that performs inlining as well as
+ /// the inlining-driven cleanups.
+ ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
+ ThinLTOPhase Phase,
+ bool DebugLogging = false);
+
/// Construct the core LLVM module optimization pipeline.
///
/// This pipeline focuses on optimizing the execution speed of the IR. It
@@ -471,6 +515,12 @@ public:
/// returns false.
Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
+ /// Returns true if the pass name is the name of an alias analysis pass.
+ bool isAAPassName(StringRef PassName);
+
+ /// Returns true if the pass name is the name of a (non-alias) analysis pass.
+ bool isAnalysisPassName(StringRef PassName);
+
/// Register a callback for a default optimizer pipeline extension
/// point
///
@@ -556,7 +606,7 @@ public:
/// is not triggered at O0. Extensions to the O0 pipeline should append their
/// passes to the end of the overall pipeline.
void registerOptimizerLastEPCallback(
- const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
OptimizerLastEPCallbacks.push_back(C);
}
@@ -639,6 +689,10 @@ public:
}
private:
+ // O1 pass pipeline
+ FunctionPassManager buildO1FunctionSimplificationPipeline(
+ OptimizationLevel Level, ThinLTOPhase Phase, bool DebugLogging = false);
+
static Optional<std::vector<PipelineElement>>
parsePipelineText(StringRef Text);
@@ -684,7 +738,7 @@ private:
CGSCCOptimizerLateEPCallbacks;
SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
VectorizerStartEPCallbacks;
- SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
OptimizerLastEPCallbacks;
// Module callbacks
SmallVector<std::function<void(ModulePassManager &)>, 2>
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index f272e8c03903..bf0dffc9653c 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -20,10 +20,10 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
@@ -54,7 +54,8 @@ enum class coveragemap_error {
no_data_found,
unsupported_version,
truncated,
- malformed
+ malformed,
+ decompression_failed
};
const std::error_category &coveragemap_category();
@@ -678,37 +679,107 @@ getLineCoverageStats(const coverage::CoverageData &CD) {
return make_range(Begin, End);
}
-// Profile coverage map has the following layout:
-// [CoverageMapFileHeader]
-// [ArrayStart]
-// [CovMapFunctionRecord]
-// [CovMapFunctionRecord]
-// ...
-// [ArrayEnd]
-// [Encoded Region Mapping Data]
+// Coverage mappping data (V2) has the following layout:
+// IPSK_covmap:
+// [CoverageMapFileHeader]
+// [ArrayStart]
+// [CovMapFunctionRecordV2]
+// [CovMapFunctionRecordV2]
+// ...
+// [ArrayEnd]
+// [Encoded Filenames and Region Mapping Data]
+//
+// Coverage mappping data (V3) has the following layout:
+// IPSK_covmap:
+// [CoverageMapFileHeader]
+// [Encoded Filenames]
+// IPSK_covfun:
+// [ArrayStart]
+// odr_name_1: [CovMapFunctionRecordV3]
+// odr_name_2: [CovMapFunctionRecordV3]
+// ...
+// [ArrayEnd]
+//
+// Both versions of the coverage mapping format encode the same information,
+// but the V3 format does so more compactly by taking advantage of linkonce_odr
+// semantics (it allows exactly 1 function record per name reference).
+
+/// This namespace defines accessors shared by different versions of coverage
+/// mapping records.
+namespace accessors {
+
+/// Return the structural hash associated with the function.
+template <class FuncRecordTy, support::endianness Endian>
+uint64_t getFuncHash(const FuncRecordTy *Record) {
+ return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
+}
+
+/// Return the coverage map data size for the function.
+template <class FuncRecordTy, support::endianness Endian>
+uint64_t getDataSize(const FuncRecordTy *Record) {
+ return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
+}
+
+/// Return the function lookup key. The value is considered opaque.
+template <class FuncRecordTy, support::endianness Endian>
+uint64_t getFuncNameRef(const FuncRecordTy *Record) {
+ return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
+}
+
+/// Return the PGO name of the function. Used for formats in which the name is
+/// a hash.
+template <class FuncRecordTy, support::endianness Endian>
+Error getFuncNameViaRef(const FuncRecordTy *Record,
+ InstrProfSymtab &ProfileNames, StringRef &FuncName) {
+ uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
+ FuncName = ProfileNames.getFuncName(NameRef);
+ return Error::success();
+}
+
+/// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
+/// coverage mapping is attached to the file header, instead of to the function
+/// record.
+template <class FuncRecordTy, support::endianness Endian>
+StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record,
+ const char *MappingBuf) {
+ return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
+}
+
+/// Advance to the next out-of-line coverage mapping and its associated
+/// function record.
+template <class FuncRecordTy, support::endianness Endian>
+std::pair<const char *, const FuncRecordTy *>
+advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
+ return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
+}
+
+} // end namespace accessors
+
LLVM_PACKED_START
-template <class IntPtrT> struct CovMapFunctionRecordV1 {
+template <class IntPtrT>
+struct CovMapFunctionRecordV1 {
+ using ThisT = CovMapFunctionRecordV1<IntPtrT>;
+
#define COVMAP_V1
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
#include "llvm/ProfileData/InstrProfData.inc"
#undef COVMAP_V1
+ CovMapFunctionRecordV1() = delete;
- // Return the structural hash associated with the function.
template <support::endianness Endian> uint64_t getFuncHash() const {
- return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
+ return accessors::getFuncHash<ThisT, Endian>(this);
}
- // Return the coverage map data size for the funciton.
- template <support::endianness Endian> uint32_t getDataSize() const {
- return support::endian::byte_swap<uint32_t, Endian>(DataSize);
+ template <support::endianness Endian> uint64_t getDataSize() const {
+ return accessors::getDataSize<ThisT, Endian>(this);
}
- // Return function lookup key. The value is consider opaque.
+ /// Return function lookup key. The value is consider opaque.
template <support::endianness Endian> IntPtrT getFuncNameRef() const {
return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
}
- // Return the PGO name of the function */
+ /// Return the PGO name of the function.
template <support::endianness Endian>
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
IntPtrT NameRef = getFuncNameRef<Endian>();
@@ -718,33 +789,119 @@ template <class IntPtrT> struct CovMapFunctionRecordV1 {
return make_error<CoverageMapError>(coveragemap_error::malformed);
return Error::success();
}
+
+ template <support::endianness Endian>
+ std::pair<const char *, const ThisT *>
+ advanceByOne(const char *MappingBuf) const {
+ return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
+ }
+
+ template <support::endianness Endian> uint64_t getFilenamesRef() const {
+ llvm_unreachable("V1 function format does not contain a filenames ref");
+ }
+
+ template <support::endianness Endian>
+ StringRef getCoverageMapping(const char *MappingBuf) const {
+ return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
+ MappingBuf);
+ }
};
-struct CovMapFunctionRecord {
+struct CovMapFunctionRecordV2 {
+ using ThisT = CovMapFunctionRecordV2;
+
+#define COVMAP_V2
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
#include "llvm/ProfileData/InstrProfData.inc"
+#undef COVMAP_V2
+ CovMapFunctionRecordV2() = delete;
- // Return the structural hash associated with the function.
template <support::endianness Endian> uint64_t getFuncHash() const {
- return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
+ return accessors::getFuncHash<ThisT, Endian>(this);
}
- // Return the coverage map data size for the funciton.
- template <support::endianness Endian> uint32_t getDataSize() const {
- return support::endian::byte_swap<uint32_t, Endian>(DataSize);
+ template <support::endianness Endian> uint64_t getDataSize() const {
+ return accessors::getDataSize<ThisT, Endian>(this);
}
- // Return function lookup key. The value is consider opaque.
template <support::endianness Endian> uint64_t getFuncNameRef() const {
- return support::endian::byte_swap<uint64_t, Endian>(NameRef);
+ return accessors::getFuncNameRef<ThisT, Endian>(this);
}
- // Return the PGO name of the function */
template <support::endianness Endian>
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
- uint64_t NameRef = getFuncNameRef<Endian>();
- FuncName = ProfileNames.getFuncName(NameRef);
- return Error::success();
+ return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
+ FuncName);
+ }
+
+ template <support::endianness Endian>
+ std::pair<const char *, const ThisT *>
+ advanceByOne(const char *MappingBuf) const {
+ return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
+ }
+
+ template <support::endianness Endian> uint64_t getFilenamesRef() const {
+ llvm_unreachable("V2 function format does not contain a filenames ref");
+ }
+
+ template <support::endianness Endian>
+ StringRef getCoverageMapping(const char *MappingBuf) const {
+ return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
+ MappingBuf);
+ }
+};
+
+struct CovMapFunctionRecordV3 {
+ using ThisT = CovMapFunctionRecordV3;
+
+#define COVMAP_V3
+#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
+#include "llvm/ProfileData/InstrProfData.inc"
+#undef COVMAP_V3
+ CovMapFunctionRecordV3() = delete;
+
+ template <support::endianness Endian> uint64_t getFuncHash() const {
+ return accessors::getFuncHash<ThisT, Endian>(this);
+ }
+
+ template <support::endianness Endian> uint64_t getDataSize() const {
+ return accessors::getDataSize<ThisT, Endian>(this);
+ }
+
+ template <support::endianness Endian> uint64_t getFuncNameRef() const {
+ return accessors::getFuncNameRef<ThisT, Endian>(this);
+ }
+
+ template <support::endianness Endian>
+ Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
+ return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
+ FuncName);
+ }
+
+ /// Get the filename set reference.
+ template <support::endianness Endian> uint64_t getFilenamesRef() const {
+ return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
+ }
+
+ /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
+ /// out-of-line coverage mapping data only.
+ template <support::endianness Endian>
+ StringRef getCoverageMapping(const char *) const {
+ return StringRef(&CoverageMapping, getDataSize<Endian>());
+ }
+
+ // Advance to the next inline coverage mapping and its associated function
+ // record. Ignore the out-of-line coverage mapping buffer.
+ template <support::endianness Endian>
+ std::pair<const char *, const CovMapFunctionRecordV3 *>
+ advanceByOne(const char *) const {
+ assert(isAddrAligned(Align(8), this) && "Function record not aligned");
+ const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
+ sizeof(char) + getDataSize<Endian>();
+ // Each function record has an alignment of 8, so we need to adjust
+ // alignment before reading the next record.
+ Next += offsetToAlignedAddr(Next, Align(8));
+ return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
}
};
@@ -781,12 +938,24 @@ enum CovMapVersion {
// A new interpretation of the columnEnd field is added in order to mark
// regions as gap areas.
Version3 = 2,
- // The current version is Version3
+ // Function records are named, uniqued, and moved to a dedicated section.
+ Version4 = 3,
+ // The current version is Version4.
CurrentVersion = INSTR_PROF_COVMAP_VERSION
};
template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
- using CovMapFuncRecordType = CovMapFunctionRecord;
+ using CovMapFuncRecordType = CovMapFunctionRecordV3;
+ using NameRefType = uint64_t;
+};
+
+template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
+ using CovMapFuncRecordType = CovMapFunctionRecordV2;
+ using NameRefType = uint64_t;
+};
+
+template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
+ using CovMapFuncRecordType = CovMapFunctionRecordV2;
using NameRefType = uint64_t;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index 57a2aaefd660..97f4c32eb035 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -113,20 +113,6 @@ protected:
Error readString(StringRef &Result);
};
-/// Reader for the raw coverage filenames.
-class RawCoverageFilenamesReader : public RawCoverageReader {
- std::vector<StringRef> &Filenames;
-
-public:
- RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
- : RawCoverageReader(Data), Filenames(Filenames) {}
- RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
- RawCoverageFilenamesReader &
- operator=(const RawCoverageFilenamesReader &) = delete;
-
- Error read();
-};
-
/// Checks if the given coverage mapping data is exported for
/// an unused function.
class RawCoverageMappingDummyChecker : public RawCoverageReader {
@@ -188,6 +174,8 @@ public:
FilenamesBegin(FilenamesBegin), FilenamesSize(FilenamesSize) {}
};
+ using DecompressedData = std::vector<std::unique_ptr<SmallVector<char, 0>>>;
+
private:
std::vector<StringRef> Filenames;
std::vector<ProfileMappingRecord> MappingRecords;
@@ -197,7 +185,17 @@ private:
std::vector<CounterExpression> Expressions;
std::vector<CounterMappingRegion> MappingRegions;
- BinaryCoverageReader() = default;
+ // Used to tie the lifetimes of coverage function records to the lifetime of
+ // this BinaryCoverageReader instance. Needed to support the format change in
+ // D69471, which can split up function records into multiple sections on ELF.
+ std::string FuncRecords;
+
+ // Used to tie the lifetimes of decompressed strings to the lifetime of this
+ // BinaryCoverageReader instance.
+ DecompressedData Decompressed;
+
+ BinaryCoverageReader(std::string &&FuncRecords)
+ : FuncRecords(std::move(FuncRecords)) {}
public:
BinaryCoverageReader(const BinaryCoverageReader &) = delete;
@@ -208,7 +206,7 @@ public:
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers);
static Expected<std::unique_ptr<BinaryCoverageReader>>
- createCoverageReaderFromBuffer(StringRef Coverage,
+ createCoverageReaderFromBuffer(StringRef Coverage, std::string &&FuncRecords,
InstrProfSymtab &&ProfileNames,
uint8_t BytesInAddress,
support::endianness Endian);
@@ -216,6 +214,24 @@ public:
Error readNextRecord(CoverageMappingRecord &Record) override;
};
+/// Reader for the raw coverage filenames.
+class RawCoverageFilenamesReader : public RawCoverageReader {
+ std::vector<StringRef> &Filenames;
+
+ // Read an uncompressed sequence of filenames.
+ Error readUncompressed(uint64_t NumFilenames);
+
+public:
+ RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)
+ : RawCoverageReader(Data), Filenames(Filenames) {}
+ RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete;
+ RawCoverageFilenamesReader &
+ operator=(const RawCoverageFilenamesReader &) = delete;
+
+ Error read(CovMapVersion Version,
+ BinaryCoverageReader::DecompressedData &Decompressed);
+};
+
} // end namespace coverage
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
index 6fcd8a09a494..303e5184d493 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
@@ -32,8 +32,9 @@ class CoverageFilenamesSectionWriter {
public:
CoverageFilenamesSectionWriter(ArrayRef<StringRef> Filenames);
- /// Write encoded filenames to the given output stream.
- void write(raw_ostream &OS);
+ /// Write encoded filenames to the given output stream. If \p Compress is
+ /// true, attempt to compress the filenames.
+ void write(raw_ostream &OS, bool Compress = true);
};
/// Writer for instrumentation based coverage mapping data.
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/GCOV.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/GCOV.h
index 004ff3f4a2e2..7b9ba4410b65 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/GCOV.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/GCOV.h
@@ -21,6 +21,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -28,6 +29,7 @@
#include <cstddef>
#include <cstdint>
#include <limits>
+#include <map>
#include <memory>
#include <string>
#include <utility>
@@ -40,14 +42,15 @@ class FileInfo;
namespace GCOV {
-enum GCOVVersion { V402, V404, V704 };
+enum GCOVVersion { V304, V407, V408, V800, V900 };
/// A struct for passing gcov options between functions.
struct Options {
- Options(bool A, bool B, bool C, bool F, bool P, bool U, bool L, bool N, bool X)
+ Options(bool A, bool B, bool C, bool F, bool P, bool U, bool I, bool L,
+ bool N, bool T, bool X)
: AllBlocks(A), BranchInfo(B), BranchCount(C), FuncCoverage(F),
- PreservePaths(P), UncondBranch(U), LongFileNames(L), NoOutput(N),
- HashFilenames(X) {}
+ PreservePaths(P), UncondBranch(U), Intermediate(I), LongFileNames(L),
+ NoOutput(N), UseStdout(T), HashFilenames(X) {}
bool AllBlocks;
bool BranchInfo;
@@ -55,8 +58,10 @@ struct Options {
bool FuncCoverage;
bool PreservePaths;
bool UncondBranch;
+ bool Intermediate;
bool LongFileNames;
bool NoOutput;
+ bool UseStdout;
bool HashFilenames;
};
@@ -67,143 +72,86 @@ struct Options {
class GCOVBuffer {
public:
GCOVBuffer(MemoryBuffer *B) : Buffer(B) {}
+ ~GCOVBuffer() { consumeError(cursor.takeError()); }
/// readGCNOFormat - Check GCNO signature is valid at the beginning of buffer.
bool readGCNOFormat() {
- StringRef File = Buffer->getBuffer().slice(0, 4);
- if (File != "oncg") {
- errs() << "Unexpected file type: " << File << ".\n";
+ StringRef buf = Buffer->getBuffer();
+ StringRef magic = buf.substr(0, 4);
+ if (magic == "gcno") {
+ de = DataExtractor(buf.substr(4), false, 0);
+ } else if (magic == "oncg") {
+ de = DataExtractor(buf.substr(4), true, 0);
+ } else {
+ errs() << "unexpected magic: " << magic << "\n";
return false;
}
- Cursor = 4;
return true;
}
/// readGCDAFormat - Check GCDA signature is valid at the beginning of buffer.
bool readGCDAFormat() {
- StringRef File = Buffer->getBuffer().slice(0, 4);
- if (File != "adcg") {
- errs() << "Unexpected file type: " << File << ".\n";
+ StringRef buf = Buffer->getBuffer();
+ StringRef magic = buf.substr(0, 4);
+ if (magic == "gcda") {
+ de = DataExtractor(buf.substr(4), false, 0);
+ } else if (magic == "adcg") {
+ de = DataExtractor(buf.substr(4), true, 0);
+ } else {
return false;
}
- Cursor = 4;
return true;
}
/// readGCOVVersion - Read GCOV version.
bool readGCOVVersion(GCOV::GCOVVersion &Version) {
- StringRef VersionStr = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (VersionStr == "*204") {
- Cursor += 4;
- Version = GCOV::V402;
+ std::string str(de.getBytes(cursor, 4));
+ if (str.size() != 4)
+ return false;
+ if (de.isLittleEndian())
+ std::reverse(str.begin(), str.end());
+ int ver = str[0] >= 'A'
+ ? (str[0] - 'A') * 100 + (str[1] - '0') * 10 + str[2] - '0'
+ : (str[0] - '0') * 10 + str[2] - '0';
+ if (ver >= 90) {
+ // PR gcov-profile/84846, r269678
+ Version = GCOV::V900;
return true;
- }
- if (VersionStr == "*404") {
- Cursor += 4;
- Version = GCOV::V404;
+ } else if (ver >= 80) {
+ // PR gcov-profile/48463
+ Version = GCOV::V800;
return true;
- }
- if (VersionStr == "*704") {
- Cursor += 4;
- Version = GCOV::V704;
+ } else if (ver >= 48) {
+ // r189778: the exit block moved from the last to the second.
+ Version = GCOV::V408;
+ return true;
+ } else if (ver >= 47) {
+ // r173147: split checksum into cfg checksum and line checksum.
+ Version = GCOV::V407;
+ return true;
+ } else if (ver >= 34) {
+ Version = GCOV::V304;
return true;
}
- errs() << "Unexpected version: " << VersionStr << ".\n";
+ errs() << "unexpected version: " << str << "\n";
return false;
}
- /// readFunctionTag - If cursor points to a function tag then increment the
- /// cursor and return true otherwise return false.
- bool readFunctionTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
- Tag[3] != '\1') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readBlockTag - If cursor points to a block tag then increment the
- /// cursor and return true otherwise return false.
- bool readBlockTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x41' ||
- Tag[3] != '\x01') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readEdgeTag - If cursor points to an edge tag then increment the
- /// cursor and return true otherwise return false.
- bool readEdgeTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x43' ||
- Tag[3] != '\x01') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readLineTag - If cursor points to a line tag then increment the
- /// cursor and return true otherwise return false.
- bool readLineTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\x45' ||
- Tag[3] != '\x01') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readArcTag - If cursor points to an gcda arc tag then increment the
- /// cursor and return true otherwise return false.
- bool readArcTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\xa1' ||
- Tag[3] != '\1') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readObjectTag - If cursor points to an object summary tag then increment
- /// the cursor and return true otherwise return false.
- bool readObjectTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
- Tag[3] != '\xa1') {
- return false;
- }
- Cursor += 4;
- return true;
- }
-
- /// readProgramTag - If cursor points to a program summary tag then increment
- /// the cursor and return true otherwise return false.
- bool readProgramTag() {
- StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- if (Tag.empty() || Tag[0] != '\0' || Tag[1] != '\0' || Tag[2] != '\0' ||
- Tag[3] != '\xa3') {
- return false;
- }
- Cursor += 4;
- return true;
+ uint32_t getWord() { return de.getU32(cursor); }
+ StringRef getString() {
+ uint32_t len;
+ if (!readInt(len) || len == 0)
+ return {};
+ return de.getBytes(cursor, len * 4).split('\0').first;
}
bool readInt(uint32_t &Val) {
- if (Buffer->getBuffer().size() < Cursor + 4) {
- errs() << "Unexpected end of memory buffer: " << Cursor + 4 << ".\n";
+ if (cursor.tell() + 4 > de.size()) {
+ Val = 0;
+ errs() << "unexpected end of memory buffer: " << cursor.tell() << "\n";
return false;
}
- StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor + 4);
- Cursor += 4;
- Val = *(const uint32_t *)(Str.data());
+ Val = de.getU32(cursor);
return true;
}
@@ -216,28 +164,18 @@ public:
}
bool readString(StringRef &Str) {
- uint32_t Len = 0;
- // Keep reading until we find a non-zero length. This emulates gcov's
- // behaviour, which appears to do the same.
- while (Len == 0)
- if (!readInt(Len))
- return false;
- Len *= 4;
- if (Buffer->getBuffer().size() < Cursor + Len) {
- errs() << "Unexpected end of memory buffer: " << Cursor + Len << ".\n";
+ uint32_t len;
+ if (!readInt(len) || len == 0)
return false;
- }
- Str = Buffer->getBuffer().slice(Cursor, Cursor + Len).split('\0').first;
- Cursor += Len;
- return true;
+ Str = de.getBytes(cursor, len * 4).split('\0').first;
+ return bool(cursor);
}
- uint64_t getCursor() const { return Cursor; }
- void advanceCursor(uint32_t n) { Cursor += n * 4; }
+ DataExtractor de{ArrayRef<uint8_t>{}, false, 0};
+ DataExtractor::Cursor cursor{0};
private:
MemoryBuffer *Buffer;
- uint64_t Cursor = 0;
};
/// GCOVFile - Collects coverage information for one pair of coverage file
@@ -248,26 +186,38 @@ public:
bool readGCNO(GCOVBuffer &Buffer);
bool readGCDA(GCOVBuffer &Buffer);
+ GCOV::GCOVVersion getVersion() const { return Version; }
uint32_t getChecksum() const { return Checksum; }
void print(raw_ostream &OS) const;
void dump() const;
void collectLineCounts(FileInfo &FI);
+ std::vector<std::string> filenames;
+ StringMap<unsigned> filenameToIdx;
+
private:
bool GCNOInitialized = false;
GCOV::GCOVVersion Version;
uint32_t Checksum = 0;
+ StringRef cwd;
SmallVector<std::unique_ptr<GCOVFunction>, 16> Functions;
+ std::map<uint32_t, GCOVFunction *> IdentToFunction;
uint32_t RunCount = 0;
uint32_t ProgramCount = 0;
+
+ using iterator = pointee_iterator<
+ SmallVectorImpl<std::unique_ptr<GCOVFunction>>::const_iterator>;
+ iterator begin() const { return iterator(Functions.begin()); }
+ iterator end() const { return iterator(Functions.end()); }
};
-/// GCOVEdge - Collects edge information.
-struct GCOVEdge {
- GCOVEdge(GCOVBlock &S, GCOVBlock &D) : Src(S), Dst(D) {}
+struct GCOVArc {
+ GCOVArc(GCOVBlock &src, GCOVBlock &dst, bool fallthrough)
+ : src(src), dst(dst), fallthrough(fallthrough) {}
- GCOVBlock &Src;
- GCOVBlock &Dst;
+ GCOVBlock &src;
+ GCOVBlock &dst;
+ bool fallthrough;
uint64_t Count = 0;
uint64_t CyclesCount = 0;
};
@@ -278,12 +228,10 @@ public:
using BlockIterator = pointee_iterator<
SmallVectorImpl<std::unique_ptr<GCOVBlock>>::const_iterator>;
- GCOVFunction(GCOVFile &P) : Parent(P) {}
+ GCOVFunction(GCOVFile &file) : file(file) {}
- bool readGCNO(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
- bool readGCDA(GCOVBuffer &Buffer, GCOV::GCOVVersion Version);
StringRef getName() const { return Name; }
- StringRef getFilename() const { return Filename; }
+ StringRef getFilename() const;
size_t getNumBlocks() const { return Blocks.size(); }
uint64_t getEntryCount() const;
uint64_t getExitCount() const;
@@ -298,15 +246,19 @@ public:
void dump() const;
void collectLineCounts(FileInfo &FI);
-private:
- GCOVFile &Parent;
- uint32_t Ident = 0;
- uint32_t Checksum;
- uint32_t LineNumber = 0;
+ GCOVFile &file;
+ uint32_t ident = 0;
+ uint32_t linenoChecksum;
+ uint32_t cfgChecksum = 0;
+ uint32_t startLine = 0;
+ uint32_t startColumn = 0;
+ uint32_t endLine = 0;
+ uint32_t endColumn = 0;
+ uint8_t artificial = 0;
StringRef Name;
- StringRef Filename;
- SmallVector<std::unique_ptr<GCOVBlock>, 16> Blocks;
- SmallVector<std::unique_ptr<GCOVEdge>, 16> Edges;
+ unsigned srcIdx;
+ SmallVector<std::unique_ptr<GCOVBlock>, 0> Blocks;
+ SmallVector<std::unique_ptr<GCOVArc>, 0> arcs, treeArcs;
};
/// GCOVBlock - Collects block information.
@@ -319,47 +271,31 @@ class GCOVBlock {
};
public:
- using EdgeIterator = SmallVectorImpl<GCOVEdge *>::const_iterator;
+ using EdgeIterator = SmallVectorImpl<GCOVArc *>::const_iterator;
using BlockVector = SmallVector<const GCOVBlock *, 4>;
using BlockVectorLists = SmallVector<BlockVector, 4>;
- using Edges = SmallVector<GCOVEdge *, 4>;
+ using Edges = SmallVector<GCOVArc *, 4>;
GCOVBlock(GCOVFunction &P, uint32_t N) : Parent(P), Number(N) {}
- ~GCOVBlock();
const GCOVFunction &getParent() const { return Parent; }
void addLine(uint32_t N) { Lines.push_back(N); }
uint32_t getLastLine() const { return Lines.back(); }
- void addCount(size_t DstEdgeNo, uint64_t N);
uint64_t getCount() const { return Counter; }
- void addSrcEdge(GCOVEdge *Edge) {
- assert(&Edge->Dst == this); // up to caller to ensure edge is valid
- SrcEdges.push_back(Edge);
- }
+ void addSrcEdge(GCOVArc *Edge) { pred.push_back(Edge); }
- void addDstEdge(GCOVEdge *Edge) {
- assert(&Edge->Src == this); // up to caller to ensure edge is valid
- // Check if adding this edge causes list to become unsorted.
- if (DstEdges.size() && DstEdges.back()->Dst.Number > Edge->Dst.Number)
- DstEdgesAreSorted = false;
- DstEdges.push_back(Edge);
- }
+ void addDstEdge(GCOVArc *Edge) { succ.push_back(Edge); }
- size_t getNumSrcEdges() const { return SrcEdges.size(); }
- size_t getNumDstEdges() const { return DstEdges.size(); }
- void sortDstEdges();
+ size_t getNumSrcEdges() const { return pred.size(); }
+ size_t getNumDstEdges() const { return succ.size(); }
- EdgeIterator src_begin() const { return SrcEdges.begin(); }
- EdgeIterator src_end() const { return SrcEdges.end(); }
iterator_range<EdgeIterator> srcs() const {
- return make_range(src_begin(), src_end());
+ return make_range(pred.begin(), pred.end());
}
- EdgeIterator dst_begin() const { return DstEdges.begin(); }
- EdgeIterator dst_end() const { return DstEdges.end(); }
iterator_range<EdgeIterator> dsts() const {
- return make_range(dst_begin(), dst_end());
+ return make_range(succ.begin(), succ.end());
}
void print(raw_ostream &OS) const;
@@ -376,16 +312,37 @@ public:
static void getCyclesCount(const BlockVector &Blocks, uint64_t &Count);
static uint64_t getLineCount(const BlockVector &Blocks);
-private:
+public:
GCOVFunction &Parent;
uint32_t Number;
uint64_t Counter = 0;
- bool DstEdgesAreSorted = true;
- SmallVector<GCOVEdge *, 16> SrcEdges;
- SmallVector<GCOVEdge *, 16> DstEdges;
+ SmallVector<GCOVArc *, 2> pred;
+ SmallVector<GCOVArc *, 2> succ;
SmallVector<uint32_t, 16> Lines;
};
+struct GCOVCoverage {
+ GCOVCoverage() = default;
+ GCOVCoverage(StringRef Name) : Name(Name) {}
+
+ StringRef Name;
+
+ uint32_t LogicalLines = 0;
+ uint32_t LinesExec = 0;
+
+ uint32_t Branches = 0;
+ uint32_t BranchesExec = 0;
+ uint32_t BranchesTaken = 0;
+};
+
+struct SourceInfo {
+ StringRef filename;
+ std::string name;
+ std::vector<GCOVFunction *> functions;
+ GCOVCoverage coverage;
+ SourceInfo(StringRef filename) : filename(filename) {}
+};
+
class FileInfo {
protected:
// It is unlikely--but possible--for multiple functions to be on the same
@@ -406,20 +363,8 @@ protected:
uint32_t LastLine = 0;
};
- struct GCOVCoverage {
- GCOVCoverage(StringRef Name) : Name(Name) {}
-
- StringRef Name;
-
- uint32_t LogicalLines = 0;
- uint32_t LinesExec = 0;
-
- uint32_t Branches = 0;
- uint32_t BranchesExec = 0;
- uint32_t BranchesTaken = 0;
- };
-
public:
+ friend class GCOVFile;
FileInfo(const GCOV::Options &Options) : Options(Options) {}
void addBlockLine(StringRef Filename, uint32_t Line, const GCOVBlock *Block) {
@@ -438,7 +383,7 @@ public:
void setRunCount(uint32_t Runs) { RunCount = Runs; }
void setProgramCount(uint32_t Programs) { ProgramCount = Programs; }
void print(raw_ostream &OS, StringRef MainFilename, StringRef GCNOFile,
- StringRef GCDAFile);
+ StringRef GCDAFile, GCOVFile &file);
protected:
std::string getCoveragePath(StringRef Filename, StringRef MainFilename);
@@ -460,11 +405,10 @@ protected:
uint32_t RunCount = 0;
uint32_t ProgramCount = 0;
- using FileCoverageList = SmallVector<std::pair<std::string, GCOVCoverage>, 4>;
using FuncCoverageMap = MapVector<const GCOVFunction *, GCOVCoverage>;
- FileCoverageList FileCoverages;
FuncCoverageMap FuncCoverages;
+ std::vector<SourceInfo> sources;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProf.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProf.h
index 1f8872947c64..62a0c6955708 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProf.h
@@ -23,6 +23,7 @@
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/ProfileData/InstrProfData.inc"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
@@ -153,6 +154,10 @@ inline StringRef getInstrProfRuntimeHookVarUseFuncName() {
return "__llvm_profile_runtime_user";
}
+inline StringRef getInstrProfCounterBiasVarName() {
+ return "__llvm_profile_counter_bias";
+}
+
/// Return the marker used to separate PGO names during serialization.
inline StringRef getInstrProfNameSeparator() { return "\01"; }
@@ -558,7 +563,7 @@ StringRef InstrProfSymtab::getFuncName(uint64_t FuncMD5Hash) {
finalizeSymtab();
auto Result =
std::lower_bound(MD5NameMap.begin(), MD5NameMap.end(), FuncMD5Hash,
- [](const std::pair<uint64_t, std::string> &LHS,
+ [](const std::pair<uint64_t, StringRef> &LHS,
uint64_t RHS) { return LHS.first < RHS; });
if (Result != MD5NameMap.end() && Result->first == FuncMD5Hash)
return Result->second;
@@ -974,6 +979,9 @@ enum ProfVersion {
Version4 = 4,
// In this version, the frontend PGO stable hash algorithm defaults to V2.
Version5 = 5,
+ // In this version, the frontend PGO stable hash algorithm got fixed and
+ // may produce hashes different from Version5.
+ Version6 = 6,
// The current version is 5.
CurrentVersion = INSTR_PROF_INDEX_VERSION
};
@@ -1135,5 +1143,9 @@ void createIRLevelProfileFlagVar(Module &M, bool IsCS);
// Create the variable for the profile file name.
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput);
+// Whether to compress function names in profile records, and filenames in
+// code coverage mappings. Used by the Instrumentation library and unit tests.
+extern cl::opt<bool> DoInstrProfNameCompression;
+
} // end namespace llvm
#endif // LLVM_PROFILEDATA_INSTRPROF_H
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc b/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc
index 99f41d8fef07..a6913527e67f 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/InstrProfData.inc
@@ -198,6 +198,14 @@ VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize, "last")
#undef VALUE_PROF_KIND
/* VALUE_PROF_KIND end */
+#undef COVMAP_V2_OR_V3
+#ifdef COVMAP_V2
+#define COVMAP_V2_OR_V3
+#endif
+#ifdef COVMAP_V3
+#define COVMAP_V2_OR_V3
+#endif
+
/* COVMAP_FUNC_RECORD start */
/* Definition of member fields of the function record structure in coverage
* map.
@@ -214,16 +222,30 @@ COVMAP_FUNC_RECORD(const IntPtrT, llvm::Type::getInt8PtrTy(Ctx), \
COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), NameSize, \
llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), \
NameValue.size()))
-#else
+#endif
+#ifdef COVMAP_V2_OR_V3
COVMAP_FUNC_RECORD(const int64_t, llvm::Type::getInt64Ty(Ctx), NameRef, \
- llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), \
- llvm::IndexedInstrProf::ComputeHash(NameValue)))
+ llvm::ConstantInt::get( \
+ llvm::Type::getInt64Ty(Ctx), NameHash))
#endif
COVMAP_FUNC_RECORD(const uint32_t, llvm::Type::getInt32Ty(Ctx), DataSize, \
- llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx),\
- CoverageMapping.size()))
+ llvm::ConstantInt::get( \
+ llvm::Type::getInt32Ty(Ctx), CoverageMapping.size()))
COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \
- llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), FuncHash))
+ llvm::ConstantInt::get( \
+ llvm::Type::getInt64Ty(Ctx), FuncHash))
+#ifdef COVMAP_V3
+COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FilenamesRef, \
+ llvm::ConstantInt::get( \
+ llvm::Type::getInt64Ty(Ctx), FilenamesRef))
+COVMAP_FUNC_RECORD(const char, \
+ llvm::ArrayType::get(llvm::Type::getInt8Ty(Ctx), \
+ CoverageMapping.size()), \
+ CoverageMapping,
+ llvm::ConstantDataArray::getRaw( \
+ CoverageMapping, CoverageMapping.size(), \
+ llvm::Type::getInt8Ty(Ctx)))
+#endif
#undef COVMAP_FUNC_RECORD
/* COVMAP_FUNC_RECORD end. */
@@ -236,7 +258,7 @@ COVMAP_FUNC_RECORD(const uint64_t, llvm::Type::getInt64Ty(Ctx), FuncHash, \
#define INSTR_PROF_DATA_DEFINED
#endif
COVMAP_HEADER(uint32_t, Int32Ty, NRecords, \
- llvm::ConstantInt::get(Int32Ty, FunctionRecords.size()))
+ llvm::ConstantInt::get(Int32Ty, NRecords))
COVMAP_HEADER(uint32_t, Int32Ty, FilenamesSize, \
llvm::ConstantInt::get(Int32Ty, FilenamesSize))
COVMAP_HEADER(uint32_t, Int32Ty, CoverageSize, \
@@ -267,6 +289,9 @@ INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \
INSTR_PROF_SECT_ENTRY(IPSK_covmap, \
INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \
INSTR_PROF_COVMAP_COFF, "__LLVM_COV,")
+INSTR_PROF_SECT_ENTRY(IPSK_covfun, \
+ INSTR_PROF_QUOTE(INSTR_PROF_COVFUN_COMMON), \
+ INSTR_PROF_COVFUN_COFF, "__LLVM_COV,")
INSTR_PROF_SECT_ENTRY(IPSK_orderfile, \
INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON), \
INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COFF), "__DATA,")
@@ -632,9 +657,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Raw profile format version (start from 1). */
#define INSTR_PROF_RAW_VERSION 5
/* Indexed profile format version (start from 1). */
-#define INSTR_PROF_INDEX_VERSION 5
-/* Coverage mapping format vresion (start from 0). */
-#define INSTR_PROF_COVMAP_VERSION 2
+#define INSTR_PROF_INDEX_VERSION 6
+/* Coverage mapping format version (start from 0). */
+#define INSTR_PROF_COVMAP_VERSION 3
/* Profile version is always of type uint64_t. Reserve the upper 8 bits in the
* version for other variants of profile. We set the lowest bit of the upper 8
@@ -661,6 +686,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
+#define INSTR_PROF_COVFUN_COMMON __llvm_covfun
#define INSTR_PROF_ORDERFILE_COMMON __llvm_orderfile
/* Windows section names. Because these section names contain dollar characters,
* they must be quoted.
@@ -671,6 +697,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_VALS_COFF ".lprfv$M"
#define INSTR_PROF_VNODES_COFF ".lprfnd$M"
#define INSTR_PROF_COVMAP_COFF ".lcovmap$M"
+#define INSTR_PROF_COVFUN_COFF ".lcovfun$M"
#define INSTR_PROF_ORDERFILE_COFF ".lorderfile$M"
#ifdef _WIN32
@@ -685,6 +712,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Value profile nodes section. */
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
+#define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_COVFUN_COFF
#define INSTR_PROF_ORDERFILE_SECT_NAME INSTR_PROF_ORDERFILE_COFF
#else
/* Runtime section names and name strings. */
@@ -698,6 +726,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
/* Value profile nodes section. */
#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON)
#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON)
+#define INSTR_PROF_COVFUN_SECT_NAME INSTR_PROF_QUOTE(INSTR_PROF_COVFUN_COMMON)
/* Order file instrumentation. */
#define INSTR_PROF_ORDERFILE_SECT_NAME \
INSTR_PROF_QUOTE(INSTR_PROF_ORDERFILE_COMMON)
@@ -752,3 +781,5 @@ typedef struct InstrProfValueData {
#else
#undef INSTR_PROF_DATA_DEFINED
#endif
+
+#undef COVMAP_V2_OR_V3
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/ProfileCommon.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/ProfileCommon.h
index f98a34387fdf..14c305b3d0c0 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/ProfileCommon.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/ProfileCommon.h
@@ -62,6 +62,10 @@ protected:
public:
/// A vector of useful cutoff values for detailed summary.
static const ArrayRef<uint32_t> DefaultCutoffs;
+
+ /// Find the summary entry for a desired percentile of counts.
+ static const ProfileSummaryEntry &
+ getEntryForPercentile(SummaryEntryVector &DS, uint64_t Percentile);
};
class InstrProfSummaryBuilder final : public ProfileSummaryBuilder {
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProf.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProf.h
index f8be89c569b7..562468333ef4 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProf.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProf.h
@@ -22,6 +22,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MathExtras.h"
@@ -100,14 +101,14 @@ static inline uint64_t SPMagic(SampleProfileFormat Format = SPF_Binary) {
uint64_t('2') << (64 - 56) | uint64_t(Format);
}
-// Get the proper representation of a string in the input Format.
-static inline StringRef getRepInFormat(StringRef Name,
- SampleProfileFormat Format,
+/// Get the proper representation of a string according to whether the
+/// current Format uses MD5 to represent the string.
+static inline StringRef getRepInFormat(StringRef Name, bool UseMD5,
std::string &GUIDBuf) {
if (Name.empty())
return Name;
GUIDBuf = std::to_string(Function::getGUID(Name));
- return (Format == SPF_Compact_Binary) ? StringRef(GUIDBuf) : Name;
+ return UseMD5 ? StringRef(GUIDBuf) : Name;
}
static inline uint64_t SPVersion() { return 103; }
@@ -153,18 +154,74 @@ struct SecHdrTableEntry {
uint64_t Size;
};
-enum SecFlags { SecFlagInValid = 0, SecFlagCompress = (1 << 0) };
+// Flags common for all sections are defined here. In SecHdrTableEntry::Flags,
+// common flags will be saved in the lower 32bits and section specific flags
+// will be saved in the higher 32 bits.
+enum class SecCommonFlags : uint32_t {
+ SecFlagInValid = 0,
+ SecFlagCompress = (1 << 0)
+};
+
+// Section specific flags are defined here.
+// !!!Note: Everytime a new enum class is created here, please add
+// a new check in verifySecFlag.
+enum class SecNameTableFlags : uint32_t {
+ SecFlagInValid = 0,
+ SecFlagMD5Name = (1 << 0)
+};
+enum class SecProfSummaryFlags : uint32_t {
+ SecFlagInValid = 0,
+ /// SecFlagPartial means the profile is for common/shared code.
+ /// The common profile is usually merged from profiles collected
+ /// from running other targets.
+ SecFlagPartial = (1 << 0)
+};
+
+// Verify section specific flag is used for the correct section.
+template <class SecFlagType>
+static inline void verifySecFlag(SecType Type, SecFlagType Flag) {
+ // No verification is needed for common flags.
+ if (std::is_same<SecCommonFlags, SecFlagType>())
+ return;
+
+ // Verification starts here for section specific flag.
+ bool IsFlagLegal = false;
+ switch (Type) {
+ case SecNameTable:
+ IsFlagLegal = std::is_same<SecNameTableFlags, SecFlagType>();
+ break;
+ case SecProfSummary:
+ IsFlagLegal = std::is_same<SecProfSummaryFlags, SecFlagType>();
+ break;
+ default:
+ break;
+ }
+ if (!IsFlagLegal)
+ llvm_unreachable("Misuse of a flag in an incompatible section");
+}
-static inline void addSecFlags(SecHdrTableEntry &Entry, uint64_t Flags) {
- Entry.Flags |= Flags;
+template <class SecFlagType>
+static inline void addSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag) {
+ verifySecFlag(Entry.Type, Flag);
+ auto FVal = static_cast<uint64_t>(Flag);
+ bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();
+ Entry.Flags |= IsCommon ? FVal : (FVal << 32);
}
-static inline void removeSecFlags(SecHdrTableEntry &Entry, uint64_t Flags) {
- Entry.Flags &= ~Flags;
+template <class SecFlagType>
+static inline void removeSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag) {
+ verifySecFlag(Entry.Type, Flag);
+ auto FVal = static_cast<uint64_t>(Flag);
+ bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();
+ Entry.Flags &= ~(IsCommon ? FVal : (FVal << 32));
}
-static inline bool hasSecFlag(SecHdrTableEntry &Entry, SecFlags Flag) {
- return Entry.Flags & Flag;
+template <class SecFlagType>
+static inline bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag) {
+ verifySecFlag(Entry.Type, Flag);
+ auto FVal = static_cast<uint64_t>(Flag);
+ bool IsCommon = std::is_same<SecCommonFlags, SecFlagType>();
+ return Entry.Flags & (IsCommon ? FVal : (FVal << 32));
}
/// Represents the relative location of an instruction.
@@ -378,7 +435,7 @@ public:
const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc,
StringRef CalleeName) const {
std::string CalleeGUID;
- CalleeName = getRepInFormat(CalleeName, Format, CalleeGUID);
+ CalleeName = getRepInFormat(CalleeName, UseMD5, CalleeGUID);
auto iter = CallsiteSamples.find(Loc);
if (iter == CallsiteSamples.end())
@@ -387,9 +444,9 @@ public:
if (FS != iter->second.end())
return &FS->second;
// If we cannot find exact match of the callee name, return the FS with
- // the max total count. Only do this when CalleeName is not provided,
+ // the max total count. Only do this when CalleeName is not provided,
// i.e., only for indirect calls.
- if (!CalleeName.empty())
+ if (!CalleeName.empty())
return nullptr;
uint64_t MaxTotalSamples = 0;
const FunctionSamples *R = nullptr;
@@ -416,21 +473,21 @@ public:
/// Return the sample count of the first instruction of the function.
/// The function can be either a standalone symbol or an inlined function.
uint64_t getEntrySamples() const {
+ uint64_t Count = 0;
// Use either BodySamples or CallsiteSamples which ever has the smaller
// lineno.
if (!BodySamples.empty() &&
(CallsiteSamples.empty() ||
BodySamples.begin()->first < CallsiteSamples.begin()->first))
- return BodySamples.begin()->second.getSamples();
- if (!CallsiteSamples.empty()) {
- uint64_t T = 0;
+ Count = BodySamples.begin()->second.getSamples();
+ else if (!CallsiteSamples.empty()) {
// An indirect callsite may be promoted to several inlined direct calls.
// We need to get the sum of them.
for (const auto &N_FS : CallsiteSamples.begin()->second)
- T += N_FS.second.getEntrySamples();
- return T;
+ Count += N_FS.second.getEntrySamples();
}
- return 0;
+ // Return at least 1 if total sample is not 0.
+ return Count ? Count : TotalSamples > 0;
}
/// Return all the samples collected in the body of the function.
@@ -441,6 +498,18 @@ public:
return CallsiteSamples;
}
+ /// Return the maximum of sample counts in a function body including functions
+ /// inlined in it.
+ uint64_t getMaxCountInside() const {
+ uint64_t MaxCount = 0;
+ for (const auto &L : getBodySamples())
+ MaxCount = std::max(MaxCount, L.second.getSamples());
+ for (const auto &C : getCallsiteSamples())
+ for (const FunctionSamplesMap::value_type &F : C.second)
+ MaxCount = std::max(MaxCount, F.second.getMaxCountInside());
+ return MaxCount;
+ }
+
/// Merge the samples in \p Other into this one.
/// Optionally scale samples by \p Weight.
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight = 1) {
@@ -470,15 +539,20 @@ public:
uint64_t Threshold) const {
if (TotalSamples <= Threshold)
return;
- S.insert(getGUID(Name));
+ auto isDeclaration = [](const Function *F) {
+ return !F || F->isDeclaration();
+ };
+ if (isDeclaration(M->getFunction(getFuncName()))) {
+ // Add to the import list only when it's defined out of module.
+ S.insert(getGUID(Name));
+ }
// Import hot CallTargets, which may not be available in IR because full
// profile annotation cannot be done until backend compilation in ThinLTO.
for (const auto &BS : BodySamples)
for (const auto &TS : BS.second.getCallTargets())
if (TS.getValue() > Threshold) {
- const Function *Callee =
- M->getFunction(getNameInModule(TS.getKey(), M));
- if (!Callee || !Callee->getSubprogram())
+ const Function *Callee = M->getFunction(getFuncName(TS.getKey()));
+ if (isDeclaration(Callee))
S.insert(getGUID(TS.getKey()));
}
for (const auto &CS : CallsiteSamples)
@@ -492,10 +566,8 @@ public:
/// Return the function name.
StringRef getName() const { return Name; }
- /// Return the original function name if it exists in Module \p M.
- StringRef getFuncNameInModule(const Module *M) const {
- return getNameInModule(Name, M);
- }
+ /// Return the original function name.
+ StringRef getFuncName() const { return getFuncName(Name); }
/// Return the canonical name for a function, taking into account
/// suffix elision policy attributes.
@@ -525,14 +597,15 @@ public:
return F.getName();
}
- /// Translate \p Name into its original name in Module.
- /// When the Format is not SPF_Compact_Binary, \p Name needs no translation.
- /// When the Format is SPF_Compact_Binary, \p Name in current FunctionSamples
- /// is actually GUID of the original function name. getNameInModule will
- /// translate \p Name in current FunctionSamples into its original name.
- /// If the original name doesn't exist in \p M, return empty StringRef.
- StringRef getNameInModule(StringRef Name, const Module *M) const {
- if (Format != SPF_Compact_Binary)
+ /// Translate \p Name into its original name.
+ /// When profile doesn't use MD5, \p Name needs no translation.
+ /// When profile uses MD5, \p Name in current FunctionSamples
+ /// is actually GUID of the original function name. getFuncName will
+ /// translate \p Name in current FunctionSamples into its original name
+ /// by looking up in the function map GUIDToFuncNameMap.
+ /// If the original name doesn't exist in the map, return empty StringRef.
+ StringRef getFuncName(StringRef Name) const {
+ if (!UseMD5)
return Name;
assert(GUIDToFuncNameMap && "GUIDToFuncNameMap needs to be popluated first");
@@ -559,16 +632,18 @@ public:
static SampleProfileFormat Format;
+ /// Whether the profile uses MD5 to represent string.
+ static bool UseMD5;
+
/// GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
/// all the function symbols defined or declared in current module.
DenseMap<uint64_t, StringRef> *GUIDToFuncNameMap = nullptr;
// Assume the input \p Name is a name coming from FunctionSamples itself.
- // If the format is SPF_Compact_Binary, the name is already a GUID and we
+ // If UseMD5 is true, the name is already a GUID and we
// don't want to return the GUID of GUID.
static uint64_t getGUID(StringRef Name) {
- return (Format == SPF_Compact_Binary) ? std::stoull(Name.data())
- : Function::getGUID(Name);
+ return UseMD5 ? std::stoull(Name.data()) : Function::getGUID(Name);
}
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfReader.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfReader.h
index 72b178edc260..0e8ee7696c54 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfReader.h
@@ -335,6 +335,7 @@ public:
return EC;
if (Remapper)
Remapper->applyRemapping(Ctx);
+ FunctionSamples::UseMD5 = useMD5();
return sampleprof_error::success;
}
@@ -363,7 +364,7 @@ public:
FunctionSamples *getOrCreateSamplesFor(const Function &F) {
std::string FGUID;
StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
- CanonName = getRepInFormat(CanonName, getFormat(), FGUID);
+ CanonName = getRepInFormat(CanonName, useMD5(), FGUID);
return &Profiles[CanonName];
}
@@ -374,7 +375,7 @@ public:
return FS;
}
std::string FGUID;
- Fname = getRepInFormat(Fname, getFormat(), FGUID);
+ Fname = getRepInFormat(Fname, useMD5(), FGUID);
auto It = Profiles.find(Fname);
if (It != Profiles.end())
return &It->second;
@@ -419,6 +420,9 @@ public:
virtual std::vector<StringRef> *getNameTable() { return nullptr; }
virtual bool dumpSectionInfo(raw_ostream &OS = dbgs()) { return false; };
+ /// Return whether names in the profile are all MD5 numbers.
+ virtual bool useMD5() { return false; }
+
protected:
/// Map every function to its associated profile.
///
@@ -590,7 +594,7 @@ protected:
virtual std::error_code readHeader() override;
virtual std::error_code verifySPMagic(uint64_t Magic) override = 0;
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size,
- SecType Type) = 0;
+ const SecHdrTableEntry &Entry) = 0;
public:
SampleProfileReaderExtBinaryBase(std::unique_ptr<MemoryBuffer> B,
@@ -610,11 +614,14 @@ public:
class SampleProfileReaderExtBinary : public SampleProfileReaderExtBinaryBase {
private:
virtual std::error_code verifySPMagic(uint64_t Magic) override;
- virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size,
- SecType Type) override;
+ virtual std::error_code
+ readOneSection(const uint8_t *Start, uint64_t Size,
+ const SecHdrTableEntry &Entry) override;
std::error_code readProfileSymbolList();
std::error_code readFuncOffsetTable();
std::error_code readFuncProfiles();
+ std::error_code readMD5NameTable();
+ std::error_code readNameTableSec(bool IsMD5);
/// The table mapping from function name to the offset of its FunctionSample
/// towards file start.
@@ -624,6 +631,15 @@ private:
/// Use all functions from the input profile.
bool UseAllFuncs = true;
+ /// If MD5 is used in NameTable section, the section saves uint64_t data.
+ /// The uint64_t data has to be converted to a string and then the string
+ /// will be used to initialize StringRef in NameTable.
+ /// Note NameTable contains StringRef so it needs another buffer to own
+ /// the string data. MD5StringBuf serves as the string buffer that is
+ /// referenced by NameTable (vector of StringRef). We make sure
+ /// the lifetime of MD5StringBuf is not shorter than that of NameTable.
+ std::unique_ptr<std::vector<std::string>> MD5StringBuf;
+
public:
SampleProfileReaderExtBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C,
SampleProfileFormat Format = SPF_Ext_Binary)
@@ -638,6 +654,12 @@ public:
/// Collect functions with definitions in Module \p M.
void collectFuncsFrom(const Module &M) override;
+
+ /// Return whether names in the profile are all MD5 numbers.
+ virtual bool useMD5() override {
+ assert(!NameTable.empty() && "NameTable should have been initialized");
+ return MD5StringBuf && !MD5StringBuf->empty();
+ }
};
class SampleProfileReaderCompactBinary : public SampleProfileReaderBinary {
@@ -671,6 +693,9 @@ public:
/// Collect functions to be used when compiling Module \p M.
void collectFuncsFrom(const Module &M) override;
+
+ /// Return whether names in the profile are all MD5 numbers.
+ virtual bool useMD5() override { return true; }
};
using InlineCallStack = SmallVector<FunctionSamples *, 10>;
diff --git a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfWriter.h b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfWriter.h
index 5814f69fdcab..7d0df9e44f58 100644
--- a/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/ProfileData/SampleProfWriter.h
@@ -57,6 +57,9 @@ public:
create(std::unique_ptr<raw_ostream> &OS, SampleProfileFormat Format);
virtual void setProfileSymbolList(ProfileSymbolList *PSL) {}
+ virtual void setToCompressAllSections() {}
+ virtual void setUseMD5() {}
+ virtual void setPartialProfile() {}
protected:
SampleProfileWriter(std::unique_ptr<raw_ostream> &OS)
@@ -147,12 +150,20 @@ public:
virtual std::error_code
write(const StringMap<FunctionSamples> &ProfileMap) override;
- void setToCompressAllSections();
+ virtual void setToCompressAllSections() override;
void setToCompressSection(SecType Type);
protected:
uint64_t markSectionStart(SecType Type);
std::error_code addNewSection(SecType Sec, uint64_t SectionStart);
+ template <class SecFlagType>
+ void addSectionFlag(SecType Type, SecFlagType Flag) {
+ for (auto &Entry : SectionHdrLayout) {
+ if (Entry.Type == Type)
+ addSecFlag(Entry, Flag);
+ }
+ }
+
virtual void initSectionHdrLayout() = 0;
virtual std::error_code
writeSections(const StringMap<FunctionSamples> &ProfileMap) = 0;
@@ -168,7 +179,6 @@ private:
std::error_code writeSecHdrTable();
virtual std::error_code
writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;
- void addSectionFlags(SecType Type, SecFlags Flags);
SecHdrTableEntry &getEntryInLayout(SecType Type);
std::error_code compressAndOutput();
@@ -202,6 +212,19 @@ public:
ProfSymList = PSL;
};
+ // Set to use MD5 to represent string in NameTable.
+ virtual void setUseMD5() override {
+ UseMD5 = true;
+ addSectionFlag(SecNameTable, SecNameTableFlags::SecFlagMD5Name);
+ }
+
+ // Set the profile to be partial. It means the profile is for
+ // common/shared code. The common profile is usually merged from
+ // profiles collected from running other targets.
+ virtual void setPartialProfile() override {
+ addSectionFlag(SecProfSummary, SecProfSummaryFlags::SecFlagPartial);
+ }
+
private:
virtual void initSectionHdrLayout() override {
// Note that SecFuncOffsetTable section is written after SecLBRProfile
@@ -222,6 +245,10 @@ private:
};
virtual std::error_code
writeSections(const StringMap<FunctionSamples> &ProfileMap) override;
+
+ std::error_code writeFuncOffsetTable();
+ virtual std::error_code writeNameTable() override;
+
ProfileSymbolList *ProfSymList = nullptr;
// Save the start of SecLBRProfile so we can compute the offset to the
@@ -231,7 +258,8 @@ private:
// FuncOffsetTable maps function name to its profile offset in SecLBRProfile
// section. It is used to load function profile on demand.
MapVector<StringRef, uint64_t> FuncOffsetTable;
- std::error_code writeFuncOffsetTable();
+ // Whether to use MD5 to represent string.
+ bool UseMD5 = false;
};
// CompactBinary is a compact format of binary profile which both reduces
diff --git a/contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h b/contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h
index 6211db4a8e96..160e8dc8db70 100644
--- a/contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h
+++ b/contrib/llvm-project/llvm/include/llvm/Remarks/Remark.h
@@ -14,8 +14,8 @@
#define LLVM_REMARKS_REMARK_H
#include "llvm-c/Remarks.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CBindingWrapping.h"
#include <string>
diff --git a/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkLinker.h b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkLinker.h
index c82c73d8c94f..7a53c30924b8 100644
--- a/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkLinker.h
+++ b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkLinker.h
@@ -80,8 +80,7 @@ public:
/// Return a collection of the linked unique remarks to iterate on.
/// Ex:
/// for (const Remark &R : RL.remarks() { [...] }
- using iterator =
- pointee_iterator<std::set<std::unique_ptr<Remark>>::iterator>;
+ using iterator = pointee_iterator<decltype(Remarks)::const_iterator>;
iterator_range<iterator> remarks() const {
return {Remarks.begin(), Remarks.end()};
diff --git a/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStreamer.h b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStreamer.h
new file mode 100644
index 000000000000..7741cb45b72c
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStreamer.h
@@ -0,0 +1,73 @@
+//===- llvm/Remarks/RemarkStreamer.h ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the main interface for streaming remarks.
+//
+// This is used to stream any llvm::remarks::Remark to an open file taking
+// advantage of all the serialization capabilities developed for remarks (e.g.
+// metadata in a section, bitstream format, etc.).
+//
+// Typically, a specialized remark emitter should hold a reference to the main
+// remark streamer set up in the LLVMContext, and should convert specialized
+// diagnostics to llvm::remarks::Remark objects as they get emitted.
+//
+// Specialized remark emitters can be components like:
+// * Remarks from LLVM (M)IR passes
+// * Remarks from the frontend
+// * Remarks from an intermediate IR
+//
+// This allows for composition between specialized remark emitters throughout
+// the compilation pipeline, that end up in the same file, using the same format
+// and serialization techniques.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_REMARKS_REMARKSTREAMER_H
+#define LLVM_REMARKS_REMARKSTREAMER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Remarks/RemarkSerializer.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+namespace llvm {
+namespace remarks {
+class RemarkStreamer final {
+ /// The regex used to filter remarks based on the passes that emit them.
+ Optional<Regex> PassFilter;
+ /// The object used to serialize the remarks to a specific format.
+ std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer;
+ /// The filename that the remark diagnostics are emitted to.
+ const Optional<std::string> Filename;
+
+public:
+ RemarkStreamer(std::unique_ptr<remarks::RemarkSerializer> RemarkSerializer,
+ Optional<StringRef> Filename = None);
+
+ /// Return the filename that the remark diagnostics are emitted to.
+ Optional<StringRef> getFilename() const {
+ return Filename ? Optional<StringRef>(*Filename) : None;
+ }
+ /// Return stream that the remark diagnostics are emitted to.
+ raw_ostream &getStream() { return RemarkSerializer->OS; }
+ /// Return the serializer used for this stream.
+ remarks::RemarkSerializer &getSerializer() { return *RemarkSerializer; }
+ /// Set a pass filter based on a regex \p Filter.
+ /// Returns an error if the regex is invalid.
+ Error setFilter(StringRef Filter);
+ /// Check wether the string matches the filter.
+ bool matchesFilter(StringRef Str);
+ /// Check if the remarks also need to have associated metadata in a section.
+ bool needsSection() const;
+};
+} // end namespace remarks
+} // end namespace llvm
+
+#endif // LLVM_REMARKS_REMARKSTREAMER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStringTable.h b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStringTable.h
index 4ce27ee884c8..60cf601e05aa 100644
--- a/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStringTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/Remarks/RemarkStringTable.h
@@ -17,17 +17,18 @@
#define LLVM_REMARKS_REMARK_STRING_TABLE_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Remarks/Remark.h"
+#include "llvm/Support/Allocator.h"
#include <vector>
namespace llvm {
class raw_ostream;
+class StringRef;
namespace remarks {
struct ParsedStringTable;
+struct Remark;
/// The string table used for serializing remarks.
/// This table can be for example serialized in a section to be consumed after
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.def b/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.def
index 050059e36a25..13b7cfc4b5cd 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.def
+++ b/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.def
@@ -44,6 +44,13 @@ AARCH64_ARCH("armv8.5-a", ARMV8_5A, "8.5-A", "v8.5a",
(AArch64::AEK_CRC | AArch64::AEK_CRYPTO | AArch64::AEK_FP |
AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD))
+AARCH64_ARCH("armv8.6-a", ARMV8_6A, "8.6-A", "v8.6a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (AArch64::AEK_CRC | AArch64::AEK_FP |
+ AArch64::AEK_SIMD | AArch64::AEK_RAS | AArch64::AEK_LSE |
+ AArch64::AEK_RDM | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+ AArch64::AEK_SM4 | AArch64::AEK_SHA3 | AArch64::AEK_BF16 |
+ AArch64::AEK_SHA2 | AArch64::AEK_AES | AArch64::AEK_I8MM))
#undef AARCH64_ARCH
#ifndef AARCH64_ARCH_EXT_NAME
@@ -79,12 +86,18 @@ AARCH64_ARCH_EXT_NAME("memtag", AArch64::AEK_MTE, "+mte", "-mte"
AARCH64_ARCH_EXT_NAME("ssbs", AArch64::AEK_SSBS, "+ssbs", "-ssbs")
AARCH64_ARCH_EXT_NAME("sb", AArch64::AEK_SB, "+sb", "-sb")
AARCH64_ARCH_EXT_NAME("predres", AArch64::AEK_PREDRES, "+predres", "-predres")
+AARCH64_ARCH_EXT_NAME("bf16", AArch64::AEK_BF16, "+bf16", "-bf16")
+AARCH64_ARCH_EXT_NAME("i8mm", AArch64::AEK_I8MM, "+i8mm", "-i8mm")
+AARCH64_ARCH_EXT_NAME("f32mm", AArch64::AEK_F32MM, "+f32mm", "-f32mm")
+AARCH64_ARCH_EXT_NAME("f64mm", AArch64::AEK_F64MM, "+f64mm", "-f64mm")
AARCH64_ARCH_EXT_NAME("tme", AArch64::AEK_TME, "+tme", "-tme")
#undef AARCH64_ARCH_EXT_NAME
#ifndef AARCH64_CPU_NAME
#define AARCH64_CPU_NAME(NAME, ID, DEFAULT_FPU, IS_DEFAULT, DEFAULT_EXT)
#endif
+AARCH64_CPU_NAME("cortex-a34", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a35", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_CRC))
AARCH64_CPU_NAME("cortex-a53", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, true,
@@ -111,6 +124,15 @@ AARCH64_CPU_NAME("cortex-a76", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
AARCH64_CPU_NAME("cortex-a76ae", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
AArch64::AEK_SSBS))
+AARCH64_CPU_NAME("cortex-a77", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_RCPC | AArch64::AEK_DOTPROD |
+ AArch64::AEK_SSBS))
+AARCH64_CPU_NAME("cortex-a78", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
+ AArch64::AEK_SSBS))
+AARCH64_CPU_NAME("cortex-x1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_DOTPROD | AArch64::AEK_RCPC |
+ AArch64::AEK_SSBS))
AARCH64_CPU_NAME("neoverse-e1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_DOTPROD | AArch64::AEK_FP16 | AArch64::AEK_RAS |
AArch64::AEK_RCPC | AArch64::AEK_SSBS))
@@ -168,6 +190,10 @@ AARCH64_CPU_NAME("tsv110", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(AArch64::AEK_DOTPROD |
AArch64::AEK_FP16 | AArch64::AEK_FP16FML |
AArch64::AEK_PROFILE))
+AARCH64_CPU_NAME("a64fx", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (AArch64::AEK_FP16 | AArch64::AEK_SVE))
+AARCH64_CPU_NAME("carmel", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ AArch64::AEK_FP16)
// Invalid CPU
AARCH64_CPU_NAME("invalid", INVALID, FK_INVALID, true, AArch64::AEK_INVALID)
#undef AARCH64_CPU_NAME
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.h b/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.h
index fbe08945a038..b045e31bc92a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/AArch64TargetParser.h
@@ -14,17 +14,20 @@
#ifndef LLVM_SUPPORT_AARCH64TARGETPARSERCOMMON_H
#define LLVM_SUPPORT_AARCH64TARGETPARSERCOMMON_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ARMTargetParser.h"
#include <vector>
// FIXME:This should be made into class design,to avoid dupplication.
namespace llvm {
+
+class Triple;
+
namespace AArch64 {
// Arch extension modifiers for CPUs.
-enum ArchExtKind : unsigned {
+enum ArchExtKind : uint64_t {
AEK_INVALID = 0,
AEK_NONE = 1,
AEK_CRC = 1 << 1,
@@ -55,6 +58,10 @@ enum ArchExtKind : unsigned {
AEK_SVE2SHA3 = 1 << 26,
AEK_SVE2BITPERM = 1 << 27,
AEK_TME = 1 << 28,
+ AEK_BF16 = 1 << 29,
+ AEK_I8MM = 1 << 30,
+ AEK_F32MM = 1ULL << 31,
+ AEK_F64MM = 1ULL << 32,
};
enum class ArchKind {
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/AMDGPUMetadata.h b/contrib/llvm-project/llvm/include/llvm/Support/AMDGPUMetadata.h
index eeef4e699c3e..920c97f7e112 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/AMDGPUMetadata.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/AMDGPUMetadata.h
@@ -79,7 +79,8 @@ enum class ValueKind : uint8_t {
Unknown = 0xff
};
-/// Value types.
+/// Value types. This is deprecated and only remains for compatibility parsing
+/// of old metadata.
enum class ValueType : uint8_t {
Struct = 0,
I8 = 1,
@@ -164,7 +165,7 @@ constexpr char Offset[] = "Offset";
constexpr char Align[] = "Align";
/// Key for Kernel::Arg::Metadata::mValueKind.
constexpr char ValueKind[] = "ValueKind";
-/// Key for Kernel::Arg::Metadata::mValueType.
+/// Key for Kernel::Arg::Metadata::mValueType. (deprecated)
constexpr char ValueType[] = "ValueType";
/// Key for Kernel::Arg::Metadata::mPointeeAlign.
constexpr char PointeeAlign[] = "PointeeAlign";
@@ -198,8 +199,6 @@ struct Metadata final {
uint32_t mAlign = 0;
/// Value kind. Required.
ValueKind mValueKind = ValueKind::Unknown;
- /// Value type. Required.
- ValueType mValueType = ValueType::Unknown;
/// Pointee alignment in bytes. Optional.
uint32_t mPointeeAlign = 0;
/// Address space qualifier. Optional.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ARMAttributeParser.h b/contrib/llvm-project/llvm/include/llvm/Support/ARMAttributeParser.h
index f6c39abb4f21..bf85ea14cfe3 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ARMAttributeParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ARMAttributeParser.h
@@ -1,4 +1,4 @@
-//===--- ARMAttributeParser.h - ARM Attribute Information Printer ---------===//
+//===- ARMAttributeParser.h - ARM Attribute Information Printer -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,132 +10,71 @@
#define LLVM_SUPPORT_ARMATTRIBUTEPARSER_H
#include "ARMBuildAttributes.h"
+#include "ELFAttributeParser.h"
#include "ScopedPrinter.h"
-
-#include <map>
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
namespace llvm {
class StringRef;
-class ARMAttributeParser {
- ScopedPrinter *SW;
-
- std::map<unsigned, unsigned> Attributes;
-
+class ARMAttributeParser : public ELFAttributeParser {
struct DisplayHandler {
- ARMBuildAttrs::AttrType Attribute;
- void (ARMAttributeParser::*Routine)(ARMBuildAttrs::AttrType,
- const uint8_t *, uint32_t &);
+ ARMBuildAttrs::AttrType attribute;
+ Error (ARMAttributeParser::*routine)(ARMBuildAttrs::AttrType);
};
- static const DisplayHandler DisplayRoutines[];
-
- uint64_t ParseInteger(const uint8_t *Data, uint32_t &Offset);
- StringRef ParseString(const uint8_t *Data, uint32_t &Offset);
-
- void IntegerAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void StringAttribute(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
-
- void PrintAttribute(unsigned Tag, unsigned Value, StringRef ValueDesc);
-
- void CPU_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void CPU_arch_profile(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ARM_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void THUMB_ISA_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void FP_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void WMMX_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void Advanced_SIMD_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void MVE_arch(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void PCS_config(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_R9_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_RW_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_RO_data(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_GOT_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_PCS_wchar_t(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_rounding(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_denormal(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_user_exceptions(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_number_model(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_align_needed(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_align_preserved(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_enum_size(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_HardFP_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_VFP_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_WMMX_args(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_optimization_goals(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_optimization_goals(ARMBuildAttrs::AttrType Tag,
- const uint8_t *Data, uint32_t &Offset);
- void compatibility(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void CPU_unaligned_access(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void FP_HP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void ABI_FP_16bit_format(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void MPextension_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void DIV_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void DSP_extension(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void T2EE_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void Virtualization_use(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
- void nodefaults(ARMBuildAttrs::AttrType Tag, const uint8_t *Data,
- uint32_t &Offset);
+ static const DisplayHandler displayRoutines[];
+
+ Error handler(uint64_t tag, bool &handled) override;
+
+ Error stringAttribute(ARMBuildAttrs::AttrType tag);
+
+ Error CPU_arch(ARMBuildAttrs::AttrType tag);
+ Error CPU_arch_profile(ARMBuildAttrs::AttrType tag);
+ Error ARM_ISA_use(ARMBuildAttrs::AttrType tag);
+ Error THUMB_ISA_use(ARMBuildAttrs::AttrType tag);
+ Error FP_arch(ARMBuildAttrs::AttrType tag);
+ Error WMMX_arch(ARMBuildAttrs::AttrType tag);
+ Error Advanced_SIMD_arch(ARMBuildAttrs::AttrType tag);
+ Error MVE_arch(ARMBuildAttrs::AttrType tag);
+ Error PCS_config(ARMBuildAttrs::AttrType tag);
+ Error ABI_PCS_R9_use(ARMBuildAttrs::AttrType tag);
+ Error ABI_PCS_RW_data(ARMBuildAttrs::AttrType tag);
+ Error ABI_PCS_RO_data(ARMBuildAttrs::AttrType tag);
+ Error ABI_PCS_GOT_use(ARMBuildAttrs::AttrType tag);
+ Error ABI_PCS_wchar_t(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_rounding(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_denormal(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_exceptions(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_user_exceptions(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_number_model(ARMBuildAttrs::AttrType tag);
+ Error ABI_align_needed(ARMBuildAttrs::AttrType tag);
+ Error ABI_align_preserved(ARMBuildAttrs::AttrType tag);
+ Error ABI_enum_size(ARMBuildAttrs::AttrType tag);
+ Error ABI_HardFP_use(ARMBuildAttrs::AttrType tag);
+ Error ABI_VFP_args(ARMBuildAttrs::AttrType tag);
+ Error ABI_WMMX_args(ARMBuildAttrs::AttrType tag);
+ Error ABI_optimization_goals(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_optimization_goals(ARMBuildAttrs::AttrType tag);
+ Error compatibility(ARMBuildAttrs::AttrType tag);
+ Error CPU_unaligned_access(ARMBuildAttrs::AttrType tag);
+ Error FP_HP_extension(ARMBuildAttrs::AttrType tag);
+ Error ABI_FP_16bit_format(ARMBuildAttrs::AttrType tag);
+ Error MPextension_use(ARMBuildAttrs::AttrType tag);
+ Error DIV_use(ARMBuildAttrs::AttrType tag);
+ Error DSP_extension(ARMBuildAttrs::AttrType tag);
+ Error T2EE_use(ARMBuildAttrs::AttrType tag);
+ Error Virtualization_use(ARMBuildAttrs::AttrType tag);
+ Error nodefaults(ARMBuildAttrs::AttrType tag);
- void ParseAttributeList(const uint8_t *Data, uint32_t &Offset,
- uint32_t Length);
- void ParseIndexList(const uint8_t *Data, uint32_t &Offset,
- SmallVectorImpl<uint8_t> &IndexList);
- void ParseSubsection(const uint8_t *Data, uint32_t Length);
public:
- ARMAttributeParser(ScopedPrinter *SW) : SW(SW) {}
-
- ARMAttributeParser() : SW(nullptr) { }
-
- void Parse(ArrayRef<uint8_t> Section, bool isLittle);
-
- bool hasAttribute(unsigned Tag) const {
- return Attributes.count(Tag);
- }
-
- unsigned getAttributeValue(unsigned Tag) const {
- return Attributes.find(Tag)->second;
- }
+ ARMAttributeParser(ScopedPrinter *sw)
+ : ELFAttributeParser(sw, ARMBuildAttrs::ARMAttributeTags, "aeabi") {}
+ ARMAttributeParser()
+ : ELFAttributeParser(ARMBuildAttrs::ARMAttributeTags, "aeabi") {}
};
-
}
#endif
-
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ARMBuildAttributes.h b/contrib/llvm-project/llvm/include/llvm/Support/ARMBuildAttributes.h
index 90481eaa1677..5a06fd6ca7be 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ARMBuildAttributes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ARMBuildAttributes.h
@@ -18,77 +18,70 @@
#ifndef LLVM_SUPPORT_ARMBUILDATTRIBUTES_H
#define LLVM_SUPPORT_ARMBUILDATTRIBUTES_H
-namespace llvm {
-class StringRef;
+#include "llvm/Support/ELFAttributes.h"
+namespace llvm {
namespace ARMBuildAttrs {
+extern const TagNameMap ARMAttributeTags;
+
enum SpecialAttr {
// This is for the .cpu asm attr. It translates into one or more
// AttrType (below) entries in the .ARM.attributes section in the ELF.
SEL_CPU
};
-enum AttrType {
+enum AttrType : unsigned {
// Rest correspond to ELF/.ARM.attributes
- File = 1,
- CPU_raw_name = 4,
- CPU_name = 5,
- CPU_arch = 6,
- CPU_arch_profile = 7,
- ARM_ISA_use = 8,
- THUMB_ISA_use = 9,
- FP_arch = 10,
- WMMX_arch = 11,
- Advanced_SIMD_arch = 12,
- PCS_config = 13,
- ABI_PCS_R9_use = 14,
- ABI_PCS_RW_data = 15,
- ABI_PCS_RO_data = 16,
- ABI_PCS_GOT_use = 17,
- ABI_PCS_wchar_t = 18,
- ABI_FP_rounding = 19,
- ABI_FP_denormal = 20,
- ABI_FP_exceptions = 21,
- ABI_FP_user_exceptions = 22,
- ABI_FP_number_model = 23,
- ABI_align_needed = 24,
- ABI_align_preserved = 25,
- ABI_enum_size = 26,
- ABI_HardFP_use = 27,
- ABI_VFP_args = 28,
- ABI_WMMX_args = 29,
- ABI_optimization_goals = 30,
+ File = 1,
+ CPU_raw_name = 4,
+ CPU_name = 5,
+ CPU_arch = 6,
+ CPU_arch_profile = 7,
+ ARM_ISA_use = 8,
+ THUMB_ISA_use = 9,
+ FP_arch = 10,
+ WMMX_arch = 11,
+ Advanced_SIMD_arch = 12,
+ PCS_config = 13,
+ ABI_PCS_R9_use = 14,
+ ABI_PCS_RW_data = 15,
+ ABI_PCS_RO_data = 16,
+ ABI_PCS_GOT_use = 17,
+ ABI_PCS_wchar_t = 18,
+ ABI_FP_rounding = 19,
+ ABI_FP_denormal = 20,
+ ABI_FP_exceptions = 21,
+ ABI_FP_user_exceptions = 22,
+ ABI_FP_number_model = 23,
+ ABI_align_needed = 24,
+ ABI_align_preserved = 25,
+ ABI_enum_size = 26,
+ ABI_HardFP_use = 27,
+ ABI_VFP_args = 28,
+ ABI_WMMX_args = 29,
+ ABI_optimization_goals = 30,
ABI_FP_optimization_goals = 31,
- compatibility = 32,
- CPU_unaligned_access = 34,
- FP_HP_extension = 36,
- ABI_FP_16bit_format = 38,
- MPextension_use = 42, // recoded from 70 (ABI r2.08)
- DIV_use = 44,
- DSP_extension = 46,
- MVE_arch = 48,
- also_compatible_with = 65,
- conformance = 67,
- Virtualization_use = 68,
+ compatibility = 32,
+ CPU_unaligned_access = 34,
+ FP_HP_extension = 36,
+ ABI_FP_16bit_format = 38,
+ MPextension_use = 42, // recoded from 70 (ABI r2.08)
+ DIV_use = 44,
+ DSP_extension = 46,
+ MVE_arch = 48,
+ also_compatible_with = 65,
+ conformance = 67,
+ Virtualization_use = 68,
/// Legacy Tags
- Section = 2, // deprecated (ABI r2.09)
- Symbol = 3, // deprecated (ABI r2.09)
- ABI_align8_needed = 24, // renamed to ABI_align_needed (ABI r2.09)
- ABI_align8_preserved = 25, // renamed to ABI_align_preserved (ABI r2.09)
- nodefaults = 64, // deprecated (ABI r2.09)
- T2EE_use = 66, // deprecated (ABI r2.09)
- MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08)
-};
-
-StringRef AttrTypeAsString(unsigned Attr, bool HasTagPrefix = true);
-StringRef AttrTypeAsString(AttrType Attr, bool HasTagPrefix = true);
-int AttrTypeFromString(StringRef Tag);
-
-// Magic numbers for .ARM.attributes
-enum AttrMagic {
- Format_Version = 0x41
+ Section = 2, // deprecated (ABI r2.09)
+ Symbol = 3, // deprecated (ABI r2.09)
+ ABI_align8_needed = 24, // renamed to ABI_align_needed (ABI r2.09)
+ ABI_align8_preserved = 25, // renamed to ABI_align_preserved (ABI r2.09)
+ nodefaults = 64, // deprecated (ABI r2.09)
+ T2EE_use = 66, // deprecated (ABI r2.09)
+ MPextension_use_old = 70 // recoded to MPextension_use (ABI r2.08)
};
// Legal Values for CPU_arch, (=6), uleb128
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.def b/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.def
index 7f03d9a1320a..9f51c841e429 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.def
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.def
@@ -112,6 +112,12 @@ ARM_ARCH("armv8.5-a", ARMV8_5A, "8.5-A", "v8.5a",
(ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
ARM::AEK_DOTPROD))
+ARM_ARCH("armv8.6-a", ARMV8_6A, "8.6-A", "v8.6a",
+ ARMBuildAttrs::CPUArch::v8_A, FK_CRYPTO_NEON_FP_ARMV8,
+ (ARM::AEK_SEC | ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM |
+ ARM::AEK_HWDIVTHUMB | ARM::AEK_DSP | ARM::AEK_CRC | ARM::AEK_RAS |
+ ARM::AEK_DOTPROD | ARM::AEK_BF16 | ARM::AEK_SHA2 | ARM::AEK_AES |
+ ARM::AEK_I8MM))
ARM_ARCH("armv8-r", ARMV8R, "8-R", "v8r", ARMBuildAttrs::CPUArch::v8_R,
FK_NEON_FP_ARMV8,
(ARM::AEK_MP | ARM::AEK_VIRT | ARM::AEK_HWDIVARM | ARM::AEK_HWDIVTHUMB |
@@ -164,8 +170,18 @@ ARM_ARCH_EXT_NAME("iwmmxt2", ARM::AEK_IWMMXT2, nullptr, nullptr)
ARM_ARCH_EXT_NAME("maverick", ARM::AEK_MAVERICK, nullptr, nullptr)
ARM_ARCH_EXT_NAME("xscale", ARM::AEK_XSCALE, nullptr, nullptr)
ARM_ARCH_EXT_NAME("fp16fml", ARM::AEK_FP16FML, "+fp16fml", "-fp16fml")
+ARM_ARCH_EXT_NAME("bf16", ARM::AEK_BF16, "+bf16", "-bf16")
ARM_ARCH_EXT_NAME("sb", ARM::AEK_SB, "+sb", "-sb")
+ARM_ARCH_EXT_NAME("i8mm", ARM::AEK_I8MM, "+i8mm", "-i8mm")
ARM_ARCH_EXT_NAME("lob", ARM::AEK_LOB, "+lob", "-lob")
+ARM_ARCH_EXT_NAME("cdecp0", ARM::AEK_CDECP0, "+cdecp0", "-cdecp0")
+ARM_ARCH_EXT_NAME("cdecp1", ARM::AEK_CDECP1, "+cdecp1", "-cdecp1")
+ARM_ARCH_EXT_NAME("cdecp2", ARM::AEK_CDECP2, "+cdecp2", "-cdecp2")
+ARM_ARCH_EXT_NAME("cdecp3", ARM::AEK_CDECP3, "+cdecp3", "-cdecp3")
+ARM_ARCH_EXT_NAME("cdecp4", ARM::AEK_CDECP4, "+cdecp4", "-cdecp4")
+ARM_ARCH_EXT_NAME("cdecp5", ARM::AEK_CDECP5, "+cdecp5", "-cdecp5")
+ARM_ARCH_EXT_NAME("cdecp6", ARM::AEK_CDECP6, "+cdecp6", "-cdecp6")
+ARM_ARCH_EXT_NAME("cdecp7", ARM::AEK_CDECP7, "+cdecp7", "-cdecp7")
#undef ARM_ARCH_EXT_NAME
#ifndef ARM_HW_DIV_NAME
@@ -260,6 +276,8 @@ ARM_CPU_NAME("cortex-m7", ARMV7EM, FK_FPV5_D16, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m23", ARMV8MBaseline, FK_NONE, false, ARM::AEK_NONE)
ARM_CPU_NAME("cortex-m33", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
ARM_CPU_NAME("cortex-m35p", ARMV8MMainline, FK_FPV5_SP_D16, false, ARM::AEK_DSP)
+ARM_CPU_NAME("cortex-m55", ARMV8_1MMainline, FK_FP_ARMV8_FULLFP16_D16, false,
+ (ARM::AEK_DSP | ARM::AEK_SIMD | ARM::AEK_FP | ARM::AEK_FP16))
ARM_CPU_NAME("cortex-a32", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a35", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
ARM_CPU_NAME("cortex-a53", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
@@ -274,6 +292,12 @@ ARM_CPU_NAME("cortex-a76", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("cortex-a76ae", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
+ARM_CPU_NAME("cortex-a77", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (ARM::AEK_FP16 | ARM::AEK_DOTPROD))
+ARM_CPU_NAME("cortex-a78",ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (ARM::AEK_FP16 | ARM::AEK_DOTPROD))
+ARM_CPU_NAME("cortex-x1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
+ (ARM::AEK_FP16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("neoverse-n1", ARMV8_2A, FK_CRYPTO_NEON_FP_ARMV8, false,
(ARM::AEK_FP16 | ARM::AEK_DOTPROD))
ARM_CPU_NAME("cyclone", ARMV8A, FK_CRYPTO_NEON_FP_ARMV8, false, ARM::AEK_CRC)
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.h b/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.h
index 02d4c975129f..4e76b3c4b83e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ARMTargetParser.h
@@ -14,17 +14,20 @@
#ifndef LLVM_SUPPORT_ARMTARGETPARSER_H
#define LLVM_SUPPORT_ARMTARGETPARSER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/ARMBuildAttributes.h"
#include <vector>
namespace llvm {
+
+class Triple;
+
namespace ARM {
// Arch extension modifiers for CPUs.
// Note that this is not the same as the AArch64 list
-enum ArchExtKind : unsigned {
+enum ArchExtKind : uint64_t {
AEK_INVALID = 0,
AEK_NONE = 1,
AEK_CRC = 1 << 1,
@@ -46,12 +49,23 @@ enum ArchExtKind : unsigned {
AEK_SB = 1 << 17,
AEK_FP_DP = 1 << 18,
AEK_LOB = 1 << 19,
+ AEK_BF16 = 1 << 20,
+ AEK_I8MM = 1 << 21,
+ AEK_CDECP0 = 1 << 22,
+ AEK_CDECP1 = 1 << 23,
+ AEK_CDECP2 = 1 << 24,
+ AEK_CDECP3 = 1 << 25,
+ AEK_CDECP4 = 1 << 26,
+ AEK_CDECP5 = 1 << 27,
+ AEK_CDECP6 = 1 << 28,
+ AEK_CDECP7 = 1 << 29,
+
// Unsupported extensions.
- AEK_OS = 0x8000000,
- AEK_IWMMXT = 0x10000000,
- AEK_IWMMXT2 = 0x20000000,
- AEK_MAVERICK = 0x40000000,
- AEK_XSCALE = 0x80000000,
+ AEK_OS = 1ULL << 59,
+ AEK_IWMMXT = 1ULL << 60,
+ AEK_IWMMXT2 = 1ULL << 61,
+ AEK_MAVERICK = 1ULL << 62,
+ AEK_XSCALE = 1ULL << 63,
};
// List of Arch Extension names.
@@ -59,7 +73,7 @@ enum ArchExtKind : unsigned {
struct ExtName {
const char *NameCStr;
size_t NameLength;
- unsigned ID;
+ uint64_t ID;
const char *Feature;
const char *NegFeature;
@@ -78,7 +92,7 @@ const ExtName ARCHExtNames[] = {
const struct {
const char *NameCStr;
size_t NameLength;
- unsigned ID;
+ uint64_t ID;
StringRef getName() const { return StringRef(NameCStr, NameLength); }
} HWDivNames[] = {
@@ -102,7 +116,7 @@ template <typename T> struct CpuNames {
size_t NameLength;
T ArchID;
bool Default; // is $Name the default CPU for $ArchID ?
- unsigned DefaultExtensions;
+ uint64_t DefaultExtensions;
StringRef getName() const { return StringRef(NameCStr, NameLength); }
};
@@ -193,7 +207,7 @@ template <typename T> struct ArchNames {
const char *SubArchCStr;
size_t SubArchLength;
unsigned DefaultFPU;
- unsigned ArchBaseExtensions;
+ uint64_t ArchBaseExtensions;
T ID;
ARMBuildAttrs::CPUArch ArchAttr; // Arch ID in build attributes.
@@ -225,33 +239,33 @@ FPURestriction getFPURestriction(unsigned FPUKind);
// FIXME: These should be moved to TargetTuple once it exists
bool getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features);
-bool getHWDivFeatures(unsigned HWDivKind, std::vector<StringRef> &Features);
-bool getExtensionFeatures(unsigned Extensions,
+bool getHWDivFeatures(uint64_t HWDivKind, std::vector<StringRef> &Features);
+bool getExtensionFeatures(uint64_t Extensions,
std::vector<StringRef> &Features);
StringRef getArchName(ArchKind AK);
unsigned getArchAttr(ArchKind AK);
StringRef getCPUAttr(ArchKind AK);
StringRef getSubArch(ArchKind AK);
-StringRef getArchExtName(unsigned ArchExtKind);
+StringRef getArchExtName(uint64_t ArchExtKind);
StringRef getArchExtFeature(StringRef ArchExt);
bool appendArchExtFeatures(StringRef CPU, ARM::ArchKind AK, StringRef ArchExt,
std::vector<StringRef> &Features);
-StringRef getHWDivName(unsigned HWDivKind);
+StringRef getHWDivName(uint64_t HWDivKind);
// Information by Name
unsigned getDefaultFPU(StringRef CPU, ArchKind AK);
-unsigned getDefaultExtensions(StringRef CPU, ArchKind AK);
+uint64_t getDefaultExtensions(StringRef CPU, ArchKind AK);
StringRef getDefaultCPU(StringRef Arch);
StringRef getCanonicalArchName(StringRef Arch);
StringRef getFPUSynonym(StringRef FPU);
StringRef getArchSynonym(StringRef Arch);
// Parser
-unsigned parseHWDiv(StringRef HWDiv);
+uint64_t parseHWDiv(StringRef HWDiv);
unsigned parseFPU(StringRef FPU);
ArchKind parseArch(StringRef Arch);
-unsigned parseArchExt(StringRef ArchExt);
+uint64_t parseArchExt(StringRef ArchExt);
ArchKind parseCPUArch(StringRef CPU);
ISAKind parseArchISA(StringRef Arch);
EndianKind parseArchEndian(StringRef Arch);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Alignment.h b/contrib/llvm-project/llvm/include/llvm/Support/Alignment.h
index 72fad87dd0d4..667434e8a407 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Alignment.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Alignment.h
@@ -22,17 +22,16 @@
#define LLVM_SUPPORT_ALIGNMENT_H_
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
-#include <limits>
+#ifndef NDEBUG
+#include <string>
+#endif // NDEBUG
namespace llvm {
#define ALIGN_CHECK_ISPOSITIVE(decl) \
assert(decl > 0 && (#decl " should be defined"))
-#define ALIGN_CHECK_ISSET(decl) \
- assert(decl.hasValue() && (#decl " should be defined"))
/// This struct is a compact representation of a valid (non-zero power of two)
/// alignment.
@@ -86,11 +85,14 @@ public:
uint64_t value() const { return uint64_t(1) << ShiftValue; }
/// Returns a default constructed Align which corresponds to no alignment.
- /// This is useful to test for unalignment as it conveys clear semantic.
- /// `if (A != Align::None())`
- /// would be better than
- /// `if (A > Align(1))`
- constexpr static const Align None() { return Align(); }
+ /// It was decided to deprecate Align::None because it's too close to
+ /// llvm::None which can be used to initialize `MaybeAlign`.
+ /// MaybeAlign = llvm::None means unspecified alignment,
+ /// Align = Align::None() means alignment of one byte.
+ LLVM_ATTRIBUTE_DEPRECATED(constexpr static const Align None(),
+ "Use Align() or Align(1) instead") {
+ return Align();
+ }
/// Allow constructions of constexpr Align.
template <size_t kValue> constexpr static LogValue Constant() {
@@ -147,13 +149,6 @@ inline bool isAligned(Align Lhs, uint64_t SizeInBytes) {
return SizeInBytes % Lhs.value() == 0;
}
-/// Checks that SizeInBytes is a multiple of the alignment.
-/// Returns false if the alignment is undefined.
-inline bool isAligned(MaybeAlign Lhs, uint64_t SizeInBytes) {
- ALIGN_CHECK_ISSET(Lhs);
- return SizeInBytes % (*Lhs).value() == 0;
-}
-
/// Checks that Addr is a multiple of the alignment.
inline bool isAddrAligned(Align Lhs, const void *Addr) {
return isAligned(Lhs, reinterpret_cast<uintptr_t>(Addr));
@@ -161,17 +156,34 @@ inline bool isAddrAligned(Align Lhs, const void *Addr) {
/// Returns a multiple of A needed to store `Size` bytes.
inline uint64_t alignTo(uint64_t Size, Align A) {
- const uint64_t value = A.value();
- // The following line is equivalent to `(Size + value - 1) / value * value`.
+ const uint64_t Value = A.value();
+ // The following line is equivalent to `(Size + Value - 1) / Value * Value`.
// The division followed by a multiplication can be thought of as a right
// shift followed by a left shift which zeros out the extra bits produced in
- // the bump; `~(value - 1)` is a mask where all those bits being zeroed out
+ // the bump; `~(Value - 1)` is a mask where all those bits being zeroed out
// are just zero.
// Most compilers can generate this code but the pattern may be missed when
// multiple functions gets inlined.
- return (Size + value - 1) & ~(value - 1);
+ return (Size + Value - 1) & ~(Value - 1U);
+}
+
+/// If non-zero \p Skew is specified, the return value will be a minimal integer
+/// that is greater than or equal to \p Size and equal to \p A * N + \p Skew for
+/// some integer N. If \p Skew is larger than \p A, its value is adjusted to '\p
+/// Skew mod \p A'.
+///
+/// Examples:
+/// \code
+/// alignTo(5, Align(8), 7) = 7
+/// alignTo(17, Align(8), 1) = 17
+/// alignTo(~0LL, Align(8), 3) = 3
+/// \endcode
+inline uint64_t alignTo(uint64_t Size, Align A, uint64_t Skew) {
+ const uint64_t Value = A.value();
+ Skew %= Value;
+ return ((Size + Value - 1 - Skew) & ~(Value - 1U)) + Skew;
}
/// Returns a multiple of A needed to store `Size` bytes.
@@ -184,7 +196,8 @@ inline uint64_t alignTo(uint64_t Size, MaybeAlign A) {
inline uintptr_t alignAddr(const void *Addr, Align Alignment) {
uintptr_t ArithAddr = reinterpret_cast<uintptr_t>(Addr);
assert(static_cast<uintptr_t>(ArithAddr + Alignment.value() - 1) >=
- ArithAddr && "Overflow");
+ ArithAddr &&
+ "Overflow");
return alignTo(ArithAddr, Alignment);
}
@@ -203,13 +216,6 @@ inline uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment) {
/// Returns the log2 of the alignment.
inline unsigned Log2(Align A) { return A.ShiftValue; }
-/// Returns the log2 of the alignment.
-/// \pre A must be defined.
-inline unsigned Log2(MaybeAlign A) {
- ALIGN_CHECK_ISSET(A);
- return Log2(A.getValue());
-}
-
/// Returns the alignment that satisfies both alignments.
/// Same semantic as MinAlign.
inline Align commonAlignment(Align A, Align B) { return std::min(A, B); }
@@ -281,26 +287,6 @@ inline bool operator==(MaybeAlign Lhs, uint64_t Rhs) {
inline bool operator!=(MaybeAlign Lhs, uint64_t Rhs) {
return Lhs ? (*Lhs).value() != Rhs : Rhs != 0;
}
-inline bool operator<=(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() <= Rhs;
-}
-inline bool operator>=(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() >= Rhs;
-}
-inline bool operator<(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() < Rhs;
-}
-inline bool operator>(MaybeAlign Lhs, uint64_t Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- ALIGN_CHECK_ISPOSITIVE(Rhs);
- return (*Lhs).value() > Rhs;
-}
/// Comparisons operators between Align.
inline bool operator==(Align Lhs, Align Rhs) {
@@ -322,56 +308,30 @@ inline bool operator>(Align Lhs, Align Rhs) {
return Lhs.ShiftValue > Rhs.ShiftValue;
}
-/// Comparisons operators between Align and MaybeAlign.
-inline bool operator==(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() == (*Rhs).value();
-}
-inline bool operator!=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() != (*Rhs).value();
-}
-inline bool operator<=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() <= (*Rhs).value();
-}
-inline bool operator>=(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() >= (*Rhs).value();
-}
-inline bool operator<(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() < (*Rhs).value();
-}
-inline bool operator>(Align Lhs, MaybeAlign Rhs) {
- ALIGN_CHECK_ISSET(Rhs);
- return Lhs.value() > (*Rhs).value();
-}
+// Don't allow relational comparisons with MaybeAlign.
+bool operator<=(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator>=(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator<(Align Lhs, MaybeAlign Rhs) = delete;
+bool operator>(Align Lhs, MaybeAlign Rhs) = delete;
-/// Comparisons operators between MaybeAlign and Align.
-inline bool operator==(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() == Rhs.value();
-}
-inline bool operator!=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() != Rhs.value();
-}
-inline bool operator<=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() <= Rhs.value();
-}
-inline bool operator>=(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() >= Rhs.value();
-}
-inline bool operator<(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() < Rhs.value();
+bool operator<=(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator>=(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator<(MaybeAlign Lhs, Align Rhs) = delete;
+bool operator>(MaybeAlign Lhs, Align Rhs) = delete;
+
+bool operator<=(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator>=(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator<(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+bool operator>(MaybeAlign Lhs, MaybeAlign Rhs) = delete;
+
+inline Align operator*(Align Lhs, uint64_t Rhs) {
+ assert(Rhs > 0 && "Rhs must be positive");
+ return Align(Lhs.value() * Rhs);
}
-inline bool operator>(MaybeAlign Lhs, Align Rhs) {
- ALIGN_CHECK_ISSET(Lhs);
- return Lhs && (*Lhs).value() > Rhs.value();
+
+inline MaybeAlign operator*(MaybeAlign Lhs, uint64_t Rhs) {
+ assert(Rhs > 0 && "Rhs must be positive");
+ return Lhs ? Lhs.getValue() * Rhs : MaybeAlign();
}
inline Align operator/(Align Lhs, uint64_t Divisor) {
@@ -395,8 +355,20 @@ inline Align max(Align Lhs, MaybeAlign Rhs) {
return Rhs && *Rhs > Lhs ? *Rhs : Lhs;
}
+#ifndef NDEBUG
+// For usage in LLVM_DEBUG macros.
+inline std::string DebugStr(const Align &A) {
+ return std::to_string(A.value());
+}
+// For usage in LLVM_DEBUG macros.
+inline std::string DebugStr(const MaybeAlign &MA) {
+ if (MA)
+ return std::to_string(MA->value());
+ return "None";
+}
+#endif // NDEBUG
+
#undef ALIGN_CHECK_ISPOSITIVE
-#undef ALIGN_CHECK_ISSET
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Allocator.h b/contrib/llvm-project/llvm/include/llvm/Support/Allocator.h
index 670335ffecbc..40c967ccc485 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Allocator.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Allocator.h
@@ -7,13 +7,10 @@
//===----------------------------------------------------------------------===//
/// \file
///
-/// This file defines the MallocAllocator and BumpPtrAllocator interfaces. Both
-/// of these conform to an LLVM "Allocator" concept which consists of an
-/// Allocate method accepting a size and alignment, and a Deallocate accepting
-/// a pointer and size. Further, the LLVM "Allocator" concept has overloads of
-/// Allocate and Deallocate for setting size and alignment based on the final
-/// type. These overloads are typically provided by a base class template \c
-/// AllocatorBase.
+/// This file defines the BumpPtrAllocator interface. BumpPtrAllocator conforms
+/// to the LLVM "Allocator" concept and is similar to MallocAllocator, but
+/// objects cannot be deallocated. Their lifetime is tied to the lifetime of the
+/// allocator.
///
//===----------------------------------------------------------------------===//
@@ -23,6 +20,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Alignment.h"
+#include "llvm/Support/AllocatorBase.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
@@ -38,81 +36,6 @@
namespace llvm {
-/// CRTP base class providing obvious overloads for the core \c
-/// Allocate() methods of LLVM-style allocators.
-///
-/// This base class both documents the full public interface exposed by all
-/// LLVM-style allocators, and redirects all of the overloads to a single core
-/// set of methods which the derived class must define.
-template <typename DerivedT> class AllocatorBase {
-public:
- /// Allocate \a Size bytes of \a Alignment aligned memory. This method
- /// must be implemented by \c DerivedT.
- void *Allocate(size_t Size, size_t Alignment) {
-#ifdef __clang__
- static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
- &AllocatorBase::Allocate) !=
- static_cast<void *(DerivedT::*)(size_t, size_t)>(
- &DerivedT::Allocate),
- "Class derives from AllocatorBase without implementing the "
- "core Allocate(size_t, size_t) overload!");
-#endif
- return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
- }
-
- /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
- /// allocator.
- void Deallocate(const void *Ptr, size_t Size) {
-#ifdef __clang__
- static_assert(static_cast<void (AllocatorBase::*)(const void *, size_t)>(
- &AllocatorBase::Deallocate) !=
- static_cast<void (DerivedT::*)(const void *, size_t)>(
- &DerivedT::Deallocate),
- "Class derives from AllocatorBase without implementing the "
- "core Deallocate(void *) overload!");
-#endif
- return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size);
- }
-
- // The rest of these methods are helpers that redirect to one of the above
- // core methods.
-
- /// Allocate space for a sequence of objects without constructing them.
- template <typename T> T *Allocate(size_t Num = 1) {
- return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
- }
-
- /// Deallocate space for a sequence of objects without constructing them.
- template <typename T>
- typename std::enable_if<
- !std::is_same<typename std::remove_cv<T>::type, void>::value, void>::type
- Deallocate(T *Ptr, size_t Num = 1) {
- Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T));
- }
-};
-
-class MallocAllocator : public AllocatorBase<MallocAllocator> {
-public:
- void Reset() {}
-
- LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size,
- size_t /*Alignment*/) {
- return safe_malloc(Size);
- }
-
- // Pull in base class overloads.
- using AllocatorBase<MallocAllocator>::Allocate;
-
- void Deallocate(const void *Ptr, size_t /*Size*/) {
- free(const_cast<void *>(Ptr));
- }
-
- // Pull in base class overloads.
- using AllocatorBase<MallocAllocator>::Deallocate;
-
- void PrintStats() const {}
-};
-
namespace detail {
// We call out to an external function to actually print the message as the
@@ -136,16 +59,22 @@ void printBumpPtrAllocatorStats(unsigned NumSlabs, size_t BytesAllocated,
/// The BumpPtrAllocatorImpl template defaults to using a MallocAllocator
/// object, which wraps malloc, to allocate memory, but it can be changed to
/// use a custom allocator.
+///
+/// The GrowthDelay specifies after how many allocated slabs the allocator
+/// increases the size of the slabs.
template <typename AllocatorT = MallocAllocator, size_t SlabSize = 4096,
- size_t SizeThreshold = SlabSize>
+ size_t SizeThreshold = SlabSize, size_t GrowthDelay = 128>
class BumpPtrAllocatorImpl
- : public AllocatorBase<
- BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>> {
+ : public AllocatorBase<BumpPtrAllocatorImpl<AllocatorT, SlabSize,
+ SizeThreshold, GrowthDelay>> {
public:
static_assert(SizeThreshold <= SlabSize,
"The SizeThreshold must be at most the SlabSize to ensure "
"that objects larger than a slab go into their own memory "
"allocation.");
+ static_assert(GrowthDelay > 0,
+ "GrowthDelay must be at least 1 which already increases the"
+ "slab size after each allocated slab.");
BumpPtrAllocatorImpl() = default;
@@ -241,7 +170,7 @@ public:
// If Size is really big, allocate a separate slab for it.
size_t PaddedSize = SizeToAllocate + Alignment.value() - 1;
if (PaddedSize > SizeThreshold) {
- void *NewSlab = Allocator.Allocate(PaddedSize, 0);
+ void *NewSlab = Allocator.Allocate(PaddedSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anyting other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, PaddedSize);
@@ -279,7 +208,7 @@ public:
// Bump pointer allocators are expected to never free their storage; and
// clients expect pointers to remain valid for non-dereferencing uses even
// after deallocation.
- void Deallocate(const void *Ptr, size_t Size) {
+ void Deallocate(const void *Ptr, size_t Size, size_t /*Alignment*/) {
__asan_poison_memory_region(Ptr, Size);
}
@@ -391,10 +320,11 @@ private:
static size_t computeSlabSize(unsigned SlabIdx) {
// Scale the actual allocated slab size based on the number of slabs
- // allocated. Every 128 slabs allocated, we double the allocated size to
- // reduce allocation frequency, but saturate at multiplying the slab size by
- // 2^30.
- return SlabSize * ((size_t)1 << std::min<size_t>(30, SlabIdx / 128));
+ // allocated. Every GrowthDelay slabs allocated, we double
+ // the allocated size to reduce allocation frequency, but saturate at
+ // multiplying the slab size by 2^30.
+ return SlabSize *
+ ((size_t)1 << std::min<size_t>(30, SlabIdx / GrowthDelay));
}
/// Allocate a new slab and move the bump pointers over into the new
@@ -402,7 +332,8 @@ private:
void StartNewSlab() {
size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
- void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
+ void *NewSlab =
+ Allocator.Allocate(AllocatedSlabSize, alignof(std::max_align_t));
// We own the new slab and don't want anyone reading anything other than
// pieces returned from this method. So poison the whole slab.
__asan_poison_memory_region(NewSlab, AllocatedSlabSize);
@@ -418,7 +349,7 @@ private:
for (; I != E; ++I) {
size_t AllocatedSlabSize =
computeSlabSize(std::distance(Slabs.begin(), I));
- Allocator.Deallocate(*I, AllocatedSlabSize);
+ Allocator.Deallocate(*I, AllocatedSlabSize, alignof(std::max_align_t));
}
}
@@ -427,7 +358,7 @@ private:
for (auto &PtrAndSize : CustomSizedSlabs) {
void *Ptr = PtrAndSize.first;
size_t Size = PtrAndSize.second;
- Allocator.Deallocate(Ptr, Size);
+ Allocator.Deallocate(Ptr, Size, alignof(std::max_align_t));
}
}
@@ -498,26 +429,21 @@ public:
} // end namespace llvm
-template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
-void *operator new(size_t Size,
- llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize,
- SizeThreshold> &Allocator) {
- struct S {
- char c;
- union {
- double D;
- long double LD;
- long long L;
- void *P;
- } x;
- };
- return Allocator.Allocate(
- Size, std::min((size_t)llvm::NextPowerOf2(Size), offsetof(S, x)));
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,
+ size_t GrowthDelay>
+void *
+operator new(size_t Size,
+ llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold,
+ GrowthDelay> &Allocator) {
+ return Allocator.Allocate(Size, std::min((size_t)llvm::NextPowerOf2(Size),
+ alignof(std::max_align_t)));
}
-template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold>
-void operator delete(
- void *, llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold> &) {
+template <typename AllocatorT, size_t SlabSize, size_t SizeThreshold,
+ size_t GrowthDelay>
+void operator delete(void *,
+ llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize,
+ SizeThreshold, GrowthDelay> &) {
}
#endif // LLVM_SUPPORT_ALLOCATOR_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/AllocatorBase.h b/contrib/llvm-project/llvm/include/llvm/Support/AllocatorBase.h
new file mode 100644
index 000000000000..e5549d111622
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/AllocatorBase.h
@@ -0,0 +1,103 @@
+//===- AllocatorBase.h - Simple memory allocation abstraction ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file defines MallocAllocator. MallocAllocator conforms to the LLVM
+/// "Allocator" concept which consists of an Allocate method accepting a size
+/// and alignment, and a Deallocate accepting a pointer and size. Further, the
+/// LLVM "Allocator" concept has overloads of Allocate and Deallocate for
+/// setting size and alignment based on the final type. These overloads are
+/// typically provided by a base class template \c AllocatorBase.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATORBASE_H
+#define LLVM_SUPPORT_ALLOCATORBASE_H
+
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/MemAlloc.h"
+
+namespace llvm {
+
+/// CRTP base class providing obvious overloads for the core \c
+/// Allocate() methods of LLVM-style allocators.
+///
+/// This base class both documents the full public interface exposed by all
+/// LLVM-style allocators, and redirects all of the overloads to a single core
+/// set of methods which the derived class must define.
+template <typename DerivedT> class AllocatorBase {
+public:
+ /// Allocate \a Size bytes of \a Alignment aligned memory. This method
+ /// must be implemented by \c DerivedT.
+ void *Allocate(size_t Size, size_t Alignment) {
+#ifdef __clang__
+ static_assert(static_cast<void *(AllocatorBase::*)(size_t, size_t)>(
+ &AllocatorBase::Allocate) !=
+ static_cast<void *(DerivedT::*)(size_t, size_t)>(
+ &DerivedT::Allocate),
+ "Class derives from AllocatorBase without implementing the "
+ "core Allocate(size_t, size_t) overload!");
+#endif
+ return static_cast<DerivedT *>(this)->Allocate(Size, Alignment);
+ }
+
+ /// Deallocate \a Ptr to \a Size bytes of memory allocated by this
+ /// allocator.
+ void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
+#ifdef __clang__
+ static_assert(
+ static_cast<void (AllocatorBase::*)(const void *, size_t, size_t)>(
+ &AllocatorBase::Deallocate) !=
+ static_cast<void (DerivedT::*)(const void *, size_t, size_t)>(
+ &DerivedT::Deallocate),
+ "Class derives from AllocatorBase without implementing the "
+ "core Deallocate(void *) overload!");
+#endif
+ return static_cast<DerivedT *>(this)->Deallocate(Ptr, Size, Alignment);
+ }
+
+ // The rest of these methods are helpers that redirect to one of the above
+ // core methods.
+
+ /// Allocate space for a sequence of objects without constructing them.
+ template <typename T> T *Allocate(size_t Num = 1) {
+ return static_cast<T *>(Allocate(Num * sizeof(T), alignof(T)));
+ }
+
+ /// Deallocate space for a sequence of objects without constructing them.
+ template <typename T>
+ std::enable_if_t<!std::is_same<std::remove_cv_t<T>, void>::value, void>
+ Deallocate(T *Ptr, size_t Num = 1) {
+ Deallocate(static_cast<const void *>(Ptr), Num * sizeof(T), alignof(T));
+ }
+};
+
+class MallocAllocator : public AllocatorBase<MallocAllocator> {
+public:
+ void Reset() {}
+
+ LLVM_ATTRIBUTE_RETURNS_NONNULL void *Allocate(size_t Size, size_t Alignment) {
+ return allocate_buffer(Size, Alignment);
+ }
+
+ // Pull in base class overloads.
+ using AllocatorBase<MallocAllocator>::Allocate;
+
+ void Deallocate(const void *Ptr, size_t Size, size_t Alignment) {
+ deallocate_buffer(const_cast<void *>(Ptr), Size, Alignment);
+ }
+
+ // Pull in base class overloads.
+ using AllocatorBase<MallocAllocator>::Deallocate;
+
+ void PrintStats() const {}
+};
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_ALLOCATORBASE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/AtomicOrdering.h b/contrib/llvm-project/llvm/include/llvm/Support/AtomicOrdering.h
index 763bc3ea7b28..a8d89955fa2b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/AtomicOrdering.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/AtomicOrdering.h
@@ -53,7 +53,7 @@ template <typename Int> inline bool isValidAtomicOrderingCABI(Int I) {
///
/// not_atomic-->unordered-->relaxed-->release--------------->acq_rel-->seq_cst
/// \-->consume-->acquire--/
-enum class AtomicOrdering {
+enum class AtomicOrdering : unsigned {
NotAtomic = 0,
Unordered = 1,
Monotonic = 2, // Equivalent to C++'s relaxed.
@@ -61,7 +61,8 @@ enum class AtomicOrdering {
Acquire = 4,
Release = 5,
AcquireRelease = 6,
- SequentiallyConsistent = 7
+ SequentiallyConsistent = 7,
+ LAST = SequentiallyConsistent
};
bool operator<(AtomicOrdering, AtomicOrdering) = delete;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Base64.h b/contrib/llvm-project/llvm/include/llvm/Support/Base64.h
new file mode 100644
index 000000000000..62064a35aa34
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Base64.h
@@ -0,0 +1,56 @@
+//===--- Base64.h - Base64 Encoder/Decoder ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides generic base64 encoder/decoder.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_BASE64_H
+#define LLVM_SUPPORT_BASE64_H
+
+#include <string>
+
+namespace llvm {
+
+template <class InputBytes> std::string encodeBase64(InputBytes const &Bytes) {
+ static const char Table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
+ std::string Buffer;
+ Buffer.resize(((Bytes.size() + 2) / 3) * 4);
+
+ size_t i = 0, j = 0;
+ for (size_t n = Bytes.size() / 3 * 3; i < n; i += 3, j += 4) {
+ uint32_t x = ((unsigned char)Bytes[i] << 16) |
+ ((unsigned char)Bytes[i + 1] << 8) |
+ (unsigned char)Bytes[i + 2];
+ Buffer[j + 0] = Table[(x >> 18) & 63];
+ Buffer[j + 1] = Table[(x >> 12) & 63];
+ Buffer[j + 2] = Table[(x >> 6) & 63];
+ Buffer[j + 3] = Table[x & 63];
+ }
+ if (i + 1 == Bytes.size()) {
+ uint32_t x = ((unsigned char)Bytes[i] << 16);
+ Buffer[j + 0] = Table[(x >> 18) & 63];
+ Buffer[j + 1] = Table[(x >> 12) & 63];
+ Buffer[j + 2] = '=';
+ Buffer[j + 3] = '=';
+ } else if (i + 2 == Bytes.size()) {
+ uint32_t x =
+ ((unsigned char)Bytes[i] << 16) | ((unsigned char)Bytes[i + 1] << 8);
+ Buffer[j + 0] = Table[(x >> 18) & 63];
+ Buffer[j + 1] = Table[(x >> 12) & 63];
+ Buffer[j + 2] = Table[(x >> 6) & 63];
+ Buffer[j + 3] = '=';
+ }
+ return Buffer;
+}
+
+} // end namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamArray.h b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamArray.h
index 1634983d26ce..3ba65c07cfe2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamArray.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamArray.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Error.h"
#include <cassert>
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamReader.h b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamReader.h
index b7d61c02667b..b611707807c0 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamReader.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Alignment.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/ConvertUTF.h"
@@ -89,7 +90,7 @@ public:
template <typename T> Error readEnum(T &Dest) {
static_assert(std::is_enum<T>::value,
"Cannot call readEnum with non-enum value!");
- typename std::underlying_type<T>::type N;
+ std::underlying_type_t<T> N;
if (auto EC = readInteger(N))
return EC;
Dest = static_cast<T>(N);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamWriter.h b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamWriter.h
index 86d2389d9182..ceba792e6b26 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/BinaryStreamWriter.h
@@ -75,7 +75,7 @@ public:
static_assert(std::is_enum<T>::value,
"Cannot call writeEnum with non-Enum type");
- using U = typename std::underlying_type<T>::type;
+ using U = std::underlying_type_t<T>;
return writeInteger<U>(static_cast<U>(Num));
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/BranchProbability.h b/contrib/llvm-project/llvm/include/llvm/Support/BranchProbability.h
index cd9d369b4f4e..6c7ad1fe2a52 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/BranchProbability.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/BranchProbability.h
@@ -32,8 +32,8 @@ class BranchProbability {
uint32_t N;
// Denominator, which is a constant value.
- static const uint32_t D = 1u << 31;
- static const uint32_t UnknownN = UINT32_MAX;
+ static constexpr uint32_t D = 1u << 31;
+ static constexpr uint32_t UnknownN = UINT32_MAX;
// Construct a BranchProbability with only numerator assuming the denominator
// is 1<<31. For internal use only.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/CFGDiff.h b/contrib/llvm-project/llvm/include/llvm/Support/CFGDiff.h
new file mode 100644
index 000000000000..94734ce70e02
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/CFGDiff.h
@@ -0,0 +1,250 @@
+//===- CFGDiff.h - Define a CFG snapshot. -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines specializations of GraphTraits that allows generic
+// algorithms to see a different snapshot of a CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CFGDIFF_H
+#define LLVM_SUPPORT_CFGDIFF_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/CFGUpdate.h"
+#include "llvm/Support/type_traits.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+
+// Two booleans are used to define orders in graphs:
+// InverseGraph defines when we need to reverse the whole graph and is as such
+// also equivalent to applying updates in reverse.
+// InverseEdge defines whether we want to change the edges direction. E.g., for
+// a non-inversed graph, the children are naturally the successors when
+// InverseEdge is false and the predecessors when InverseEdge is true.
+
+// We define two base clases that call into GraphDiff, one for successors
+// (CFGSuccessors), where InverseEdge is false, and one for predecessors
+// (CFGPredecessors), where InverseEdge is true.
+// FIXME: Further refactoring may merge the two base classes into a single one
+// templated / parametrized on using succ_iterator/pred_iterator and false/true
+// for the InverseEdge.
+
+// CFGViewChildren and CFGViewPredecessors, both can be parametrized to
+// consider the graph inverted or not (i.e. InverseGraph). Successors
+// implicitly has InverseEdge = false and Predecessors implicitly has
+// InverseEdge = true (see calls to GraphDiff methods in there). The GraphTraits
+// instantiations that follow define the value of InverseGraph.
+
+// GraphTraits instantiations:
+// - GraphDiff<BasicBlock *> is equivalent to InverseGraph = false
+// - GraphDiff<Inverse<BasicBlock *>> is equivalent to InverseGraph = true
+// - second pair item is BasicBlock *, then InverseEdge = false (so it inherits
+// from CFGViewChildren).
+// - second pair item is Inverse<BasicBlock *>, then InverseEdge = true (so it
+// inherits from CFGViewPredecessors).
+
+// The 4 GraphTraits are as follows:
+// 1. std::pair<const GraphDiff<BasicBlock *> *, BasicBlock *>> :
+// CFGViewChildren<false>
+// Regular CFG, children means successors, InverseGraph = false,
+// InverseEdge = false.
+// 2. std::pair<const GraphDiff<Inverse<BasicBlock *>> *, BasicBlock *>> :
+// CFGViewChildren<true>
+// Reverse the graph, get successors but reverse-apply updates,
+// InverseGraph = true, InverseEdge = false.
+// 3. std::pair<const GraphDiff<BasicBlock *> *, Inverse<BasicBlock *>>> :
+// CFGViewPredecessors<false>
+// Regular CFG, reverse edges, so children mean predecessors,
+// InverseGraph = false, InverseEdge = true.
+// 4. std::pair<const GraphDiff<Inverse<BasicBlock *>> *, Inverse<BasicBlock *>>
+// : CFGViewPredecessors<true>
+// Reverse the graph and the edges, InverseGraph = true, InverseEdge = true.
+
+namespace llvm {
+
+// GraphDiff defines a CFG snapshot: given a set of Update<NodePtr>, provide
+// utilities to skip edges marked as deleted and return a set of edges marked as
+// newly inserted. The current diff treats the CFG as a graph rather than a
+// multigraph. Added edges are pruned to be unique, and deleted edges will
+// remove all existing edges between two blocks.
+template <typename NodePtr, bool InverseGraph = false> class GraphDiff {
+ using UpdateMapType = SmallDenseMap<NodePtr, SmallVector<NodePtr, 2>>;
+ struct EdgesInsertedDeleted {
+ UpdateMapType Succ;
+ UpdateMapType Pred;
+ };
+ // Store Deleted edges on position 0, and Inserted edges on position 1.
+ EdgesInsertedDeleted Edges[2];
+ // By default, it is assumed that, given a CFG and a set of updates, we wish
+ // to apply these updates as given. If UpdatedAreReverseApplied is set, the
+ // updates will be applied in reverse: deleted edges are considered re-added
+ // and inserted edges are considered deleted when returning children.
+ bool UpdatedAreReverseApplied;
+ // Using a singleton empty vector for all node requests with no
+ // children.
+ SmallVector<NodePtr, 0> Empty;
+
+ // Keep the list of legalized updates for a deterministic order of updates
+ // when using a GraphDiff for incremental updates in the DominatorTree.
+ // The list is kept in reverse to allow popping from end.
+ SmallVector<cfg::Update<NodePtr>, 4> LegalizedUpdates;
+
+ void printMap(raw_ostream &OS, const UpdateMapType &M) const {
+ for (auto Pair : M)
+ for (auto Child : Pair.second) {
+ OS << "(";
+ Pair.first->printAsOperand(OS, false);
+ OS << ", ";
+ Child->printAsOperand(OS, false);
+ OS << ") ";
+ }
+ OS << "\n";
+ }
+
+public:
+ GraphDiff() : UpdatedAreReverseApplied(false) {}
+ GraphDiff(ArrayRef<cfg::Update<NodePtr>> Updates,
+ bool ReverseApplyUpdates = false) {
+ cfg::LegalizeUpdates<NodePtr>(Updates, LegalizedUpdates, InverseGraph,
+ /*ReverseResultOrder=*/true);
+ // The legalized updates are stored in reverse so we can pop_back when doing
+ // incremental updates.
+ for (auto U : LegalizedUpdates) {
+ unsigned IsInsert =
+ (U.getKind() == cfg::UpdateKind::Insert) == !ReverseApplyUpdates;
+ Edges[IsInsert].Succ[U.getFrom()].push_back(U.getTo());
+ Edges[IsInsert].Pred[U.getTo()].push_back(U.getFrom());
+ }
+ UpdatedAreReverseApplied = ReverseApplyUpdates;
+ }
+
+ auto getLegalizedUpdates() const {
+ return make_range(LegalizedUpdates.begin(), LegalizedUpdates.end());
+ }
+
+ unsigned getNumLegalizedUpdates() const { return LegalizedUpdates.size(); }
+
+ cfg::Update<NodePtr> popUpdateForIncrementalUpdates() {
+ assert(!LegalizedUpdates.empty() && "No updates to apply!");
+ auto U = LegalizedUpdates.pop_back_val();
+ unsigned IsInsert =
+ (U.getKind() == cfg::UpdateKind::Insert) == !UpdatedAreReverseApplied;
+ auto &SuccList = Edges[IsInsert].Succ[U.getFrom()];
+ assert(SuccList.back() == U.getTo());
+ SuccList.pop_back();
+ if (SuccList.empty())
+ Edges[IsInsert].Succ.erase(U.getFrom());
+
+ auto &PredList = Edges[IsInsert].Pred[U.getTo()];
+ assert(PredList.back() == U.getFrom());
+ PredList.pop_back();
+ if (PredList.empty())
+ Edges[IsInsert].Pred.erase(U.getTo());
+ return U;
+ }
+
+ bool ignoreChild(const NodePtr BB, NodePtr EdgeEnd, bool InverseEdge) const {
+ // Used to filter nullptr in clang.
+ if (EdgeEnd == nullptr)
+ return true;
+ auto &DeleteChildren =
+ (InverseEdge != InverseGraph) ? Edges[0].Pred : Edges[0].Succ;
+ auto It = DeleteChildren.find(BB);
+ if (It == DeleteChildren.end())
+ return false;
+ auto &EdgesForBB = It->second;
+ return llvm::find(EdgesForBB, EdgeEnd) != EdgesForBB.end();
+ }
+
+ iterator_range<typename SmallVectorImpl<NodePtr>::const_iterator>
+ getAddedChildren(const NodePtr BB, bool InverseEdge) const {
+ auto &InsertChildren =
+ (InverseEdge != InverseGraph) ? Edges[1].Pred : Edges[1].Succ;
+ auto It = InsertChildren.find(BB);
+ if (It == InsertChildren.end())
+ return make_range(Empty.begin(), Empty.end());
+ return make_range(It->second.begin(), It->second.end());
+ }
+
+ void print(raw_ostream &OS) const {
+ OS << "===== GraphDiff: CFG edge changes to create a CFG snapshot. \n"
+ "===== (Note: notion of children/inverse_children depends on "
+ "the direction of edges and the graph.)\n";
+ OS << "Children to insert:\n\t";
+ printMap(OS, Edges[1].Succ);
+ OS << "Children to delete:\n\t";
+ printMap(OS, Edges[0].Succ);
+ OS << "Inverse_children to insert:\n\t";
+ printMap(OS, Edges[1].Pred);
+ OS << "Inverse_children to delete:\n\t";
+ printMap(OS, Edges[0].Pred);
+ OS << "\n";
+ }
+
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const { print(dbgs()); }
+#endif
+};
+
+template <typename GraphT, bool InverseGraph = false, bool InverseEdge = false,
+ typename GT = GraphTraits<GraphT>>
+struct CFGViewChildren {
+ using DataRef = const GraphDiff<typename GT::NodeRef, InverseGraph> *;
+ using NodeRef = std::pair<DataRef, typename GT::NodeRef>;
+
+ template<typename Range>
+ static auto makeChildRange(Range &&R, DataRef DR) {
+ using Iter = WrappedPairNodeDataIterator<decltype(std::forward<Range>(R).begin()), NodeRef, DataRef>;
+ return make_range(Iter(R.begin(), DR), Iter(R.end(), DR));
+ }
+
+ static auto children(NodeRef N) {
+
+ // filter iterator init:
+ auto R = make_range(GT::child_begin(N.second), GT::child_end(N.second));
+ // This lambda is copied into the iterators and persists to callers, ensure
+ // captures are by value or otherwise have sufficient lifetime.
+ auto First = make_filter_range(makeChildRange(R, N.first), [N](NodeRef C) {
+ return !C.first->ignoreChild(N.second, C.second, InverseEdge);
+ });
+
+ // new inserts iterator init:
+ auto InsertVec = N.first->getAddedChildren(N.second, InverseEdge);
+ auto Second = makeChildRange(InsertVec, N.first);
+
+ auto CR = concat<NodeRef>(First, Second);
+
+ // concat_range contains references to other ranges, returning it would
+ // leave those references dangling - the iterators contain
+ // other iterators by value so they're safe to return.
+ return make_range(CR.begin(), CR.end());
+ }
+
+ static auto child_begin(NodeRef N) {
+ return children(N).begin();
+ }
+
+ static auto child_end(NodeRef N) {
+ return children(N).end();
+ }
+
+ using ChildIteratorType = decltype(child_end(std::declval<NodeRef>()));
+};
+
+template <typename T, bool B>
+struct GraphTraits<std::pair<const GraphDiff<T, B> *, T>>
+ : CFGViewChildren<T, B> {};
+template <typename T, bool B>
+struct GraphTraits<std::pair<const GraphDiff<T, B> *, Inverse<T>>>
+ : CFGViewChildren<Inverse<T>, B, true> {};
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_CFGDIFF_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/CFGUpdate.h b/contrib/llvm-project/llvm/include/llvm/Support/CFGUpdate.h
index eeaf5d0a21ac..af4cd6ed1f1d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/CFGUpdate.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/CFGUpdate.h
@@ -62,7 +62,7 @@ public:
template <typename NodePtr>
void LegalizeUpdates(ArrayRef<Update<NodePtr>> AllUpdates,
SmallVectorImpl<Update<NodePtr>> &Result,
- bool InverseGraph) {
+ bool InverseGraph, bool ReverseResultOrder = false) {
// Count the total number of inserions of each edge.
// Each insertion adds 1 and deletion subtracts 1. The end number should be
// one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence
@@ -104,11 +104,11 @@ void LegalizeUpdates(ArrayRef<Update<NodePtr>> AllUpdates,
Operations[{U.getTo(), U.getFrom()}] = int(i);
}
- llvm::sort(Result,
- [&Operations](const Update<NodePtr> &A, const Update<NodePtr> &B) {
- return Operations[{A.getFrom(), A.getTo()}] >
- Operations[{B.getFrom(), B.getTo()}];
- });
+ llvm::sort(Result, [&](const Update<NodePtr> &A, const Update<NodePtr> &B) {
+ const auto &OpA = Operations[{A.getFrom(), A.getTo()}];
+ const auto &OpB = Operations[{B.getFrom(), B.getTo()}];
+ return ReverseResultOrder ? OpA < OpB : OpA > OpB;
+ });
}
} // end namespace cfg
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/CachePruning.h b/contrib/llvm-project/llvm/include/llvm/Support/CachePruning.h
index a72a86439f6a..10d6372f9163 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/CachePruning.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/CachePruning.h
@@ -14,12 +14,13 @@
#ifndef LLVM_SUPPORT_CACHE_PRUNING_H
#define LLVM_SUPPORT_CACHE_PRUNING_H
-#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Optional.h"
#include <chrono>
namespace llvm {
template <typename T> class Expected;
+class StringRef;
/// Policy for the pruneCache() function. A default constructed
/// CachePruningPolicy provides a reasonable default policy.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Casting.h b/contrib/llvm-project/llvm/include/llvm/Support/Casting.h
index 46bdedb04cfe..d6f7793d5df0 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Casting.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Casting.h
@@ -61,8 +61,7 @@ struct isa_impl {
/// Always allow upcasts, and perform no dynamic check for them.
template <typename To, typename From>
-struct isa_impl<
- To, From, typename std::enable_if<std::is_base_of<To, From>::value>::type> {
+struct isa_impl<To, From, std::enable_if_t<std::is_base_of<To, From>::value>> {
static inline bool doit(const From &) { return true; }
};
@@ -133,24 +132,30 @@ struct isa_impl_wrap<To, FromTy, FromTy> {
}
};
-// isa<X> - Return true if the parameter to the template is an instance of the
-// template type argument. Used like this:
+// isa<X> - Return true if the parameter to the template is an instance of one
+// of the template type arguments. Used like this:
//
// if (isa<Type>(myVal)) { ... }
+// if (isa<Type0, Type1, Type2>(myVal)) { ... }
//
template <class X, class Y> LLVM_NODISCARD inline bool isa(const Y &Val) {
return isa_impl_wrap<X, const Y,
typename simplify_type<const Y>::SimpleType>::doit(Val);
}
+template <typename First, typename Second, typename... Rest, typename Y>
+LLVM_NODISCARD inline bool isa(const Y &Val) {
+ return isa<First>(Val) || isa<Second, Rest...>(Val);
+}
+
// isa_and_nonnull<X> - Functionally identical to isa, except that a null value
// is accepted.
//
-template <class X, class Y>
+template <typename... X, class Y>
LLVM_NODISCARD inline bool isa_and_nonnull(const Y &Val) {
if (!Val)
return false;
- return isa<X>(Val);
+ return isa<X...>(Val);
}
//===----------------------------------------------------------------------===//
@@ -184,7 +189,7 @@ template <class To, class From>
struct cast_retty_impl<To, std::unique_ptr<From>> {
private:
using PointerType = typename cast_retty_impl<To, From *>::ret_type;
- using ResultType = typename std::remove_pointer<PointerType>::type;
+ using ResultType = std::remove_pointer_t<PointerType>;
public:
using ret_type = std::unique_ptr<ResultType>;
@@ -244,8 +249,8 @@ template <class X> struct is_simple_type {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
+inline std::enable_if_t<!is_simple_type<Y>::value,
+ typename cast_retty<X, const Y>::ret_type>
cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<
@@ -280,10 +285,9 @@ cast(std::unique_ptr<Y> &&Val) {
// accepted.
//
template <class X, class Y>
-LLVM_NODISCARD inline
- typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
- cast_or_null(const Y &Val) {
+LLVM_NODISCARD inline std::enable_if_t<
+ !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>
+cast_or_null(const Y &Val) {
if (!Val)
return nullptr;
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
@@ -291,10 +295,9 @@ LLVM_NODISCARD inline
}
template <class X, class Y>
-LLVM_NODISCARD inline
- typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, Y>::ret_type>::type
- cast_or_null(Y &Val) {
+LLVM_NODISCARD inline std::enable_if_t<!is_simple_type<Y>::value,
+ typename cast_retty<X, Y>::ret_type>
+cast_or_null(Y &Val) {
if (!Val)
return nullptr;
assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
@@ -326,10 +329,9 @@ cast_or_null(std::unique_ptr<Y> &&Val) {
//
template <class X, class Y>
-LLVM_NODISCARD inline
- typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
- dyn_cast(const Y &Val) {
+LLVM_NODISCARD inline std::enable_if_t<
+ !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>
+dyn_cast(const Y &Val) {
return isa<X>(Val) ? cast<X>(Val) : nullptr;
}
@@ -347,18 +349,16 @@ LLVM_NODISCARD inline typename cast_retty<X, Y *>::ret_type dyn_cast(Y *Val) {
// value is accepted.
//
template <class X, class Y>
-LLVM_NODISCARD inline
- typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, const Y>::ret_type>::type
- dyn_cast_or_null(const Y &Val) {
+LLVM_NODISCARD inline std::enable_if_t<
+ !is_simple_type<Y>::value, typename cast_retty<X, const Y>::ret_type>
+dyn_cast_or_null(const Y &Val) {
return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
}
template <class X, class Y>
-LLVM_NODISCARD inline
- typename std::enable_if<!is_simple_type<Y>::value,
- typename cast_retty<X, Y>::ret_type>::type
- dyn_cast_or_null(Y &Val) {
+LLVM_NODISCARD inline std::enable_if_t<!is_simple_type<Y>::value,
+ typename cast_retty<X, Y>::ret_type>
+dyn_cast_or_null(Y &Val) {
return (Val && isa<X>(Val)) ? cast<X>(Val) : nullptr;
}
@@ -382,8 +382,7 @@ LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &Val)
}
template <class X, class Y>
-LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val)
- -> decltype(cast<X>(Val)) {
+LLVM_NODISCARD inline auto unique_dyn_cast(std::unique_ptr<Y> &&Val) {
return unique_dyn_cast<X, Y>(Val);
}
@@ -398,8 +397,7 @@ LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &Val)
}
template <class X, class Y>
-LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val)
- -> decltype(cast<X>(Val)) {
+LLVM_NODISCARD inline auto unique_dyn_cast_or_null(std::unique_ptr<Y> &&Val) {
return unique_dyn_cast_or_null<X, Y>(Val);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/CheckedArithmetic.h b/contrib/llvm-project/llvm/include/llvm/Support/CheckedArithmetic.h
index 8a50e3d5ddf6..035e4533322c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/CheckedArithmetic.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/CheckedArithmetic.h
@@ -25,8 +25,8 @@ namespace {
/// \p RHS.
/// \return Empty optional if the operation overflows, or result otherwise.
template <typename T, typename F>
-typename std::enable_if<std::is_integral<T>::value && sizeof(T) * 8 <= 64,
- llvm::Optional<T>>::type
+std::enable_if_t<std::is_integral<T>::value && sizeof(T) * 8 <= 64,
+ llvm::Optional<T>>
checkedOp(T LHS, T RHS, F Op, bool Signed = true) {
llvm::APInt ALHS(/*BitSize=*/sizeof(T) * 8, LHS, Signed);
llvm::APInt ARHS(/*BitSize=*/sizeof(T) * 8, RHS, Signed);
@@ -44,7 +44,7 @@ namespace llvm {
/// \return Optional of sum if no signed overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_signed<T>::value, llvm::Optional<T>>
checkedAdd(T LHS, T RHS) {
return checkedOp(LHS, RHS, &llvm::APInt::sadd_ov);
}
@@ -53,7 +53,7 @@ checkedAdd(T LHS, T RHS) {
/// \return Optional of sum if no signed overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_signed<T>::value, llvm::Optional<T>>
checkedSub(T LHS, T RHS) {
return checkedOp(LHS, RHS, &llvm::APInt::ssub_ov);
}
@@ -62,7 +62,7 @@ checkedSub(T LHS, T RHS) {
/// \return Optional of product if no signed overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_signed<T>::value, llvm::Optional<T>>
checkedMul(T LHS, T RHS) {
return checkedOp(LHS, RHS, &llvm::APInt::smul_ov);
}
@@ -71,7 +71,7 @@ checkedMul(T LHS, T RHS) {
/// \return Optional of result if no signed overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_signed<T>::value, llvm::Optional<T>>
checkedMulAdd(T A, T B, T C) {
if (auto Product = checkedMul(A, B))
return checkedAdd(*Product, C);
@@ -82,7 +82,7 @@ checkedMulAdd(T A, T B, T C) {
/// \return Optional of sum if no unsigned overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_unsigned<T>::value, llvm::Optional<T>>
checkedAddUnsigned(T LHS, T RHS) {
return checkedOp(LHS, RHS, &llvm::APInt::uadd_ov, /*Signed=*/false);
}
@@ -91,7 +91,7 @@ checkedAddUnsigned(T LHS, T RHS) {
/// \return Optional of product if no unsigned overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_unsigned<T>::value, llvm::Optional<T>>
checkedMulUnsigned(T LHS, T RHS) {
return checkedOp(LHS, RHS, &llvm::APInt::umul_ov, /*Signed=*/false);
}
@@ -100,7 +100,7 @@ checkedMulUnsigned(T LHS, T RHS) {
/// \return Optional of result if no unsigned overflow occurred,
/// \c None otherwise.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, llvm::Optional<T>>::type
+std::enable_if_t<std::is_unsigned<T>::value, llvm::Optional<T>>
checkedMulAddUnsigned(T A, T B, T C) {
if (auto Product = checkedMulUnsigned(A, B))
return checkedAddUnsigned(*Product, C);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Chrono.h b/contrib/llvm-project/llvm/include/llvm/Support/Chrono.h
index 334ab60835a4..098512dce783 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Chrono.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Chrono.h
@@ -112,8 +112,8 @@ template <typename Rep, typename Period>
struct format_provider<std::chrono::duration<Rep, Period>> {
private:
typedef std::chrono::duration<Rep, Period> Dur;
- typedef typename std::conditional<
- std::chrono::treat_as_floating_point<Rep>::value, double, intmax_t>::type
+ typedef std::conditional_t<std::chrono::treat_as_floating_point<Rep>::value,
+ double, intmax_t>
InternalRep;
template <typename AsPeriod> static InternalRep getAs(const Dur &D) {
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/CommandLine.h b/contrib/llvm-project/llvm/include/llvm/Support/CommandLine.h
index 05374e34aa7d..466945e40a9c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/CommandLine.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/CommandLine.h
@@ -45,7 +45,6 @@
namespace llvm {
class StringSaver;
-class raw_ostream;
/// cl Namespace - This namespace contains all of the command line option
/// processing machinery. It is intentionally a short name to make qualified
@@ -488,14 +487,13 @@ struct callback_traits : public callback_traits<decltype(&F::operator())> {};
template <typename R, typename C, typename... Args>
struct callback_traits<R (C::*)(Args...) const> {
using result_type = R;
- using arg_type = typename std::tuple_element<0, std::tuple<Args...>>::type;
+ using arg_type = std::tuple_element_t<0, std::tuple<Args...>>;
static_assert(sizeof...(Args) == 1, "callback function must have one and only one parameter");
static_assert(std::is_same<result_type, void>::value,
"callback return type must be void");
- static_assert(
- std::is_lvalue_reference<arg_type>::value &&
- std::is_const<typename std::remove_reference<arg_type>::type>::value,
- "callback arg_type must be a const lvalue reference");
+ static_assert(std::is_lvalue_reference<arg_type>::value &&
+ std::is_const<std::remove_reference_t<arg_type>>::value,
+ "callback arg_type must be a const lvalue reference");
};
} // namespace detail
@@ -1453,16 +1451,16 @@ class opt : public Option,
}
}
- template <class T, class = typename std::enable_if<
- std::is_assignable<T&, T>::value>::type>
+ template <class T,
+ class = std::enable_if_t<std::is_assignable<T &, T>::value>>
void setDefaultImpl() {
const OptionValue<DataType> &V = this->getDefault();
if (V.hasValue())
this->setValue(V.getValue());
}
- template <class T, class = typename std::enable_if<
- !std::is_assignable<T&, T>::value>::type>
+ template <class T,
+ class = std::enable_if_t<!std::is_assignable<T &, T>::value>>
void setDefaultImpl(...) {}
void setDefault() override { setDefaultImpl<DataType>(); }
@@ -1607,8 +1605,8 @@ public:
reference front() { return Storage.front(); }
const_reference front() const { return Storage.front(); }
- operator std::vector<DataType>&() { return Storage; }
- operator ArrayRef<DataType>() { return Storage; }
+ operator std::vector<DataType> &() { return Storage; }
+ operator ArrayRef<DataType>() const { return Storage; }
std::vector<DataType> *operator&() { return &Storage; }
const std::vector<DataType> *operator&() const { return &Storage; }
@@ -2028,6 +2026,13 @@ void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
SmallVectorImpl<const char *> &NewArgv,
bool MarkEOLs = false);
+/// Tokenizes a Windows command line while attempting to avoid copies. If no
+/// quoting or escaping was used, this produces substrings of the original
+/// string. If a token requires unquoting, it will be allocated with the
+/// StringSaver.
+void TokenizeWindowsCommandLineNoCopy(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<StringRef> &NewArgv);
+
/// String tokenization function type. Should be compatible with either
/// Windows or Unix command line tokenizers.
using TokenizerCallback = void (*)(StringRef Source, StringSaver &Saver,
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Compiler.h b/contrib/llvm-project/llvm/include/llvm/Support/Compiler.h
index 6f6f65cad6f5..80ea76240d6c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Compiler.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Compiler.h
@@ -95,7 +95,8 @@
/// Does the compiler support ref-qualifiers for *this?
///
/// Sadly, this is separate from just rvalue reference support because GCC
-/// and MSVC implemented this later than everything else.
+/// and MSVC implemented this later than everything else. This appears to be
+/// corrected in MSVC 2019 but not MSVC 2017.
#if __has_feature(cxx_rvalue_references) || LLVM_GNUC_PREREQ(4, 8, 1)
#define LLVM_HAS_RVALUE_REFERENCE_THIS 1
#else
@@ -288,6 +289,22 @@
#define LLVM_REQUIRE_CONSTANT_INITIALIZATION
#endif
+/// LLVM_GSL_OWNER - Apply this to owning classes like SmallVector to enable
+/// lifetime warnings.
+#if LLVM_HAS_CPP_ATTRIBUTE(gsl::Owner)
+#define LLVM_GSL_OWNER [[gsl::Owner]]
+#else
+#define LLVM_GSL_OWNER
+#endif
+
+/// LLVM_GSL_POINTER - Apply this to non-owning classes like
+/// StringRef to enable lifetime warnings.
+#if LLVM_HAS_CPP_ATTRIBUTE(gsl::Pointer)
+#define LLVM_GSL_POINTER [[gsl::Pointer]]
+#else
+#define LLVM_GSL_POINTER
+#endif
+
/// LLVM_EXTENSION - Support compilers where we have a keyword to suppress
/// pedantic diagnostics.
#ifdef __GNUC__
@@ -356,7 +373,6 @@
#if __has_builtin(__builtin_assume_aligned) || LLVM_GNUC_PREREQ(4, 7, 0)
# define LLVM_ASSUME_ALIGNED(p, a) __builtin_assume_aligned(p, a)
#elif defined(LLVM_BUILTIN_UNREACHABLE)
-// As of today, clang does not support __builtin_assume_aligned.
# define LLVM_ASSUME_ALIGNED(p, a) \
(((uintptr_t(p) % (a)) == 0) ? (p) : (LLVM_BUILTIN_UNREACHABLE, (p)))
#else
@@ -542,48 +558,4 @@ void AnnotateIgnoreWritesEnd(const char *file, int line);
#define LLVM_ENABLE_EXCEPTIONS 1
#endif
-#ifdef __cplusplus
-namespace llvm {
-
-/// Allocate a buffer of memory with the given size and alignment.
-///
-/// When the compiler supports aligned operator new, this will use it to to
-/// handle even over-aligned allocations.
-///
-/// However, this doesn't make any attempt to leverage the fancier techniques
-/// like posix_memalign due to portability. It is mostly intended to allow
-/// compatibility with platforms that, after aligned allocation was added, use
-/// reduced default alignment.
-inline void *allocate_buffer(size_t Size, size_t Alignment) {
- return ::operator new(Size
-#ifdef __cpp_aligned_new
- ,
- std::align_val_t(Alignment)
-#endif
- );
-}
-
-/// Deallocate a buffer of memory with the given size and alignment.
-///
-/// If supported, this will used the sized delete operator. Also if supported,
-/// this will pass the alignment to the delete operator.
-///
-/// The pointer must have been allocated with the corresponding new operator,
-/// most likely using the above helper.
-inline void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment) {
- ::operator delete(Ptr
-#ifdef __cpp_sized_deallocation
- ,
- Size
-#endif
-#ifdef __cpp_aligned_new
- ,
- std::align_val_t(Alignment)
-#endif
- );
-}
-
-} // End namespace llvm
-
-#endif // __cplusplus
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/DataExtractor.h b/contrib/llvm-project/llvm/include/llvm/Support/DataExtractor.h
index 0be478811b22..f9335c161563 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/DataExtractor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/DataExtractor.h
@@ -105,19 +105,32 @@ public:
/// updated with the offset of the byte that follows the NULL
/// terminator byte.
///
- /// @param[in,out] offset_ptr
+ /// @param[in,out] OffsetPtr
/// A pointer to an offset within the data that will be advanced
/// by the appropriate number of bytes if the value is extracted
/// correctly. If the offset is out of bounds or there are not
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
+ /// @param[in,out] Err
+ /// A pointer to an Error object. Upon return the Error object is set to
+ /// indicate the result (success/failure) of the function. If the Error
+ /// object is already set when calling this function, no extraction is
+ /// performed.
+ ///
/// @return
/// A pointer to the C string value in the data. If the offset
/// pointed to by \a offset_ptr is out of bounds, or if the
/// offset plus the length of the C string is out of bounds,
/// NULL will be returned.
- const char *getCStr(uint64_t *offset_ptr) const;
+ const char *getCStr(uint64_t *OffsetPtr, Error *Err = nullptr) const {
+ return getCStrRef(OffsetPtr, Err).data();
+ }
+
+ /// Extract a C string from the location given by the cursor. In case of an
+ /// extraction error, or if the cursor is already in an error state, a
+ /// nullptr is returned.
+ const char *getCStr(Cursor &C) const { return getCStrRef(C).data(); }
/// Extract a C string from \a *offset_ptr.
///
@@ -127,19 +140,102 @@ public:
/// updated with the offset of the byte that follows the NULL
/// terminator byte.
///
- /// \param[in,out] offset_ptr
+ /// \param[in,out] OffsetPtr
/// A pointer to an offset within the data that will be advanced
/// by the appropriate number of bytes if the value is extracted
/// correctly. If the offset is out of bounds or there are not
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
+ /// @param[in,out] Err
+ /// A pointer to an Error object. Upon return the Error object is set to
+ /// indicate the result (success/failure) of the function. If the Error
+ /// object is already set when calling this function, no extraction is
+ /// performed.
+ ///
/// \return
/// A StringRef for the C string value in the data. If the offset
/// pointed to by \a offset_ptr is out of bounds, or if the
/// offset plus the length of the C string is out of bounds,
/// a default-initialized StringRef will be returned.
- StringRef getCStrRef(uint64_t *offset_ptr) const;
+ StringRef getCStrRef(uint64_t *OffsetPtr, Error *Err = nullptr) const;
+
+ /// Extract a C string (as a StringRef) from the location given by the cursor.
+ /// In case of an extraction error, or if the cursor is already in an error
+ /// state, a default-initialized StringRef is returned.
+ StringRef getCStrRef(Cursor &C) const {
+ return getCStrRef(&C.Offset, &C.Err);
+ }
+
+ /// Extract a fixed length string from \a *OffsetPtr and consume \a Length
+ /// bytes.
+ ///
+ /// Returns a StringRef for the string from the data at the offset
+ /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
+ /// and the \a OffsetPtr will be advanced by \a Length bytes.
+ ///
+ /// \param[in,out] OffsetPtr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// \param[in] Length
+ /// The length of the fixed length string to extract. If there are not
+ /// enough bytes in the data to extract the full string, the offset will
+ /// be left unmodified.
+ ///
+ /// \param[in] TrimChars
+ /// A set of characters to trim from the end of the string. Fixed length
+ /// strings are commonly either NULL terminated by one or more zero
+ /// bytes. Some clients have one or more spaces at the end of the string,
+ /// but a good default is to trim the NULL characters.
+ ///
+ /// \return
+ /// A StringRef for the C string value in the data. If the offset
+ /// pointed to by \a OffsetPtr is out of bounds, or if the
+ /// offset plus the length of the C string is out of bounds,
+ /// a default-initialized StringRef will be returned.
+ StringRef getFixedLengthString(uint64_t *OffsetPtr,
+ uint64_t Length, StringRef TrimChars = {"\0", 1}) const;
+
+ /// Extract a fixed number of bytes from the specified offset.
+ ///
+ /// Returns a StringRef for the bytes from the data at the offset
+ /// pointed to by \a OffsetPtr. A fixed length C string will be extracted
+ /// and the \a OffsetPtr will be advanced by \a Length bytes.
+ ///
+ /// \param[in,out] OffsetPtr
+ /// A pointer to an offset within the data that will be advanced
+ /// by the appropriate number of bytes if the value is extracted
+ /// correctly. If the offset is out of bounds or there are not
+ /// enough bytes to extract this value, the offset will be left
+ /// unmodified.
+ ///
+ /// \param[in] Length
+ /// The number of bytes to extract. If there are not enough bytes in the
+ /// data to extract all of the bytes, the offset will be left unmodified.
+ ///
+ /// @param[in,out] Err
+ /// A pointer to an Error object. Upon return the Error object is set to
+ /// indicate the result (success/failure) of the function. If the Error
+ /// object is already set when calling this function, no extraction is
+ /// performed.
+ ///
+ /// \return
+ /// A StringRef for the extracted bytes. If the offset pointed to by
+ /// \a OffsetPtr is out of bounds, or if the offset plus the length
+ /// is out of bounds, a default-initialized StringRef will be returned.
+ StringRef getBytes(uint64_t *OffsetPtr, uint64_t Length,
+ Error *Err = nullptr) const;
+
+ /// Extract a fixed number of bytes from the location given by the cursor. In
+ /// case of an extraction error, or if the cursor is already in an error
+ /// state, a default-initialized StringRef is returned.
+ StringRef getBytes(Cursor &C, uint64_t Length) {
+ return getBytes(&C.Offset, Length, &C.Err);
+ }
/// Extract an unsigned integer of size \a byte_size from \a
/// *offset_ptr.
@@ -365,15 +461,26 @@ public:
/// \a offset_ptr, construct a uint32_t from them and update the offset
/// on success.
///
- /// @param[in,out] offset_ptr
+ /// @param[in,out] OffsetPtr
/// A pointer to an offset within the data that will be advanced
/// by the 3 bytes if the value is extracted correctly. If the offset
/// is out of bounds or there are not enough bytes to extract this value,
/// the offset will be left unmodified.
///
+ /// @param[in,out] Err
+ /// A pointer to an Error object. Upon return the Error object is set to
+ /// indicate the result (success/failure) of the function. If the Error
+ /// object is already set when calling this function, no extraction is
+ /// performed.
+ ///
/// @return
/// The extracted 24-bit value represented in a uint32_t.
- uint32_t getU24(uint64_t *offset_ptr) const;
+ uint32_t getU24(uint64_t *OffsetPtr, Error *Err = nullptr) const;
+
+ /// Extract a single 24-bit unsigned value from the location given by the
+ /// cursor. In case of an extraction error, or if the cursor is already in an
+ /// error state, zero is returned.
+ uint32_t getU24(Cursor &C) const { return getU24(&C.Offset, &C.Err); }
/// Extract a uint32_t value from \a *offset_ptr.
///
@@ -486,16 +593,27 @@ public:
/// pointed to by \a offset_ptr will be updated with the offset of
/// the byte following the last extracted byte.
///
- /// @param[in,out] offset_ptr
+ /// @param[in,out] OffsetPtr
/// A pointer to an offset within the data that will be advanced
/// by the appropriate number of bytes if the value is extracted
/// correctly. If the offset is out of bounds or there are not
/// enough bytes to extract this value, the offset will be left
/// unmodified.
///
+ /// @param[in,out] Err
+ /// A pointer to an Error object. Upon return the Error object is set to
+ /// indicate the result (success/failure) of the function. If the Error
+ /// object is already set when calling this function, no extraction is
+ /// performed.
+ ///
/// @return
/// The extracted signed integer value.
- int64_t getSLEB128(uint64_t *offset_ptr) const;
+ int64_t getSLEB128(uint64_t *OffsetPtr, Error *Err = nullptr) const;
+
+ /// Extract an signed LEB128 value from the location given by the cursor.
+ /// In case of an extraction error, or if the cursor is already in an error
+ /// state, zero is returned.
+ int64_t getSLEB128(Cursor &C) const { return getSLEB128(&C.Offset, &C.Err); }
/// Extract a unsigned LEB128 value from \a *offset_ptr.
///
@@ -521,7 +639,7 @@ public:
/// The extracted unsigned integer value.
uint64_t getULEB128(uint64_t *offset_ptr, llvm::Error *Err = nullptr) const;
- /// Extract an unsigned ULEB128 value from the location given by the cursor.
+ /// Extract an unsigned LEB128 value from the location given by the cursor.
/// In case of an extraction error, or if the cursor is already in an error
/// state, zero is returned.
uint64_t getULEB128(Cursor &C) const { return getULEB128(&C.Offset, &C.Err); }
@@ -571,6 +689,16 @@ protected:
// public.
static uint64_t &getOffset(Cursor &C) { return C.Offset; }
static Error &getError(Cursor &C) { return C.Err; }
+
+private:
+ /// If it is possible to read \a Size bytes at offset \a Offset, returns \b
+ /// true. Otherwise, returns \b false. If \a E is not nullptr, also sets the
+ /// error object to indicate an error.
+ bool prepareRead(uint64_t Offset, uint64_t Size, Error *E) const;
+
+ template <typename T> T getU(uint64_t *OffsetPtr, Error *Err) const;
+ template <typename T>
+ T *getUs(uint64_t *OffsetPtr, T *Dst, uint32_t Count, Error *Err) const;
};
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/DebugCounter.h b/contrib/llvm-project/llvm/include/llvm/Support/DebugCounter.h
index e7d1fa68f21a..cd9474a4d918 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/DebugCounter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/DebugCounter.h
@@ -44,14 +44,15 @@
#define LLVM_SUPPORT_DEBUGCOUNTER_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/UniqueVector.h"
-#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
#include <string>
namespace llvm {
+class raw_ostream;
+
class DebugCounter {
public:
~DebugCounter();
@@ -68,7 +69,7 @@ public:
// line option parsing. The main reason to register counters is to produce a
// nice list of them on the command line, but i'm not sure this is worth it.
static unsigned registerCounter(StringRef Name, StringRef Desc) {
- return instance().addCounter(Name, Desc);
+ return instance().addCounter(std::string(Name), std::string(Desc));
}
inline static bool shouldExecute(unsigned CounterName) {
if (!isCountingEnabled())
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributeParser.h b/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributeParser.h
new file mode 100644
index 000000000000..8bf87b2d84f0
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributeParser.h
@@ -0,0 +1,72 @@
+//===- ELF AttributeParser.h - ELF Attribute Parser -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
+#define LLVM_SUPPORT_ELFATTRIBUTEPARSER_H
+
+#include "ELFAttributes.h"
+#include "ScopedPrinter.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Error.h"
+
+#include <unordered_map>
+
+namespace llvm {
+class StringRef;
+
+class ELFAttributeParser {
+ StringRef vendor;
+ std::unordered_map<unsigned, unsigned> attributes;
+ std::unordered_map<unsigned, StringRef> attributesStr;
+
+ virtual Error handler(uint64_t tag, bool &handled) = 0;
+
+protected:
+ ScopedPrinter *sw;
+ TagNameMap tagToStringMap;
+ DataExtractor de{ArrayRef<uint8_t>{}, true, 0};
+ DataExtractor::Cursor cursor{0};
+
+ void printAttribute(unsigned tag, unsigned value, StringRef valueDesc);
+
+ Error parseStringAttribute(const char *name, unsigned tag,
+ ArrayRef<const char *> strings);
+ Error parseAttributeList(uint32_t length);
+ void parseIndexList(SmallVectorImpl<uint8_t> &indexList);
+ Error parseSubsection(uint32_t length);
+
+public:
+ virtual ~ELFAttributeParser() { static_cast<void>(!cursor.takeError()); }
+ Error integerAttribute(unsigned tag);
+ Error stringAttribute(unsigned tag);
+
+ ELFAttributeParser(ScopedPrinter *sw, TagNameMap tagNameMap, StringRef vendor)
+ : vendor(vendor), sw(sw), tagToStringMap(tagNameMap) {}
+
+ ELFAttributeParser(TagNameMap tagNameMap, StringRef vendor)
+ : vendor(vendor), sw(nullptr), tagToStringMap(tagNameMap) {}
+
+ Error parse(ArrayRef<uint8_t> section, support::endianness endian);
+
+ Optional<unsigned> getAttributeValue(unsigned tag) const {
+ auto I = attributes.find(tag);
+ if (I == attributes.end())
+ return None;
+ return I->second;
+ }
+ Optional<StringRef> getAttributeString(unsigned tag) const {
+ auto I = attributesStr.find(tag);
+ if (I == attributesStr.end())
+ return None;
+ return I->second;
+ }
+};
+
+} // namespace llvm
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributes.h b/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributes.h
new file mode 100644
index 000000000000..c8a7ae142b9a
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ELFAttributes.h
@@ -0,0 +1,37 @@
+//===-- ELFAttributes.h - ELF Attributes ------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELFATTRIBUTES_H
+#define LLVM_SUPPORT_ELFATTRIBUTES_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+struct TagNameItem {
+ unsigned attr;
+ StringRef tagName;
+};
+
+using TagNameMap = ArrayRef<TagNameItem>;
+
+namespace ELFAttrs {
+
+enum AttrType : unsigned { File = 1, Section = 2, Symbol = 3 };
+
+StringRef attrTypeAsString(unsigned attr, TagNameMap tagNameMap,
+ bool hasTagPrefix = true);
+Optional<unsigned> attrTypeFromString(StringRef tag, TagNameMap tagNameMap);
+
+// Magic numbers for ELF attributes.
+enum AttrMagic { Format_Version = 0x41 };
+
+} // namespace ELFAttrs
+} // namespace llvm
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Endian.h b/contrib/llvm-project/llvm/include/llvm/Support/Endian.h
index 87aecedd3a4b..5e7c1e961b9d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Endian.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Endian.h
@@ -13,9 +13,7 @@
#ifndef LLVM_SUPPORT_ENDIAN_H
#define LLVM_SUPPORT_ENDIAN_H
-#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/SwapByteOrder.h"
#include <cassert>
#include <cstddef>
@@ -111,7 +109,7 @@ inline void write(void *memory, value_type value) {
}
template <typename value_type>
-using make_unsigned_t = typename std::make_unsigned<value_type>::type;
+using make_unsigned_t = std::make_unsigned_t<value_type>;
/// Read a value of a particular endianness from memory, for a location
/// that starts at the given bit offset within the first byte.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Errno.h b/contrib/llvm-project/llvm/include/llvm/Support/Errno.h
index aedb5fb292b8..dc3b3322ed98 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Errno.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Errno.h
@@ -30,8 +30,8 @@ std::string StrError();
std::string StrError(int errnum);
template <typename FailT, typename Fun, typename... Args>
-inline auto RetryAfterSignal(const FailT &Fail, const Fun &F,
- const Args &... As) -> decltype(F(As...)) {
+inline decltype(auto) RetryAfterSignal(const FailT &Fail, const Fun &F,
+ const Args &... As) {
decltype(F(As...)) Res;
do {
errno = 0;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Error.h b/contrib/llvm-project/llvm/include/llvm/Support/Error.h
index 44676338808b..9dd1bb7cb96d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Error.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Error.h
@@ -269,9 +269,13 @@ private:
}
ErrorInfoBase *getPtr() const {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
return reinterpret_cast<ErrorInfoBase*>(
reinterpret_cast<uintptr_t>(Payload) &
~static_cast<uintptr_t>(0x1));
+#else
+ return Payload;
+#endif
}
void setPtr(ErrorInfoBase *EI) {
@@ -294,10 +298,12 @@ private:
}
void setChecked(bool V) {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
Payload = reinterpret_cast<ErrorInfoBase*>(
(reinterpret_cast<uintptr_t>(Payload) &
~static_cast<uintptr_t>(0x1)) |
(V ? 0 : 1));
+#endif
}
std::unique_ptr<ErrorInfoBase> takePayload() {
@@ -434,21 +440,21 @@ template <class T> class LLVM_NODISCARD Expected {
template <class T1> friend class ExpectedAsOutParameter;
template <class OtherT> friend class Expected;
- static const bool isRef = std::is_reference<T>::value;
+ static constexpr bool isRef = std::is_reference<T>::value;
- using wrap = std::reference_wrapper<typename std::remove_reference<T>::type>;
+ using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
using error_type = std::unique_ptr<ErrorInfoBase>;
public:
- using storage_type = typename std::conditional<isRef, wrap, T>::type;
+ using storage_type = std::conditional_t<isRef, wrap, T>;
using value_type = T;
private:
- using reference = typename std::remove_reference<T>::type &;
- using const_reference = const typename std::remove_reference<T>::type &;
- using pointer = typename std::remove_reference<T>::type *;
- using const_pointer = const typename std::remove_reference<T>::type *;
+ using reference = std::remove_reference_t<T> &;
+ using const_reference = const std::remove_reference_t<T> &;
+ using pointer = std::remove_reference_t<T> *;
+ using const_pointer = const std::remove_reference_t<T> *;
public:
/// Create an Expected<T> error value from the given Error.
@@ -472,12 +478,12 @@ public:
/// must be convertible to T.
template <typename OtherT>
Expected(OtherT &&Val,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
- * = nullptr)
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
: HasError(false)
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
// Expected is unchecked upon construction in Debug builds.
- , Unchecked(true)
+ ,
+ Unchecked(true)
#endif
{
new (getStorage()) storage_type(std::forward<OtherT>(Val));
@@ -489,9 +495,9 @@ public:
/// Move construct an Expected<T> value from an Expected<OtherT>, where OtherT
/// must be convertible to T.
template <class OtherT>
- Expected(Expected<OtherT> &&Other,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
- * = nullptr) {
+ Expected(
+ Expected<OtherT> &&Other,
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) {
moveConstruct(std::move(Other));
}
@@ -500,8 +506,7 @@ public:
template <class OtherT>
explicit Expected(
Expected<OtherT> &&Other,
- typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
- nullptr) {
+ std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) {
moveConstruct(std::move(Other));
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h b/contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h
index f75c2984a9ff..7cbc668b3a0e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ErrorHandling.h
@@ -66,7 +66,7 @@ class StringRef;
///
/// If no error handler is installed the default is to print the message to
/// standard error, followed by a newline.
-/// After the error handler is called this function will call exit(1), it
+/// After the error handler is called this function will call abort(), it
/// does not return.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason,
bool gen_crash_diag = true);
@@ -103,8 +103,8 @@ void install_out_of_memory_new_handler();
/// Reports a bad alloc error, calling any user defined bad alloc
/// error handler. In contrast to the generic 'report_fatal_error'
-/// functions, this function is expected to return, e.g. the user
-/// defined error handler throws an exception.
+/// functions, this function might not terminate, e.g. the user
+/// defined error handler throws an exception, but it won't return.
///
/// Note: When throwing an exception in the bad alloc handler, make sure that
/// the following unwind succeeds, e.g. do not trigger additional allocations
@@ -113,7 +113,8 @@ void install_out_of_memory_new_handler();
/// If no error handler is installed (default), then a bad_alloc exception
/// is thrown, if LLVM is compiled with exception support, otherwise an
/// assertion is called.
-void report_bad_alloc_error(const char *Reason, bool GenCrashDiag = true);
+LLVM_ATTRIBUTE_NORETURN void report_bad_alloc_error(const char *Reason,
+ bool GenCrashDiag = true);
/// This function calls abort(), and prints the optional message to stderr.
/// Use the llvm_unreachable macro (that adds location info), instead of
@@ -127,7 +128,7 @@ llvm_unreachable_internal(const char *msg = nullptr, const char *file = nullptr,
/// In !NDEBUG builds, prints the message and location info to stderr.
/// In NDEBUG builds, becomes an optimizer hint that the current location
/// is not supposed to be reachable. On compilers that don't support
-/// such hints, prints a reduced message instead.
+/// such hints, prints a reduced message instead and aborts the program.
///
/// Use this instead of assert(0). It conveys intent more clearly and
/// allows compilers to omit some unnecessary code.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ErrorOr.h b/contrib/llvm-project/llvm/include/llvm/Support/ErrorOr.h
index 8211f4d8a098..1fbccc1d1e26 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ErrorOr.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ErrorOr.h
@@ -56,25 +56,25 @@ template<class T>
class ErrorOr {
template <class OtherT> friend class ErrorOr;
- static const bool isRef = std::is_reference<T>::value;
+ static constexpr bool isRef = std::is_reference<T>::value;
- using wrap = std::reference_wrapper<typename std::remove_reference<T>::type>;
+ using wrap = std::reference_wrapper<std::remove_reference_t<T>>;
public:
- using storage_type = typename std::conditional<isRef, wrap, T>::type;
+ using storage_type = std::conditional_t<isRef, wrap, T>;
private:
- using reference = typename std::remove_reference<T>::type &;
- using const_reference = const typename std::remove_reference<T>::type &;
- using pointer = typename std::remove_reference<T>::type *;
- using const_pointer = const typename std::remove_reference<T>::type *;
+ using reference = std::remove_reference_t<T> &;
+ using const_reference = const std::remove_reference_t<T> &;
+ using pointer = std::remove_reference_t<T> *;
+ using const_pointer = const std::remove_reference_t<T> *;
public:
template <class E>
ErrorOr(E ErrorCode,
- typename std::enable_if<std::is_error_code_enum<E>::value ||
- std::is_error_condition_enum<E>::value,
- void *>::type = nullptr)
+ std::enable_if_t<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ void *> = nullptr)
: HasError(true) {
new (getErrorStorage()) std::error_code(make_error_code(ErrorCode));
}
@@ -85,8 +85,7 @@ public:
template <class OtherT>
ErrorOr(OtherT &&Val,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type
- * = nullptr)
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
: HasError(false) {
new (getStorage()) storage_type(std::forward<OtherT>(Val));
}
@@ -96,18 +95,16 @@ public:
}
template <class OtherT>
- ErrorOr(
- const ErrorOr<OtherT> &Other,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
- nullptr) {
+ ErrorOr(const ErrorOr<OtherT> &Other,
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) {
copyConstruct(Other);
}
template <class OtherT>
explicit ErrorOr(
const ErrorOr<OtherT> &Other,
- typename std::enable_if<
- !std::is_convertible<OtherT, const T &>::value>::type * = nullptr) {
+ std::enable_if_t<!std::is_convertible<OtherT, const T &>::value> * =
+ nullptr) {
copyConstruct(Other);
}
@@ -116,10 +113,8 @@ public:
}
template <class OtherT>
- ErrorOr(
- ErrorOr<OtherT> &&Other,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
- nullptr) {
+ ErrorOr(ErrorOr<OtherT> &&Other,
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr) {
moveConstruct(std::move(Other));
}
@@ -128,8 +123,7 @@ public:
template <class OtherT>
explicit ErrorOr(
ErrorOr<OtherT> &&Other,
- typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
- nullptr) {
+ std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr) {
moveConstruct(std::move(Other));
}
@@ -266,9 +260,9 @@ private:
};
template <class T, class E>
-typename std::enable_if<std::is_error_code_enum<E>::value ||
- std::is_error_condition_enum<E>::value,
- bool>::type
+std::enable_if_t<std::is_error_code_enum<E>::value ||
+ std::is_error_condition_enum<E>::value,
+ bool>
operator==(const ErrorOr<T> &Err, E Code) {
return Err.getError() == Code;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ExtensibleRTTI.h b/contrib/llvm-project/llvm/include/llvm/Support/ExtensibleRTTI.h
new file mode 100644
index 000000000000..6b8510ce759f
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ExtensibleRTTI.h
@@ -0,0 +1,135 @@
+//===-- llvm/Support/ExtensibleRTTI.h - ExtensibleRTTI support --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+//
+// Defines an extensible RTTI mechanism designed to work with Casting.h.
+//
+// Extensible RTTI differs from LLVM's primary RTTI mechanism (see
+// llvm.org/docs/HowToSetUpLLVMStyleRTTI.html) by supporting open type
+// hierarchies, where new types can be added from outside libraries without
+// needing to change existing code. LLVM's primary RTTI mechanism should be
+// preferred where possible, but where open hierarchies are needed this system
+// can be used.
+//
+// The RTTIRoot class defines methods for comparing type ids. Implementations
+// of these methods can be injected into new classes using the RTTIExtends
+// class template.
+//
+// E.g.
+//
+// @code{.cpp}
+// class MyBaseClass : public RTTIExtends<MyBaseClass, RTTIRoot> {
+// public:
+// static char ID;
+// virtual void foo() = 0;
+// };
+//
+// class MyDerivedClass1 : public RTTIExtends<MyDerivedClass1, MyBaseClass> {
+// public:
+// static char ID;
+// void foo() override {}
+// };
+//
+// class MyDerivedClass2 : public RTTIExtends<MyDerivedClass2, MyBaseClass> {
+// public:
+// static char ID;
+// void foo() override {}
+// };
+//
+// char MyBaseClass::ID = 0;
+// char MyDerivedClass1::ID = 0;
+// char MyDerivedClass2:: ID = 0;
+//
+// void fn() {
+// std::unique_ptr<MyBaseClass> B = llvm::make_unique<MyDerivedClass1>();
+// llvm::outs() << isa<MyBaseClass>(B) << "\n"; // Outputs "1".
+// llvm::outs() << isa<MyDerivedClass1>(B) << "\n"; // Outputs "1".
+// llvm::outs() << isa<MyDerivedClass2>(B) << "\n"; // Outputs "0'.
+// }
+//
+// @endcode
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_EXTENSIBLERTTI_H
+#define LLVM_SUPPORT_EXTENSIBLERTTI_H
+
+namespace llvm {
+
+template <typename ThisT, typename ParentT> class RTTIExtends;
+
+/// Base class for the extensible RTTI hierarchy.
+///
+/// This class defines virtual methods, dynamicClassID and isA, that enable
+/// type comparisons.
+class RTTIRoot {
+public:
+ virtual ~RTTIRoot() = default;
+
+ /// Returns the class ID for this type.
+ static const void *classID() { return &ID; }
+
+ /// Returns the class ID for the dynamic type of this RTTIRoot instance.
+ virtual const void *dynamicClassID() const = 0;
+
+ /// Returns true if this class's ID matches the given class ID.
+ virtual bool isA(const void *const ClassID) const {
+ return ClassID == classID();
+ }
+
+ /// Check whether this instance is a subclass of QueryT.
+ template <typename QueryT>
+ bool isA() const { return isA(QueryT::classID()); }
+
+private:
+ virtual void anchor();
+
+ static char ID;
+};
+
+/// Inheritance utility for extensible RTTI.
+///
+/// Supports single inheritance only: A class can only have one
+/// ExtensibleRTTI-parent (i.e. a parent for which the isa<> test will work),
+/// though it can have many non-ExtensibleRTTI parents.
+///
+/// RTTIExtents uses CRTP so the first template argument to RTTIExtends is the
+/// newly introduced type, and the *second* argument is the parent class.
+///
+/// class MyType : public RTTIExtends<MyType, RTTIRoot> {
+/// public:
+/// static char ID;
+/// };
+///
+/// class MyDerivedType : public RTTIExtends<MyDerivedType, MyType> {
+/// public:
+/// static char ID;
+/// };
+///
+template <typename ThisT, typename ParentT>
+class RTTIExtends : public ParentT {
+public:
+ // Inherit constructors from ParentT.
+ using ParentT::ParentT;
+
+ static const void *classID() { return &ThisT::ID; }
+
+ const void *dynamicClassID() const override { return &ThisT::ID; }
+
+ bool isA(const void *const ClassID) const override {
+ return ClassID == classID() || ParentT::isA(ClassID);
+ }
+
+ static bool classof(const RTTIRoot *R) { return R->isA<ThisT>(); }
+};
+
+} // end namespace llvm
+
+#endif // LLVM_SUPPORT_EXTENSIBLERTTI_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FileCheck.h b/contrib/llvm-project/llvm/include/llvm/Support/FileCheck.h
index 429e36cfcbb5..2f0e641394d5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FileCheck.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FileCheck.h
@@ -24,13 +24,15 @@ namespace llvm {
/// Contains info about various FileCheck options.
struct FileCheckRequest {
- std::vector<std::string> CheckPrefixes;
+ std::vector<StringRef> CheckPrefixes;
+ std::vector<StringRef> CommentPrefixes;
bool NoCanonicalizeWhiteSpace = false;
- std::vector<std::string> ImplicitCheckNot;
- std::vector<std::string> GlobalDefines;
+ std::vector<StringRef> ImplicitCheckNot;
+ std::vector<StringRef> GlobalDefines;
bool AllowEmptyInput = false;
bool MatchFullLines = false;
bool IgnoreCase = false;
+ bool IsDefaultCheckPrefix = false;
bool EnableVarScope = false;
bool AllowDeprecatedDagOverlap = false;
bool Verbose = false;
@@ -52,6 +54,7 @@ enum FileCheckKind {
CheckDAG,
CheckLabel,
CheckEmpty,
+ CheckComment,
/// Indicates the pattern only matches the end of file. This is used for
/// trailing CHECK-NOTs.
@@ -87,7 +90,7 @@ struct FileCheckDiag {
/// What is the FileCheck directive for this diagnostic?
Check::FileCheckType CheckTy;
/// Where is the FileCheck directive for this diagnostic?
- unsigned CheckLine, CheckCol;
+ SMLoc CheckLoc;
/// What type of match result does this diagnostic describe?
///
/// A directive's supplied pattern is said to be either expected or excluded
@@ -159,7 +162,13 @@ public:
///
/// Only expected strings whose prefix is one of those listed in \p PrefixRE
/// are recorded. \returns true in case of an error, false otherwise.
- bool readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE);
+ ///
+ /// If \p ImpPatBufferIDRange, then the range (inclusive start, exclusive end)
+ /// of IDs for source buffers added to \p SM for implicit patterns are
+ /// recorded in it. The range is empty if there are none.
+ bool
+ readCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE,
+ std::pair<unsigned, unsigned> *ImpPatBufferIDRange = nullptr);
bool ValidateCheckPrefixes();
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FileCollector.h b/contrib/llvm-project/llvm/include/llvm/Support/FileCollector.h
index 079fe3efab9d..2b5e9c669b68 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FileCollector.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FileCollector.h
@@ -12,23 +12,44 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/VirtualFileSystem.h"
-
#include <mutex>
+#include <string>
namespace llvm {
-
-/// Collects files into a directory and generates a mapping that can be used by
-/// the VFS.
+class FileCollectorFileSystem;
+class Twine;
+
+/// Captures file system interaction and generates data to be later replayed
+/// with the RedirectingFileSystem.
+///
+/// For any file that gets accessed we eventually create:
+/// - a copy of the file inside Root
+/// - a record in RedirectingFileSystem mapping that maps:
+/// current real path -> path to the copy in Root
+///
+/// That intent is that later when the mapping is used by RedirectingFileSystem
+/// it simulates the state of FS that we collected.
+///
+/// We generate file copies and mapping lazily - see writeMapping and copyFiles.
+/// We don't try to capture the state of the file at the exact time when it's
+/// accessed. Files might get changed, deleted ... we record only the "final"
+/// state.
+///
+/// In order to preserve the relative topology of files we use their real paths
+/// as relative paths inside of the Root.
class FileCollector {
public:
+ /// \p Root is the directory where collected files are will be stored.
+ /// \p OverlayRoot is VFS mapping root.
+ /// \p Root directory gets created in copyFiles unless it already exists.
FileCollector(std::string Root, std::string OverlayRoot);
void addFile(const Twine &file);
+ void addDirectory(const Twine &Dir);
/// Write the yaml mapping (for the VFS) to the given file.
- std::error_code writeMapping(StringRef mapping_file);
+ std::error_code writeMapping(StringRef MappingFile);
/// Copy the files into the root directory.
///
@@ -37,14 +58,14 @@ public:
/// removed after it was added to the mapping.
std::error_code copyFiles(bool StopOnError = true);
- /// Create a VFS that collects all the paths that might be looked at by the
- /// file system accesses.
+ /// Create a VFS that uses \p Collector to collect files accessed via \p
+ /// BaseFS.
static IntrusiveRefCntPtr<vfs::FileSystem>
createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS,
std::shared_ptr<FileCollector> Collector);
private:
- void addFileImpl(StringRef SrcPath);
+ friend FileCollectorFileSystem;
bool markAsSeen(StringRef Path) {
if (Path.empty())
@@ -55,18 +76,27 @@ private:
bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result);
void addFileToMapping(StringRef VirtualPath, StringRef RealPath) {
- VFSWriter.addFileMapping(VirtualPath, RealPath);
+ if (sys::fs::is_directory(VirtualPath))
+ VFSWriter.addDirectoryMapping(VirtualPath, RealPath);
+ else
+ VFSWriter.addFileMapping(VirtualPath, RealPath);
}
protected:
- /// Synchronizes adding files.
+ void addFileImpl(StringRef SrcPath);
+
+ llvm::vfs::directory_iterator
+ addDirectoryImpl(const llvm::Twine &Dir,
+ IntrusiveRefCntPtr<vfs::FileSystem> FS, std::error_code &EC);
+
+ /// Synchronizes access to Seen, VFSWriter and SymlinkMap.
std::mutex Mutex;
- /// The root directory where files are copied.
- std::string Root;
+ /// The directory where collected files are copied to in copyFiles().
+ const std::string Root;
/// The root directory where the VFS overlay lives.
- std::string OverlayRoot;
+ const std::string OverlayRoot;
/// Tracks already seen files so they can be skipped.
StringSet<> Seen;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FileOutputBuffer.h b/contrib/llvm-project/llvm/include/llvm/Support/FileOutputBuffer.h
index bdc1425d4361..8eb36d0034ad 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FileOutputBuffer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FileOutputBuffer.h
@@ -13,11 +13,9 @@
#ifndef LLVM_SUPPORT_FILEOUTPUTBUFFER_H
#define LLVM_SUPPORT_FILEOUTPUTBUFFER_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
-#include "llvm/Support/FileSystem.h"
namespace llvm {
/// FileOutputBuffer - This interface provides simple way to create an in-memory
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FormatAdapters.h b/contrib/llvm-project/llvm/include/llvm/Support/FormatAdapters.h
index a0e8cc439191..495205d11748 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FormatAdapters.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FormatAdapters.h
@@ -9,7 +9,6 @@
#ifndef LLVM_SUPPORT_FORMATADAPTERS_H
#define LLVM_SUPPORT_FORMATADAPTERS_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FormatCommon.h"
@@ -35,7 +34,7 @@ public:
: FormatAdapter<T>(std::forward<T>(Item)), Where(Where), Amount(Amount),
Fill(Fill) {}
- void format(llvm::raw_ostream &Stream, StringRef Style) {
+ void format(llvm::raw_ostream &Stream, StringRef Style) override {
auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
FmtAlign(Adapter, Where, Amount, Fill).format(Stream, Style);
}
@@ -49,7 +48,7 @@ public:
PadAdapter(T &&Item, size_t Left, size_t Right)
: FormatAdapter<T>(std::forward<T>(Item)), Left(Left), Right(Right) {}
- void format(llvm::raw_ostream &Stream, StringRef Style) {
+ void format(llvm::raw_ostream &Stream, StringRef Style) override {
auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
Stream.indent(Left);
Adapter.format(Stream, Style);
@@ -64,7 +63,7 @@ public:
RepeatAdapter(T &&Item, size_t Count)
: FormatAdapter<T>(std::forward<T>(Item)), Count(Count) {}
- void format(llvm::raw_ostream &Stream, StringRef Style) {
+ void format(llvm::raw_ostream &Stream, StringRef Style) override {
auto Adapter = detail::build_format_adapter(std::forward<T>(this->Item));
for (size_t I = 0; I < Count; ++I) {
Adapter.format(Stream, Style);
@@ -77,7 +76,9 @@ public:
ErrorAdapter(Error &&Item) : FormatAdapter(std::move(Item)) {}
ErrorAdapter(ErrorAdapter &&) = default;
~ErrorAdapter() { consumeError(std::move(Item)); }
- void format(llvm::raw_ostream &Stream, StringRef Style) { Stream << Item; }
+ void format(llvm::raw_ostream &Stream, StringRef Style) override {
+ Stream << Item;
+ }
};
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FormatProviders.h b/contrib/llvm-project/llvm/include/llvm/Support/FormatProviders.h
index 629a4845716a..c31481a29259 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FormatProviders.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FormatProviders.h
@@ -124,7 +124,7 @@ protected:
template <typename T>
struct format_provider<
- T, typename std::enable_if<detail::use_integral_formatter<T>::value>::type>
+ T, std::enable_if_t<detail::use_integral_formatter<T>::value>>
: public detail::HelperFunctions {
private:
public:
@@ -173,7 +173,7 @@ public:
/// cases indicates the minimum number of nibbles to print.
template <typename T>
struct format_provider<
- T, typename std::enable_if<detail::use_pointer_formatter<T>::value>::type>
+ T, std::enable_if_t<detail::use_pointer_formatter<T>::value>>
: public detail::HelperFunctions {
private:
public:
@@ -198,7 +198,7 @@ public:
template <typename T>
struct format_provider<
- T, typename std::enable_if<detail::use_string_formatter<T>::value>::type> {
+ T, std::enable_if_t<detail::use_string_formatter<T>::value>> {
static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
size_t N = StringRef::npos;
if (!Style.empty() && Style.getAsInteger(10, N)) {
@@ -230,8 +230,8 @@ template <> struct format_provider<Twine> {
/// character. Otherwise, it is treated as an integer options string.
///
template <typename T>
-struct format_provider<
- T, typename std::enable_if<detail::use_char_formatter<T>::value>::type> {
+struct format_provider<T,
+ std::enable_if_t<detail::use_char_formatter<T>::value>> {
static void format(const char &V, llvm::raw_ostream &Stream,
StringRef Style) {
if (Style.empty())
@@ -296,8 +296,8 @@ template <> struct format_provider<bool> {
/// else.
template <typename T>
-struct format_provider<
- T, typename std::enable_if<detail::use_double_formatter<T>::value>::type>
+struct format_provider<T,
+ std::enable_if_t<detail::use_double_formatter<T>::value>>
: public detail::HelperFunctions {
static void format(const T &V, llvm::raw_ostream &Stream, StringRef Style) {
FloatStyle S;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadic.h b/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadic.h
index 86a9d30cc138..dfafc3ccb44e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadic.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadic.h
@@ -25,6 +25,7 @@
#ifndef LLVM_SUPPORT_FORMATVARIADIC_H
#define LLVM_SUPPORT_FORMATVARIADIC_H
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
@@ -63,23 +64,8 @@ struct ReplacementItem {
class formatv_object_base {
protected:
- // The parameters are stored in a std::tuple, which does not provide runtime
- // indexing capabilities. In order to enable runtime indexing, we use this
- // structure to put the parameters into a std::vector. Since the parameters
- // are not all the same type, we use some type-erasure by wrapping the
- // parameters in a template class that derives from a non-template superclass.
- // Essentially, we are converting a std::tuple<Derived<Ts...>> to a
- // std::vector<Base*>.
- struct create_adapters {
- template <typename... Ts>
- std::vector<detail::format_adapter *> operator()(Ts &... Items) {
- return std::vector<detail::format_adapter *>{&Items...};
- }
- };
-
StringRef Fmt;
- std::vector<detail::format_adapter *> Adapters;
- std::vector<ReplacementItem> Replacements;
+ ArrayRef<detail::format_adapter *> Adapters;
static bool consumeFieldLayout(StringRef &Spec, AlignStyle &Where,
size_t &Align, char &Pad);
@@ -87,23 +73,16 @@ protected:
static std::pair<ReplacementItem, StringRef>
splitLiteralAndReplacement(StringRef Fmt);
-public:
- formatv_object_base(StringRef Fmt, std::size_t ParamCount)
- : Fmt(Fmt), Replacements(parseFormatString(Fmt)) {
- Adapters.reserve(ParamCount);
- }
+ formatv_object_base(StringRef Fmt,
+ ArrayRef<detail::format_adapter *> Adapters)
+ : Fmt(Fmt), Adapters(Adapters) {}
formatv_object_base(formatv_object_base const &rhs) = delete;
+ formatv_object_base(formatv_object_base &&rhs) = default;
- formatv_object_base(formatv_object_base &&rhs)
- : Fmt(std::move(rhs.Fmt)),
- Adapters(), // Adapters are initialized by formatv_object
- Replacements(std::move(rhs.Replacements)) {
- Adapters.reserve(rhs.Adapters.size());
- };
-
+public:
void format(raw_ostream &S) const {
- for (auto &R : Replacements) {
+ for (auto &R : parseFormatString(Fmt)) {
if (R.Type == ReplacementType::Empty)
continue;
if (R.Type == ReplacementType::Literal) {
@@ -121,7 +100,7 @@ public:
Align.format(S, R.Options);
}
}
- static std::vector<ReplacementItem> parseFormatString(StringRef Fmt);
+ static SmallVector<ReplacementItem, 2> parseFormatString(StringRef Fmt);
static Optional<ReplacementItem> parseReplacementItem(StringRef Spec);
@@ -150,12 +129,29 @@ template <typename Tuple> class formatv_object : public formatv_object_base {
// of the parameters, we have to own the storage for the parameters here, and
// have the base class store type-erased pointers into this tuple.
Tuple Parameters;
+ std::array<detail::format_adapter *, std::tuple_size<Tuple>::value>
+ ParameterPointers;
+
+ // The parameters are stored in a std::tuple, which does not provide runtime
+ // indexing capabilities. In order to enable runtime indexing, we use this
+ // structure to put the parameters into a std::array. Since the parameters
+ // are not all the same type, we use some type-erasure by wrapping the
+ // parameters in a template class that derives from a non-template superclass.
+ // Essentially, we are converting a std::tuple<Derived<Ts...>> to a
+ // std::array<Base*>.
+ struct create_adapters {
+ template <typename... Ts>
+ std::array<detail::format_adapter *, std::tuple_size<Tuple>::value>
+ operator()(Ts &... Items) {
+ return {{&Items...}};
+ }
+ };
public:
formatv_object(StringRef Fmt, Tuple &&Params)
- : formatv_object_base(Fmt, std::tuple_size<Tuple>::value),
+ : formatv_object_base(Fmt, ParameterPointers),
Parameters(std::move(Params)) {
- Adapters = apply_tuple(create_adapters(), Parameters);
+ ParameterPointers = apply_tuple(create_adapters(), Parameters);
}
formatv_object(formatv_object const &rhs) = delete;
@@ -163,7 +159,8 @@ public:
formatv_object(formatv_object &&rhs)
: formatv_object_base(std::move(rhs)),
Parameters(std::move(rhs.Parameters)) {
- Adapters = apply_tuple(create_adapters(), Parameters);
+ ParameterPointers = apply_tuple(create_adapters(), Parameters);
+ Adapters = ParameterPointers;
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadicDetails.h b/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadicDetails.h
index e3c185134daa..d5e67b756a47 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadicDetails.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FormatVariadicDetails.h
@@ -36,7 +36,7 @@ public:
explicit provider_format_adapter(T &&Item) : Item(std::forward<T>(Item)) {}
void format(llvm::raw_ostream &S, StringRef Options) override {
- format_provider<typename std::decay<T>::type>::format(Item, S, Options);
+ format_provider<std::decay_t<T>>::format(Item, S, Options);
}
};
@@ -59,7 +59,7 @@ template <typename T> class missing_format_adapter;
//
template <class T> class has_FormatProvider {
public:
- using Decayed = typename std::decay<T>::type;
+ using Decayed = std::decay_t<T>;
typedef void (*Signature_format)(const Decayed &, llvm::raw_ostream &,
StringRef);
@@ -75,14 +75,14 @@ public:
// Test if raw_ostream& << T -> raw_ostream& is findable via ADL.
template <class T> class has_StreamOperator {
public:
- using ConstRefT = const typename std::decay<T>::type &;
+ using ConstRefT = const std::decay_t<T> &;
template <typename U>
- static char test(typename std::enable_if<
- std::is_same<decltype(std::declval<llvm::raw_ostream &>()
- << std::declval<U>()),
- llvm::raw_ostream &>::value,
- int *>::type);
+ static char test(
+ std::enable_if_t<std::is_same<decltype(std::declval<llvm::raw_ostream &>()
+ << std::declval<U>()),
+ llvm::raw_ostream &>::value,
+ int *>);
template <typename U> static double test(...);
@@ -95,8 +95,8 @@ template <typename T>
struct uses_format_member
: public std::integral_constant<
bool,
- std::is_base_of<format_adapter,
- typename std::remove_reference<T>::type>::value> {};
+ std::is_base_of<format_adapter, std::remove_reference_t<T>>::value> {
+};
// Simple template that decides whether a type T should use the format_provider
// based format() invocation. The member function takes priority, so this test
@@ -127,34 +127,32 @@ struct uses_missing_provider
};
template <typename T>
-typename std::enable_if<uses_format_member<T>::value, T>::type
+std::enable_if_t<uses_format_member<T>::value, T>
build_format_adapter(T &&Item) {
return std::forward<T>(Item);
}
template <typename T>
-typename std::enable_if<uses_format_provider<T>::value,
- provider_format_adapter<T>>::type
+std::enable_if_t<uses_format_provider<T>::value, provider_format_adapter<T>>
build_format_adapter(T &&Item) {
return provider_format_adapter<T>(std::forward<T>(Item));
}
template <typename T>
-typename std::enable_if<uses_stream_operator<T>::value,
- stream_operator_format_adapter<T>>::type
+std::enable_if_t<uses_stream_operator<T>::value,
+ stream_operator_format_adapter<T>>
build_format_adapter(T &&Item) {
// If the caller passed an Error by value, then stream_operator_format_adapter
// would be responsible for consuming it.
// Make the caller opt into this by calling fmt_consume().
static_assert(
- !std::is_same<llvm::Error, typename std::remove_cv<T>::type>::value,
+ !std::is_same<llvm::Error, std::remove_cv_t<T>>::value,
"llvm::Error-by-value must be wrapped in fmt_consume() for formatv");
return stream_operator_format_adapter<T>(std::forward<T>(Item));
}
template <typename T>
-typename std::enable_if<uses_missing_provider<T>::value,
- missing_format_adapter<T>>::type
+std::enable_if_t<uses_missing_provider<T>::value, missing_format_adapter<T>>
build_format_adapter(T &&Item) {
return missing_format_adapter<T>();
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/FormattedStream.h b/contrib/llvm-project/llvm/include/llvm/Support/FormattedStream.h
index b49c8d86531d..5f937cfa7984 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/FormattedStream.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/FormattedStream.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
#define LLVM_SUPPORT_FORMATTEDSTREAM_H
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
#include <utility>
@@ -21,8 +22,11 @@ namespace llvm {
/// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
/// of line and column position, allowing padding out to specific column
-/// boundaries and querying the number of lines written to the stream.
-///
+/// boundaries and querying the number of lines written to the stream. This
+/// assumes that the contents of the stream is valid UTF-8 encoded text. This
+/// doesn't attempt to handle everything Unicode can do (combining characters,
+/// right-to-left markers, etc), but should cover the cases likely to appear in
+/// source code or diagnostic messages.
class formatted_raw_ostream : public raw_ostream {
/// TheStream - The real stream we output to. We set it to be
/// unbuffered, since we're already doing our own buffering.
@@ -40,6 +44,14 @@ class formatted_raw_ostream : public raw_ostream {
///
const char *Scanned;
+ /// PartialUTF8Char - Either empty or a prefix of a UTF-8 code unit sequence
+ /// for a Unicode scalar value which should be prepended to the buffer for the
+ /// next call to ComputePosition. This is needed when the buffer is flushed
+ /// when it ends part-way through the UTF-8 encoding of a Unicode scalar
+ /// value, so that we can compute the display width of the character once we
+ /// have the rest of it.
+ SmallString<4> PartialUTF8Char;
+
void write_impl(const char *Ptr, size_t Size) override;
/// current_pos - Return the current position within the stream,
@@ -52,10 +64,16 @@ class formatted_raw_ostream : public raw_ostream {
}
/// ComputePosition - Examine the given output buffer and figure out the new
- /// position after output.
- ///
+ /// position after output. This is safe to call multiple times on the same
+ /// buffer, as it records the most recently scanned character and resumes from
+ /// there when the buffer has not been flushed.
void ComputePosition(const char *Ptr, size_t size);
+ /// UpdatePosition - scan the characters in [Ptr, Ptr+Size), and update the
+ /// line and column numbers. Unlike ComputePosition, this must be called
+ /// exactly once on each region of the buffer.
+ void UpdatePosition(const char *Ptr, size_t Size);
+
void setStream(raw_ostream &Stream) {
releaseStream();
@@ -105,11 +123,17 @@ public:
/// \param NewCol - The column to move to.
formatted_raw_ostream &PadToColumn(unsigned NewCol);
- /// getColumn - Return the column number
- unsigned getColumn() { return Position.first; }
+ unsigned getColumn() {
+ // Calculate current position, taking buffer contents into account.
+ ComputePosition(getBufferStart(), GetNumBytesInBuffer());
+ return Position.first;
+ }
- /// getLine - Return the line number
- unsigned getLine() { return Position.second; }
+ unsigned getLine() {
+ // Calculate current position, taking buffer contents into account.
+ ComputePosition(getBufferStart(), GetNumBytesInBuffer());
+ return Position.second;
+ }
raw_ostream &resetColor() override {
TheStream->resetColor();
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTree.h b/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTree.h
index 2545a075062a..10e591a69d36 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTree.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTree.h
@@ -25,7 +25,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -78,18 +77,25 @@ template <class NodeT> class DomTreeNodeBase {
const_iterator begin() const { return Children.begin(); }
const_iterator end() const { return Children.end(); }
+ DomTreeNodeBase *const &back() const { return Children.back(); }
+ DomTreeNodeBase *&back() { return Children.back(); }
+
+ iterator_range<iterator> children() { return make_range(begin(), end()); }
+ iterator_range<const_iterator> children() const {
+ return make_range(begin(), end());
+ }
+
NodeT *getBlock() const { return TheBB; }
DomTreeNodeBase *getIDom() const { return IDom; }
unsigned getLevel() const { return Level; }
- const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; }
-
std::unique_ptr<DomTreeNodeBase> addChild(
std::unique_ptr<DomTreeNodeBase> C) {
Children.push_back(C.get());
return C;
}
+ bool isLeaf() const { return Children.empty(); }
size_t getNumChildren() const { return Children.size(); }
void clearAllChildren() { Children.clear(); }
@@ -225,7 +231,7 @@ class DominatorTreeBase {
using ParentPtr = decltype(std::declval<NodeT *>()->getParent());
static_assert(std::is_pointer<ParentPtr>::value,
"Currently NodeT's parent must be a pointer type");
- using ParentType = typename std::remove_pointer<ParentPtr>::type;
+ using ParentType = std::remove_pointer_t<ParentPtr>;
static constexpr bool IsPostDominator = IsPostDom;
using UpdateType = cfg::Update<NodePtr>;
@@ -277,11 +283,27 @@ protected:
DominatorTreeBase(const DominatorTreeBase &) = delete;
DominatorTreeBase &operator=(const DominatorTreeBase &) = delete;
- /// getRoots - Return the root blocks of the current CFG. This may include
- /// multiple blocks if we are computing post dominators. For forward
- /// dominators, this will always be a single block (the entry node).
+ /// Iteration over roots.
///
- const SmallVectorImpl<NodeT *> &getRoots() const { return Roots; }
+ /// This may include multiple blocks if we are computing post dominators.
+ /// For forward dominators, this will always be a single block (the entry
+ /// block).
+ using root_iterator = typename SmallVectorImpl<NodeT *>::iterator;
+ using const_root_iterator = typename SmallVectorImpl<NodeT *>::const_iterator;
+
+ root_iterator root_begin() { return Roots.begin(); }
+ const_root_iterator root_begin() const { return Roots.begin(); }
+ root_iterator root_end() { return Roots.end(); }
+ const_root_iterator root_end() const { return Roots.end(); }
+
+ size_t root_size() const { return Roots.size(); }
+
+ iterator_range<root_iterator> roots() {
+ return make_range(root_begin(), root_end());
+ }
+ iterator_range<const_root_iterator> roots() const {
+ return make_range(root_begin(), root_end());
+ }
/// isPostDominator - Returns true if analysis based of postdoms
///
@@ -319,8 +341,6 @@ protected:
return false;
}
- void releaseMemory() { reset(); }
-
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class. The result
/// may (but is not required to) be null for a forward (backwards)
@@ -570,8 +590,7 @@ protected:
DomTreeNodeBase<NodeT> *IDomNode = getNode(DomBB);
assert(IDomNode && "Not immediate dominator specified for block!");
DFSInfoValid = false;
- return (DomTreeNodes[BB] = IDomNode->addChild(
- std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))).get();
+ return createChild(BB, IDomNode);
}
/// Add a new node to the forward dominator tree and make it a new root.
@@ -584,8 +603,7 @@ protected:
assert(!this->isPostDominator() &&
"Cannot change root of post-dominator tree");
DFSInfoValid = false;
- DomTreeNodeBase<NodeT> *NewNode = (DomTreeNodes[BB] =
- std::make_unique<DomTreeNodeBase<NodeT>>(BB, nullptr)).get();
+ DomTreeNodeBase<NodeT> *NewNode = createNode(BB);
if (Roots.empty()) {
addRoot(BB);
} else {
@@ -620,7 +638,7 @@ protected:
void eraseNode(NodeT *BB) {
DomTreeNodeBase<NodeT> *Node = getNode(BB);
assert(Node && "Removing node that isn't in dominator tree.");
- assert(Node->getChildren().empty() && "Node is not a leaf node.");
+ assert(Node->isLeaf() && "Node is not a leaf node.");
DFSInfoValid = false;
@@ -754,9 +772,6 @@ public:
return DomTreeBuilder::Verify(*this, VL);
}
-protected:
- void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
-
void reset() {
DomTreeNodes.clear();
Roots.clear();
@@ -766,6 +781,21 @@ protected:
SlowQueries = 0;
}
+protected:
+ void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
+
+ DomTreeNodeBase<NodeT> *createChild(NodeT *BB, DomTreeNodeBase<NodeT> *IDom) {
+ return (DomTreeNodes[BB] = IDom->addChild(
+ std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDom)))
+ .get();
+ }
+
+ DomTreeNodeBase<NodeT> *createNode(NodeT *BB) {
+ return (DomTreeNodes[BB] =
+ std::make_unique<DomTreeNodeBase<NodeT>>(BB, nullptr))
+ .get();
+ }
+
// NewBB is split and now it has one successor. Update dominator tree to
// reflect this change.
template <class N>
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h b/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h
index 7c0278e8770e..464de4e2b3ba 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/GenericDomTreeConstruction.h
@@ -7,11 +7,11 @@
//===----------------------------------------------------------------------===//
/// \file
///
-/// Generic dominator tree construction - This file provides routines to
+/// Generic dominator tree construction - this file provides routines to
/// construct immediate dominator information for a flow-graph based on the
/// Semi-NCA algorithm described in this dissertation:
///
-/// Linear-Time Algorithms for Dominators and Related Problems
+/// [1] Linear-Time Algorithms for Dominators and Related Problems
/// Loukas Georgiadis, Princeton University, November 2005, pp. 21-23:
/// ftp://ftp.cs.princeton.edu/reports/2005/737.pdf
///
@@ -20,13 +20,15 @@
///
/// O(n^2) worst cases happen when the computation of nearest common ancestors
/// requires O(n) average time, which is very unlikely in real world. If this
-/// ever turns out to be an issue, consider implementing a hybrid algorithm.
+/// ever turns out to be an issue, consider implementing a hybrid algorithm
+/// that uses SLT to perform full constructions and SemiNCA for incremental
+/// updates.
///
/// The file uses the Depth Based Search algorithm to perform incremental
/// updates (insertion and deletions). The implemented algorithm is based on
/// this publication:
///
-/// An Experimental Study of Dynamic Dominators
+/// [2] An Experimental Study of Dynamic Dominators
/// Loukas Georgiadis, et al., April 12 2016, pp. 5-7, 9-10:
/// https://arxiv.org/pdf/1604.02711.pdf
///
@@ -35,7 +37,6 @@
#ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
#define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
-#include <queue>
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/DepthFirstIterator.h"
@@ -43,6 +44,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GenericDomTree.h"
+#include <queue>
#define DEBUG_TYPE "dom-tree-builder"
@@ -185,9 +187,7 @@ struct SemiNCAInfo {
// Add a new tree node for this NodeT, and link it as a child of
// IDomNode
- return (DT.DomTreeNodes[BB] = IDomNode->addChild(
- std::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
- .get();
+ return DT.createChild(BB, IDomNode);
}
static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
@@ -585,9 +585,7 @@ struct SemiNCAInfo {
// all real exits (including multiple exit blocks, infinite loops).
NodePtr Root = IsPostDom ? nullptr : DT.Roots[0];
- DT.RootNode = (DT.DomTreeNodes[Root] =
- std::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
- .get();
+ DT.RootNode = DT.createNode(Root);
SNCA.attachNewSubtree(DT, DT.RootNode);
}
@@ -597,8 +595,6 @@ struct SemiNCAInfo {
// Loop over all of the discovered blocks in the function...
for (size_t i = 1, e = NumToNode.size(); i != e; ++i) {
NodePtr W = NumToNode[i];
- LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
- << BlockNamePrinter(W) << "\n");
// Don't replace this with 'count', the insertion side effect is important
if (DT.DomTreeNodes[W]) continue; // Haven't calculated this node yet?
@@ -610,8 +606,7 @@ struct SemiNCAInfo {
// Add a new tree node for this BasicBlock, and link it as a child of
// IDomNode.
- DT.DomTreeNodes[W] = IDomNode->addChild(
- std::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
+ DT.createChild(W, IDomNode);
}
}
@@ -661,10 +656,7 @@ struct SemiNCAInfo {
// The unreachable node becomes a new root -- a tree node for it.
TreeNodePtr VirtualRoot = DT.getNode(nullptr);
- FromTN =
- (DT.DomTreeNodes[From] = VirtualRoot->addChild(
- std::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot)))
- .get();
+ FromTN = DT.createChild(From, VirtualRoot);
DT.Roots.push_back(From);
}
@@ -732,7 +724,7 @@ struct SemiNCAInfo {
LLVM_DEBUG(dbgs() << "Roots are different in updated trees\n"
<< "The entire tree needs to be rebuilt\n");
// It may be possible to update the tree without recalculating it, but
- // we do not know yet how to do it, and it happens rarely in practise.
+ // we do not know yet how to do it, and it happens rarely in practice.
CalculateFromScratch(DT, BUI);
}
}
@@ -757,13 +749,13 @@ struct SemiNCAInfo {
LLVM_DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
const unsigned NCDLevel = NCD->getLevel();
- // Based on Lemma 2.5 from the second paper, after insertion of (From,To), v
- // is affected iff depth(NCD)+1 < depth(v) && a path P from To to v exists
- // where every w on P s.t. depth(v) <= depth(w)
+ // Based on Lemma 2.5 from [2], after insertion of (From,To), v is affected
+ // iff depth(NCD)+1 < depth(v) && a path P from To to v exists where every
+ // w on P s.t. depth(v) <= depth(w)
//
// This reduces to a widest path problem (maximizing the depth of the
// minimum vertex in the path) which can be solved by a modified version of
- // Dijkstra with a bucket queue (named depth-based search in the paper).
+ // Dijkstra with a bucket queue (named depth-based search in [2]).
// To is in the path, so depth(NCD)+1 < depth(v) <= depth(To). Nothing
// affected if this does not hold.
@@ -957,7 +949,7 @@ struct SemiNCAInfo {
<< BlockNamePrinter(ToIDom) << "\n");
// To remains reachable after deletion.
- // (Based on the caption under Figure 4. from the second paper.)
+ // (Based on the caption under Figure 4. from [2].)
if (FromTN != ToIDom || HasProperSupport(DT, BUI, ToTN))
DeleteReachable(DT, BUI, FromTN, ToTN);
else
@@ -976,7 +968,7 @@ struct SemiNCAInfo {
LLVM_DEBUG(dbgs() << "\tRebuilding subtree\n");
// Find the top of the subtree that needs to be rebuilt.
- // (Based on the lemma 2.6 from the second paper.)
+ // (Based on the lemma 2.6 from [2].)
const NodePtr ToIDom =
DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
assert(ToIDom || DT.isPostDominator());
@@ -1008,7 +1000,7 @@ struct SemiNCAInfo {
}
// Checks if a node has proper support, as defined on the page 3 and later
- // explained on the page 7 of the second paper.
+ // explained on the page 7 of [2].
static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI,
const TreeNodePtr TN) {
LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
@@ -1033,7 +1025,7 @@ struct SemiNCAInfo {
}
// Handle deletions that make destination node unreachable.
- // (Based on the lemma 2.7 from the second paper.)
+ // (Based on the lemma 2.7 from the [2].)
static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI,
const TreeNodePtr ToTN) {
LLVM_DEBUG(dbgs() << "Deleting unreachable subtree "
@@ -1372,7 +1364,7 @@ struct SemiNCAInfo {
if (!DT.DFSInfoValid || !DT.Parent)
return true;
- const NodePtr RootBB = IsPostDom ? nullptr : DT.getRoots()[0];
+ const NodePtr RootBB = IsPostDom ? nullptr : *DT.root_begin();
const TreeNodePtr Root = DT.getNode(RootBB);
auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
@@ -1396,7 +1388,7 @@ struct SemiNCAInfo {
const TreeNodePtr Node = NodeToTN.second.get();
// Handle tree leaves.
- if (Node->getChildren().empty()) {
+ if (Node->isLeaf()) {
if (Node->getDFSNumIn() + 1 != Node->getDFSNumOut()) {
errs() << "Tree leaf should have DFSOut = DFSIn + 1:\n\t";
PrintNodeAndDFSNums(Node);
@@ -1493,9 +1485,9 @@ struct SemiNCAInfo {
// LEFT, and thus, LEFT is really an ancestor (in the dominator tree) of
// RIGHT, not a sibling.
- // It is possible to verify the parent and sibling properties in
- // linear time, but the algorithms are complex. Instead, we do it in a
- // straightforward N^2 and N^3 way below, using direct path reachability.
+ // It is possible to verify the parent and sibling properties in linear time,
+ // but the algorithms are complex. Instead, we do it in a straightforward
+ // N^2 and N^3 way below, using direct path reachability.
// Checks if the tree has the parent property: if for all edges from V to W in
// the input graph, such that V is reachable, the parent of W in the tree is
@@ -1508,7 +1500,8 @@ struct SemiNCAInfo {
for (auto &NodeToTN : DT.DomTreeNodes) {
const TreeNodePtr TN = NodeToTN.second.get();
const NodePtr BB = TN->getBlock();
- if (!BB || TN->getChildren().empty()) continue;
+ if (!BB || TN->isLeaf())
+ continue;
LLVM_DEBUG(dbgs() << "Verifying parent property of node "
<< BlockNamePrinter(TN) << "\n");
@@ -1517,7 +1510,7 @@ struct SemiNCAInfo {
return From != BB && To != BB;
});
- for (TreeNodePtr Child : TN->getChildren())
+ for (TreeNodePtr Child : TN->children())
if (NodeToInfo.count(Child->getBlock()) != 0) {
errs() << "Child " << BlockNamePrinter(Child)
<< " reachable after its parent " << BlockNamePrinter(BB)
@@ -1541,17 +1534,17 @@ struct SemiNCAInfo {
for (auto &NodeToTN : DT.DomTreeNodes) {
const TreeNodePtr TN = NodeToTN.second.get();
const NodePtr BB = TN->getBlock();
- if (!BB || TN->getChildren().empty()) continue;
+ if (!BB || TN->isLeaf())
+ continue;
- const auto &Siblings = TN->getChildren();
- for (const TreeNodePtr N : Siblings) {
+ for (const TreeNodePtr N : TN->children()) {
clear();
NodePtr BBN = N->getBlock();
doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
return From != BBN && To != BBN;
});
- for (const TreeNodePtr S : Siblings) {
+ for (const TreeNodePtr S : TN->children()) {
if (S == N) continue;
if (NodeToInfo.count(S->getBlock()) == 0) {
@@ -1571,7 +1564,7 @@ struct SemiNCAInfo {
// Check if the given tree is the same as a freshly computed one for the same
// Parent.
- // Running time: O(N^2), but faster in practise (same as tree construction).
+ // Running time: O(N^2), but faster in practice (same as tree construction).
//
// Note that this does not check if that the tree construction algorithm is
// correct and should be only used for fast (but possibly unsound)
@@ -1648,12 +1641,12 @@ bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
if (!SNCA.IsSameAsFreshTree(DT))
return false;
- // Common checks to verify the properties of the tree. O(N log N) at worst
+ // Common checks to verify the properties of the tree. O(N log N) at worst.
if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
!SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
return false;
- // Extra checks depending on VerificationLevel. Up to O(N^3)
+ // Extra checks depending on VerificationLevel. Up to O(N^3).
if (VL == DomTreeT::VerificationLevel::Basic ||
VL == DomTreeT::VerificationLevel::Full)
if (!SNCA.verifyParentProperty(DT))
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h b/contrib/llvm-project/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
index 25eb7cd7b6d5..a8fca70159f5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/GenericIteratedDominanceFrontier.h
@@ -57,7 +57,7 @@ template <class NodeTy, bool IsPostDom> struct ChildrenGetterTy {
template <class NodeTy, bool IsPostDom> class IDFCalculatorBase {
public:
using OrderedNodeTy =
- typename std::conditional<IsPostDom, Inverse<NodeTy *>, NodeTy *>::type;
+ std::conditional_t<IsPostDom, Inverse<NodeTy *>, NodeTy *>;
using ChildrenGetterTy =
IDFCalculatorDetail::ChildrenGetterTy<NodeTy, IsPostDom>;
@@ -129,7 +129,7 @@ ChildrenGetterTy<NodeTy, IsPostDom>::get(const NodeRef &N) {
template <class NodeTy, bool IsPostDom>
void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
- SmallVectorImpl<NodeTy *> &PHIBlocks) {
+ SmallVectorImpl<NodeTy *> &IDFBlocks) {
// Use a priority queue keyed on dominator tree level so that inserted nodes
// are handled from the bottom of the dominator tree upwards. We also augment
// the level with a DFS number to ensure that the blocks are ordered in a
@@ -144,15 +144,16 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
DT.updateDFSNumbers();
- for (NodeTy *BB : *DefBlocks) {
- if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB))
- PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
- }
-
SmallVector<DomTreeNodeBase<NodeTy> *, 32> Worklist;
SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedPQ;
SmallPtrSet<DomTreeNodeBase<NodeTy> *, 32> VisitedWorklist;
+ for (NodeTy *BB : *DefBlocks)
+ if (DomTreeNodeBase<NodeTy> *Node = DT.getNode(BB)) {
+ PQ.push({Node, std::make_pair(Node->getLevel(), Node->getDFSNumIn())});
+ VisitedWorklist.insert(Node);
+ }
+
while (!PQ.empty()) {
DomTreeNodePair RootPair = PQ.top();
PQ.pop();
@@ -164,9 +165,8 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
// most Root's level are added to the iterated dominance frontier of the
// definition set.
- Worklist.clear();
+ assert(Worklist.empty());
Worklist.push_back(Root);
- VisitedWorklist.insert(Root);
while (!Worklist.empty()) {
DomTreeNodeBase<NodeTy> *Node = Worklist.pop_back_val();
@@ -187,7 +187,7 @@ void IDFCalculatorBase<NodeTy, IsPostDom>::calculate(
if (useLiveIn && !LiveInBlocks->count(SuccBB))
return;
- PHIBlocks.emplace_back(SuccBB);
+ IDFBlocks.emplace_back(SuccBB);
if (!DefBlocks->count(SuccBB))
PQ.push(std::make_pair(
SuccNode, std::make_pair(SuccLevel, SuccNode->getDFSNumIn())));
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/GlobPattern.h b/contrib/llvm-project/llvm/include/llvm/Support/GlobPattern.h
index 0098ac65fd30..3e5989d02500 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/GlobPattern.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/GlobPattern.h
@@ -16,15 +16,15 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
#include <vector>
// This class represents a glob pattern. Supported metacharacters
// are "*", "?", "\", "[<chars>]", "[^<chars>]", and "[!<chars>]".
namespace llvm {
-class BitVector;
+
template <typename T> class ArrayRef;
+class StringRef;
class GlobPattern {
public:
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/GraphWriter.h b/contrib/llvm-project/llvm/include/llvm/Support/GraphWriter.h
index 466a0449e257..f9241b1e8081 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/GraphWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/GraphWriter.h
@@ -126,7 +126,7 @@ public:
}
void writeHeader(const std::string &Title) {
- std::string GraphName = DTraits.getGraphName(G);
+ std::string GraphName(DTraits.getGraphName(G));
if (!Title.empty())
O << "digraph \"" << DOT::EscapeString(Title) << "\" {\n";
@@ -330,11 +330,8 @@ std::string WriteGraph(const GraphType &G, const Twine &Name,
const Twine &Title = "",
std::string Filename = "") {
int FD;
- // Windows can't always handle long paths, so limit the length of the name.
- std::string N = Name.str();
- N = N.substr(0, std::min<std::size_t>(N.size(), 140));
if (Filename.empty()) {
- Filename = createGraphFilename(N, FD);
+ Filename = createGraphFilename(Name.str(), FD);
} else {
std::error_code EC = sys::fs::openFileForWrite(Filename, FD);
@@ -344,6 +341,8 @@ std::string WriteGraph(const GraphType &G, const Twine &Name,
} else if (EC) {
errs() << "error writing into file" << "\n";
return "";
+ } else {
+ errs() << "writing to the newly created file " << Filename << "\n";
}
}
raw_fd_ostream O(FD, /*shouldClose=*/ true);
@@ -359,6 +358,17 @@ std::string WriteGraph(const GraphType &G, const Twine &Name,
return Filename;
}
+/// DumpDotGraph - Just dump a dot graph to the user-provided file name.
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+template <typename GraphType>
+LLVM_DUMP_METHOD void
+dumpDotGraphToFile(const GraphType &G, const Twine &FileName,
+ const Twine &Title, bool ShortNames = false,
+ const Twine &Name = "") {
+ llvm::WriteGraph(G, Name, ShortNames, Title, FileName.str());
+}
+#endif
+
/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
/// then cleanup. For use from the debugger.
///
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Host.h b/contrib/llvm-project/llvm/include/llvm/Support/Host.h
index 44f543c363db..d4ef389450cc 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Host.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Host.h
@@ -13,11 +13,13 @@
#ifndef LLVM_SUPPORT_HOST_H
#define LLVM_SUPPORT_HOST_H
-#include "llvm/ADT/StringMap.h"
-
#include <string>
namespace llvm {
+class MallocAllocator;
+class StringRef;
+template <typename ValueTy, typename AllocatorTy> class StringMap;
+
namespace sys {
/// getDefaultTargetTriple() - Return the default target triple the compiler
@@ -50,7 +52,7 @@ namespace sys {
/// all valid LLVM feature names.
///
/// \return - True on success.
- bool getHostCPUFeatures(StringMap<bool> &Features);
+ bool getHostCPUFeatures(StringMap<bool, MallocAllocator> &Features);
/// Get the number of physical cores (as opposed to logical cores returned
/// from thread::hardware_concurrency(), which includes hyperthreads).
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h b/contrib/llvm-project/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h
index 6920000340d4..8e1b3d631983 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h
@@ -14,11 +14,13 @@
#ifndef LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H
#define LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H
-#include "llvm/ADT/StringRef.h"
-
#include <cstddef>
+#include <cstdint>
namespace llvm {
+
+class StringRef;
+
/// Canonicalizer for mangled names.
///
/// This class allows specifying a list of "equivalent" manglings. For example,
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/JSON.h b/contrib/llvm-project/llvm/include/llvm/Support/JSON.h
index 2c63468c401a..8b1c66234fe8 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/JSON.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/JSON.h
@@ -329,32 +329,28 @@ public:
Value(std::nullptr_t) : Type(T_Null) {}
// Boolean (disallow implicit conversions).
// (The last template parameter is a dummy to keep templates distinct.)
- template <
- typename T,
- typename = typename std::enable_if<std::is_same<T, bool>::value>::type,
- bool = false>
+ template <typename T,
+ typename = std::enable_if_t<std::is_same<T, bool>::value>,
+ bool = false>
Value(T B) : Type(T_Boolean) {
create<bool>(B);
}
// Integers (except boolean). Must be non-narrowing convertible to int64_t.
- template <
- typename T,
- typename = typename std::enable_if<std::is_integral<T>::value>::type,
- typename = typename std::enable_if<!std::is_same<T, bool>::value>::type>
+ template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
+ typename = std::enable_if_t<!std::is_same<T, bool>::value>>
Value(T I) : Type(T_Integer) {
create<int64_t>(int64_t{I});
}
// Floating point. Must be non-narrowing convertible to double.
template <typename T,
- typename =
- typename std::enable_if<std::is_floating_point<T>::value>::type,
+ typename = std::enable_if_t<std::is_floating_point<T>::value>,
double * = nullptr>
Value(T D) : Type(T_Double) {
create<double>(double{D});
}
// Serializable types: with a toJSON(const T&)->Value function, found by ADL.
template <typename T,
- typename = typename std::enable_if<std::is_same<
+ typename = std::enable_if_t<std::is_same<
Value, decltype(toJSON(*(const T *)nullptr))>::value>,
Value * = nullptr>
Value(const T &V) : Value(toJSON(V)) {}
@@ -565,7 +561,7 @@ inline bool Object::erase(StringRef K) {
// See comments on Value.
inline bool fromJSON(const Value &E, std::string &Out) {
if (auto S = E.getAsString()) {
- Out = *S;
+ Out = std::string(*S);
return true;
}
return false;
@@ -598,6 +594,13 @@ inline bool fromJSON(const Value &E, bool &Out) {
}
return false;
}
+inline bool fromJSON(const Value &E, std::nullptr_t &Out) {
+ if (auto S = E.getAsNull()) {
+ Out = *S;
+ return true;
+ }
+ return false;
+}
template <typename T> bool fromJSON(const Value &E, llvm::Optional<T> &Out) {
if (E.getAsNull()) {
Out = llvm::None;
@@ -625,7 +628,7 @@ bool fromJSON(const Value &E, std::map<std::string, T> &Out) {
if (auto *O = E.getAsObject()) {
Out.clear();
for (const auto &KV : *O)
- if (!fromJSON(KV.second, Out[llvm::StringRef(KV.first)]))
+ if (!fromJSON(KV.second, Out[std::string(llvm::StringRef(KV.first))]))
return false;
return true;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/KnownBits.h b/contrib/llvm-project/llvm/include/llvm/Support/KnownBits.h
index ff25b6fc572c..69040cd23f03 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/KnownBits.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/KnownBits.h
@@ -122,39 +122,55 @@ public:
return ~Zero;
}
- /// Truncate the underlying known Zero and One bits. This is equivalent
- /// to truncating the value we're tracking.
+ /// Return known bits for a truncation of the value we're tracking.
KnownBits trunc(unsigned BitWidth) const {
return KnownBits(Zero.trunc(BitWidth), One.trunc(BitWidth));
}
- /// Extends the underlying known Zero and One bits.
- /// By setting ExtendedBitsAreKnownZero=true this will be equivalent to
- /// zero extending the value we're tracking.
- /// With ExtendedBitsAreKnownZero=false the extended bits are set to unknown.
- KnownBits zext(unsigned BitWidth, bool ExtendedBitsAreKnownZero) const {
+ /// Return known bits for an "any" extension of the value we're tracking,
+ /// where we don't know anything about the extended bits.
+ KnownBits anyext(unsigned BitWidth) const {
+ return KnownBits(Zero.zext(BitWidth), One.zext(BitWidth));
+ }
+
+ /// Return known bits for a zero extension of the value we're tracking.
+ KnownBits zext(unsigned BitWidth) const {
unsigned OldBitWidth = getBitWidth();
APInt NewZero = Zero.zext(BitWidth);
- if (ExtendedBitsAreKnownZero)
- NewZero.setBitsFrom(OldBitWidth);
+ NewZero.setBitsFrom(OldBitWidth);
return KnownBits(NewZero, One.zext(BitWidth));
}
- /// Sign extends the underlying known Zero and One bits. This is equivalent
- /// to sign extending the value we're tracking.
+ /// Return known bits for a sign extension of the value we're tracking.
KnownBits sext(unsigned BitWidth) const {
return KnownBits(Zero.sext(BitWidth), One.sext(BitWidth));
}
- /// Extends or truncates the underlying known Zero and One bits. When
- /// extending the extended bits can either be set as known zero (if
- /// ExtendedBitsAreKnownZero=true) or as unknown (if
- /// ExtendedBitsAreKnownZero=false).
- KnownBits zextOrTrunc(unsigned BitWidth,
- bool ExtendedBitsAreKnownZero) const {
+ /// Return known bits for an "any" extension or truncation of the value we're
+ /// tracking.
+ KnownBits anyextOrTrunc(unsigned BitWidth) const {
+ if (BitWidth > getBitWidth())
+ return anyext(BitWidth);
+ if (BitWidth < getBitWidth())
+ return trunc(BitWidth);
+ return *this;
+ }
+
+ /// Return known bits for a zero extension or truncation of the value we're
+ /// tracking.
+ KnownBits zextOrTrunc(unsigned BitWidth) const {
if (BitWidth > getBitWidth())
- return zext(BitWidth, ExtendedBitsAreKnownZero);
- return KnownBits(Zero.zextOrTrunc(BitWidth), One.zextOrTrunc(BitWidth));
+ return zext(BitWidth);
+ if (BitWidth < getBitWidth())
+ return trunc(BitWidth);
+ return *this;
+ }
+
+ /// Return a KnownBits with the extracted bits
+ /// [bitPosition,bitPosition+numBits).
+ KnownBits extractBits(unsigned NumBits, unsigned BitPosition) const {
+ return KnownBits(Zero.extractBits(NumBits, BitPosition),
+ One.extractBits(NumBits, BitPosition));
}
/// Returns the minimum number of trailing zero bits.
@@ -224,8 +240,47 @@ public:
/// Compute known bits resulting from adding LHS and RHS.
static KnownBits computeForAddSub(bool Add, bool NSW, const KnownBits &LHS,
KnownBits RHS);
+
+ /// Update known bits based on ANDing with RHS.
+ KnownBits &operator&=(const KnownBits &RHS);
+
+ /// Update known bits based on ORing with RHS.
+ KnownBits &operator|=(const KnownBits &RHS);
+
+ /// Update known bits based on XORing with RHS.
+ KnownBits &operator^=(const KnownBits &RHS);
};
+inline KnownBits operator&(KnownBits LHS, const KnownBits &RHS) {
+ LHS &= RHS;
+ return LHS;
+}
+
+inline KnownBits operator&(const KnownBits &LHS, KnownBits &&RHS) {
+ RHS &= LHS;
+ return std::move(RHS);
+}
+
+inline KnownBits operator|(KnownBits LHS, const KnownBits &RHS) {
+ LHS |= RHS;
+ return LHS;
+}
+
+inline KnownBits operator|(const KnownBits &LHS, KnownBits &&RHS) {
+ RHS |= LHS;
+ return std::move(RHS);
+}
+
+inline KnownBits operator^(KnownBits LHS, const KnownBits &RHS) {
+ LHS ^= RHS;
+ return LHS;
+}
+
+inline KnownBits operator^(const KnownBits &LHS, KnownBits &&RHS) {
+ RHS ^= LHS;
+ return std::move(RHS);
+}
+
} // end namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/LEB128.h b/contrib/llvm-project/llvm/include/llvm/Support/LEB128.h
index a02b83ca9597..8ab35431354d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/LEB128.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/LEB128.h
@@ -134,7 +134,7 @@ inline uint64_t decodeULEB128(const uint8_t *p, unsigned *n = nullptr,
if (error)
*error = nullptr;
do {
- if (end && p == end) {
+ if (p == end) {
if (error)
*error = "malformed uleb128, extends past end";
if (n)
@@ -168,7 +168,7 @@ inline int64_t decodeSLEB128(const uint8_t *p, unsigned *n = nullptr,
if (error)
*error = nullptr;
do {
- if (end && p == end) {
+ if (p == end) {
if (error)
*error = "malformed sleb128, extends past end";
if (n)
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h b/contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h
index 2efeca3b6200..ab66621e6756 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/LockFileManager.h
@@ -78,8 +78,8 @@ public:
/// For a shared lock, wait until the owner releases the lock.
/// Total timeout for the file to appear is ~1.5 minutes.
- /// \param MaxSeconds the maximum wait time per iteration in seconds.
- WaitForUnlockResult waitForUnlock(const unsigned MaxSeconds = 40);
+ /// \param MaxSeconds the maximum total wait time in seconds.
+ WaitForUnlockResult waitForUnlock(const unsigned MaxSeconds = 90);
/// Remove the lock file. This may delete a different lock file than
/// the one previously read if there is a race.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h b/contrib/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h
index 6ef7c298bc28..c1d516f2fe58 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/LowLevelTypeImpl.h
@@ -27,6 +27,7 @@
#define LLVM_SUPPORT_LOWLEVELTYPEIMPL_H
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/MachineValueType.h"
#include <cassert>
@@ -137,6 +138,26 @@ public:
: LLT::scalar(NewEltSize);
}
+ /// Return a vector or scalar with the same element type and the new number of
+ /// elements.
+ LLT changeNumElements(unsigned NewNumElts) const {
+ return LLT::scalarOrVector(NewNumElts, getScalarType());
+ }
+
+ /// Return a type that is \p Factor times smaller. Reduces the number of
+ /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
+ /// not attempt to handle cases that aren't evenly divisible.
+ LLT divide(int Factor) const {
+ assert(Factor != 1);
+ if (isVector()) {
+ assert(getNumElements() % Factor == 0);
+ return scalarOrVector(getNumElements() / Factor, getElementType());
+ }
+
+ assert(getSizeInBits() % Factor == 0);
+ return scalar(getSizeInBits() / Factor);
+ }
+
bool isByteSized() const { return (getSizeInBits() & 7) == 0; }
unsigned getScalarSizeInBits() const {
@@ -174,6 +195,13 @@ public:
void print(raw_ostream &OS) const;
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+ LLVM_DUMP_METHOD void dump() const {
+ print(dbgs());
+ dbgs() << '\n';
+ }
+#endif
+
bool operator==(const LLT &RHS) const {
return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector &&
RHS.RawData == RawData;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MD5.h b/contrib/llvm-project/llvm/include/llvm/Support/MD5.h
index bb2bdbf1bed2..3b2d5b974d0b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MD5.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MD5.h
@@ -28,7 +28,6 @@
#ifndef LLVM_SUPPORT_MD5_H
#define LLVM_SUPPORT_MD5_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
#include <array>
@@ -36,6 +35,7 @@
namespace llvm {
+template <unsigned N> class SmallString;
template <typename T> class ArrayRef;
class MD5 {
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MSVCErrorWorkarounds.h b/contrib/llvm-project/llvm/include/llvm/Support/MSVCErrorWorkarounds.h
index 30e8febae20b..bf983dc1e406 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MSVCErrorWorkarounds.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MSVCErrorWorkarounds.h
@@ -59,22 +59,19 @@ public:
template <typename OtherT>
MSVCPExpected(
OtherT &&Val,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
- nullptr)
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
: Expected<T>(std::move(Val)) {}
template <class OtherT>
MSVCPExpected(
Expected<OtherT> &&Other,
- typename std::enable_if<std::is_convertible<OtherT, T>::value>::type * =
- nullptr)
+ std::enable_if_t<std::is_convertible<OtherT, T>::value> * = nullptr)
: Expected<T>(std::move(Other)) {}
template <class OtherT>
explicit MSVCPExpected(
Expected<OtherT> &&Other,
- typename std::enable_if<!std::is_convertible<OtherT, T>::value>::type * =
- nullptr)
+ std::enable_if_t<!std::is_convertible<OtherT, T>::value> * = nullptr)
: Expected<T>(std::move(Other)) {}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MachineValueType.h b/contrib/llvm-project/llvm/include/llvm/Support/MachineValueType.h
index 26b45a602763..3bb8220e72e5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MachineValueType.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MachineValueType.h
@@ -47,158 +47,179 @@ namespace llvm {
FIRST_INTEGER_VALUETYPE = i1,
LAST_INTEGER_VALUETYPE = i128,
- f16 = 8, // This is a 16 bit floating point value
- f32 = 9, // This is a 32 bit floating point value
- f64 = 10, // This is a 64 bit floating point value
- f80 = 11, // This is a 80 bit floating point value
- f128 = 12, // This is a 128 bit floating point value
- ppcf128 = 13, // This is a PPC 128-bit floating point value
-
- FIRST_FP_VALUETYPE = f16,
+ bf16 = 8, // This is a 16 bit brain floating point value
+ f16 = 9, // This is a 16 bit floating point value
+ f32 = 10, // This is a 32 bit floating point value
+ f64 = 11, // This is a 64 bit floating point value
+ f80 = 12, // This is a 80 bit floating point value
+ f128 = 13, // This is a 128 bit floating point value
+ ppcf128 = 14, // This is a PPC 128-bit floating point value
+
+ FIRST_FP_VALUETYPE = bf16,
LAST_FP_VALUETYPE = ppcf128,
- v1i1 = 14, // 1 x i1
- v2i1 = 15, // 2 x i1
- v4i1 = 16, // 4 x i1
- v8i1 = 17, // 8 x i1
- v16i1 = 18, // 16 x i1
- v32i1 = 19, // 32 x i1
- v64i1 = 20, // 64 x i1
- v128i1 = 21, // 128 x i1
- v256i1 = 22, // 256 x i1
- v512i1 = 23, // 512 x i1
- v1024i1 = 24, // 1024 x i1
-
- v1i8 = 25, // 1 x i8
- v2i8 = 26, // 2 x i8
- v4i8 = 27, // 4 x i8
- v8i8 = 28, // 8 x i8
- v16i8 = 29, // 16 x i8
- v32i8 = 30, // 32 x i8
- v64i8 = 31, // 64 x i8
- v128i8 = 32, //128 x i8
- v256i8 = 33, //256 x i8
-
- v1i16 = 34, // 1 x i16
- v2i16 = 35, // 2 x i16
- v3i16 = 36, // 3 x i16
- v4i16 = 37, // 4 x i16
- v8i16 = 38, // 8 x i16
- v16i16 = 39, // 16 x i16
- v32i16 = 40, // 32 x i16
- v64i16 = 41, // 64 x i16
- v128i16 = 42, //128 x i16
-
- v1i32 = 43, // 1 x i32
- v2i32 = 44, // 2 x i32
- v3i32 = 45, // 3 x i32
- v4i32 = 46, // 4 x i32
- v5i32 = 47, // 5 x i32
- v8i32 = 48, // 8 x i32
- v16i32 = 49, // 16 x i32
- v32i32 = 50, // 32 x i32
- v64i32 = 51, // 64 x i32
- v128i32 = 52, // 128 x i32
- v256i32 = 53, // 256 x i32
- v512i32 = 54, // 512 x i32
- v1024i32 = 55, // 1024 x i32
- v2048i32 = 56, // 2048 x i32
-
- v1i64 = 57, // 1 x i64
- v2i64 = 58, // 2 x i64
- v4i64 = 59, // 4 x i64
- v8i64 = 60, // 8 x i64
- v16i64 = 61, // 16 x i64
- v32i64 = 62, // 32 x i64
-
- v1i128 = 63, // 1 x i128
+ v1i1 = 15, // 1 x i1
+ v2i1 = 16, // 2 x i1
+ v4i1 = 17, // 4 x i1
+ v8i1 = 18, // 8 x i1
+ v16i1 = 19, // 16 x i1
+ v32i1 = 20, // 32 x i1
+ v64i1 = 21, // 64 x i1
+ v128i1 = 22, // 128 x i1
+ v256i1 = 23, // 256 x i1
+ v512i1 = 24, // 512 x i1
+ v1024i1 = 25, // 1024 x i1
+
+ v1i8 = 26, // 1 x i8
+ v2i8 = 27, // 2 x i8
+ v4i8 = 28, // 4 x i8
+ v8i8 = 29, // 8 x i8
+ v16i8 = 30, // 16 x i8
+ v32i8 = 31, // 32 x i8
+ v64i8 = 32, // 64 x i8
+ v128i8 = 33, //128 x i8
+ v256i8 = 34, //256 x i8
+
+ v1i16 = 35, // 1 x i16
+ v2i16 = 36, // 2 x i16
+ v3i16 = 37, // 3 x i16
+ v4i16 = 38, // 4 x i16
+ v8i16 = 39, // 8 x i16
+ v16i16 = 40, // 16 x i16
+ v32i16 = 41, // 32 x i16
+ v64i16 = 42, // 64 x i16
+ v128i16 = 43, //128 x i16
+
+ v1i32 = 44, // 1 x i32
+ v2i32 = 45, // 2 x i32
+ v3i32 = 46, // 3 x i32
+ v4i32 = 47, // 4 x i32
+ v5i32 = 48, // 5 x i32
+ v8i32 = 49, // 8 x i32
+ v16i32 = 50, // 16 x i32
+ v32i32 = 51, // 32 x i32
+ v64i32 = 52, // 64 x i32
+ v128i32 = 53, // 128 x i32
+ v256i32 = 54, // 256 x i32
+ v512i32 = 55, // 512 x i32
+ v1024i32 = 56, // 1024 x i32
+ v2048i32 = 57, // 2048 x i32
+
+ v1i64 = 58, // 1 x i64
+ v2i64 = 59, // 2 x i64
+ v4i64 = 60, // 4 x i64
+ v8i64 = 61, // 8 x i64
+ v16i64 = 62, // 16 x i64
+ v32i64 = 63, // 32 x i64
+
+ v1i128 = 64, // 1 x i128
FIRST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i1,
LAST_INTEGER_FIXEDLEN_VECTOR_VALUETYPE = v1i128,
- v2f16 = 64, // 2 x f16
- v3f16 = 65, // 3 x f16
- v4f16 = 66, // 4 x f16
- v8f16 = 67, // 8 x f16
- v16f16 = 68, // 16 x f16
- v32f16 = 69, // 32 x f16
- v1f32 = 70, // 1 x f32
- v2f32 = 71, // 2 x f32
- v3f32 = 72, // 3 x f32
- v4f32 = 73, // 4 x f32
- v5f32 = 74, // 5 x f32
- v8f32 = 75, // 8 x f32
- v16f32 = 76, // 16 x f32
- v32f32 = 77, // 32 x f32
- v64f32 = 78, // 64 x f32
- v128f32 = 79, // 128 x f32
- v256f32 = 80, // 256 x f32
- v512f32 = 81, // 512 x f32
- v1024f32 = 82, // 1024 x f32
- v2048f32 = 83, // 2048 x f32
- v1f64 = 84, // 1 x f64
- v2f64 = 85, // 2 x f64
- v4f64 = 86, // 4 x f64
- v8f64 = 87, // 8 x f64
+ v2f16 = 65, // 2 x f16
+ v3f16 = 66, // 3 x f16
+ v4f16 = 67, // 4 x f16
+ v8f16 = 68, // 8 x f16
+ v16f16 = 69, // 16 x f16
+ v32f16 = 70, // 32 x f16
+ v64f16 = 71, // 64 x f16
+ v128f16 = 72, // 128 x f16
+ v2bf16 = 73, // 2 x bf16
+ v3bf16 = 74, // 3 x bf16
+ v4bf16 = 75, // 4 x bf16
+ v8bf16 = 76, // 8 x bf16
+ v16bf16 = 77, // 16 x bf16
+ v32bf16 = 78, // 32 x bf16
+ v64bf16 = 79, // 64 x bf16
+ v128bf16 = 80, // 128 x bf16
+ v1f32 = 81, // 1 x f32
+ v2f32 = 82, // 2 x f32
+ v3f32 = 83, // 3 x f32
+ v4f32 = 84, // 4 x f32
+ v5f32 = 85, // 5 x f32
+ v8f32 = 86, // 8 x f32
+ v16f32 = 87, // 16 x f32
+ v32f32 = 88, // 32 x f32
+ v64f32 = 89, // 64 x f32
+ v128f32 = 90, // 128 x f32
+ v256f32 = 91, // 256 x f32
+ v512f32 = 92, // 512 x f32
+ v1024f32 = 93, // 1024 x f32
+ v2048f32 = 94, // 2048 x f32
+ v1f64 = 95, // 1 x f64
+ v2f64 = 96, // 2 x f64
+ v4f64 = 97, // 4 x f64
+ v8f64 = 98, // 8 x f64
+ v16f64 = 99, // 16 x f64
+ v32f64 = 100, // 32 x f64
FIRST_FP_FIXEDLEN_VECTOR_VALUETYPE = v2f16,
- LAST_FP_FIXEDLEN_VECTOR_VALUETYPE = v8f64,
+ LAST_FP_FIXEDLEN_VECTOR_VALUETYPE = v32f64,
FIRST_FIXEDLEN_VECTOR_VALUETYPE = v1i1,
- LAST_FIXEDLEN_VECTOR_VALUETYPE = v8f64,
-
- nxv1i1 = 88, // n x 1 x i1
- nxv2i1 = 89, // n x 2 x i1
- nxv4i1 = 90, // n x 4 x i1
- nxv8i1 = 91, // n x 8 x i1
- nxv16i1 = 92, // n x 16 x i1
- nxv32i1 = 93, // n x 32 x i1
-
- nxv1i8 = 94, // n x 1 x i8
- nxv2i8 = 95, // n x 2 x i8
- nxv4i8 = 96, // n x 4 x i8
- nxv8i8 = 97, // n x 8 x i8
- nxv16i8 = 98, // n x 16 x i8
- nxv32i8 = 99, // n x 32 x i8
-
- nxv1i16 = 100, // n x 1 x i16
- nxv2i16 = 101, // n x 2 x i16
- nxv4i16 = 102, // n x 4 x i16
- nxv8i16 = 103, // n x 8 x i16
- nxv16i16 = 104, // n x 16 x i16
- nxv32i16 = 105, // n x 32 x i16
-
- nxv1i32 = 106, // n x 1 x i32
- nxv2i32 = 107, // n x 2 x i32
- nxv4i32 = 108, // n x 4 x i32
- nxv8i32 = 109, // n x 8 x i32
- nxv16i32 = 110, // n x 16 x i32
- nxv32i32 = 111, // n x 32 x i32
-
- nxv1i64 = 112, // n x 1 x i64
- nxv2i64 = 113, // n x 2 x i64
- nxv4i64 = 114, // n x 4 x i64
- nxv8i64 = 115, // n x 8 x i64
- nxv16i64 = 116, // n x 16 x i64
- nxv32i64 = 117, // n x 32 x i64
+ LAST_FIXEDLEN_VECTOR_VALUETYPE = v32f64,
+
+ nxv1i1 = 101, // n x 1 x i1
+ nxv2i1 = 102, // n x 2 x i1
+ nxv4i1 = 103, // n x 4 x i1
+ nxv8i1 = 104, // n x 8 x i1
+ nxv16i1 = 105, // n x 16 x i1
+ nxv32i1 = 106, // n x 32 x i1
+ nxv64i1 = 107, // n x 64 x i1
+
+ nxv1i8 = 108, // n x 1 x i8
+ nxv2i8 = 109, // n x 2 x i8
+ nxv4i8 = 110, // n x 4 x i8
+ nxv8i8 = 111, // n x 8 x i8
+ nxv16i8 = 112, // n x 16 x i8
+ nxv32i8 = 113, // n x 32 x i8
+ nxv64i8 = 114, // n x 64 x i8
+
+ nxv1i16 = 115, // n x 1 x i16
+ nxv2i16 = 116, // n x 2 x i16
+ nxv4i16 = 117, // n x 4 x i16
+ nxv8i16 = 118, // n x 8 x i16
+ nxv16i16 = 119, // n x 16 x i16
+ nxv32i16 = 120, // n x 32 x i16
+
+ nxv1i32 = 121, // n x 1 x i32
+ nxv2i32 = 122, // n x 2 x i32
+ nxv4i32 = 123, // n x 4 x i32
+ nxv8i32 = 124, // n x 8 x i32
+ nxv16i32 = 125, // n x 16 x i32
+ nxv32i32 = 126, // n x 32 x i32
+
+ nxv1i64 = 127, // n x 1 x i64
+ nxv2i64 = 128, // n x 2 x i64
+ nxv4i64 = 129, // n x 4 x i64
+ nxv8i64 = 130, // n x 8 x i64
+ nxv16i64 = 131, // n x 16 x i64
+ nxv32i64 = 132, // n x 32 x i64
FIRST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv1i1,
LAST_INTEGER_SCALABLE_VECTOR_VALUETYPE = nxv32i64,
- nxv2f16 = 118, // n x 2 x f16
- nxv4f16 = 119, // n x 4 x f16
- nxv8f16 = 120, // n x 8 x f16
- nxv1f32 = 121, // n x 1 x f32
- nxv2f32 = 122, // n x 2 x f32
- nxv4f32 = 123, // n x 4 x f32
- nxv8f32 = 124, // n x 8 x f32
- nxv16f32 = 125, // n x 16 x f32
- nxv1f64 = 126, // n x 1 x f64
- nxv2f64 = 127, // n x 2 x f64
- nxv4f64 = 128, // n x 4 x f64
- nxv8f64 = 129, // n x 8 x f64
-
- FIRST_FP_SCALABLE_VECTOR_VALUETYPE = nxv2f16,
+ nxv1f16 = 133, // n x 1 x f16
+ nxv2f16 = 134, // n x 2 x f16
+ nxv4f16 = 135, // n x 4 x f16
+ nxv8f16 = 136, // n x 8 x f16
+ nxv16f16 = 137, // n x 16 x f16
+ nxv32f16 = 138, // n x 32 x f16
+ nxv2bf16 = 139, // n x 2 x bf16
+ nxv4bf16 = 140, // n x 4 x bf16
+ nxv8bf16 = 141, // n x 8 x bf16
+ nxv1f32 = 142, // n x 1 x f32
+ nxv2f32 = 143, // n x 2 x f32
+ nxv4f32 = 144, // n x 4 x f32
+ nxv8f32 = 145, // n x 8 x f32
+ nxv16f32 = 146, // n x 16 x f32
+ nxv1f64 = 147, // n x 1 x f64
+ nxv2f64 = 148, // n x 2 x f64
+ nxv4f64 = 149, // n x 4 x f64
+ nxv8f64 = 150, // n x 8 x f64
+
+ FIRST_FP_SCALABLE_VECTOR_VALUETYPE = nxv1f16,
LAST_FP_SCALABLE_VECTOR_VALUETYPE = nxv8f64,
FIRST_SCALABLE_VECTOR_VALUETYPE = nxv1i1,
@@ -207,20 +228,20 @@ namespace llvm {
FIRST_VECTOR_VALUETYPE = v1i1,
LAST_VECTOR_VALUETYPE = nxv8f64,
- x86mmx = 130, // This is an X86 MMX value
+ x86mmx = 151, // This is an X86 MMX value
- Glue = 131, // This glues nodes together during pre-RA sched
+ Glue = 152, // This glues nodes together during pre-RA sched
- isVoid = 132, // This has no value
+ isVoid = 153, // This has no value
- Untyped = 133, // This value takes a register, but has
- // unspecified type. The register class
- // will be determined by the opcode.
+ Untyped = 154, // This value takes a register, but has
+ // unspecified type. The register class
+ // will be determined by the opcode.
- exnref = 134, // WebAssembly's exnref type
+ exnref = 155, // WebAssembly's exnref type
- FIRST_VALUETYPE = 1, // This is always the beginning of the list.
- LAST_VALUETYPE = 135, // This always remains at the end of the list.
+ FIRST_VALUETYPE = 1, // This is always the beginning of the list.
+ LAST_VALUETYPE = 156, // This always remains at the end of the list.
// This is the current maximum for LAST_VALUETYPE.
// MVT::MAX_ALLOWED_VALUETYPE is used for asserts and to size bit vectors
@@ -332,17 +353,19 @@ namespace llvm {
/// Return true if this is a 32-bit vector type.
bool is32BitVector() const {
- return (SimpleTy == MVT::v32i1 || SimpleTy == MVT::v4i8 ||
- SimpleTy == MVT::v2i16 || SimpleTy == MVT::v1i32 ||
- SimpleTy == MVT::v2f16 || SimpleTy == MVT::v1f32);
+ return (SimpleTy == MVT::v32i1 || SimpleTy == MVT::v4i8 ||
+ SimpleTy == MVT::v2i16 || SimpleTy == MVT::v1i32 ||
+ SimpleTy == MVT::v2f16 || SimpleTy == MVT::v2bf16 ||
+ SimpleTy == MVT::v1f32);
}
/// Return true if this is a 64-bit vector type.
bool is64BitVector() const {
- return (SimpleTy == MVT::v64i1 || SimpleTy == MVT::v8i8 ||
- SimpleTy == MVT::v4i16 || SimpleTy == MVT::v2i32 ||
- SimpleTy == MVT::v1i64 || SimpleTy == MVT::v4f16 ||
- SimpleTy == MVT::v2f32 || SimpleTy == MVT::v1f64);
+ return (SimpleTy == MVT::v64i1 || SimpleTy == MVT::v8i8 ||
+ SimpleTy == MVT::v4i16 || SimpleTy == MVT::v2i32 ||
+ SimpleTy == MVT::v1i64 || SimpleTy == MVT::v4f16 ||
+ SimpleTy == MVT::v4bf16 ||SimpleTy == MVT::v2f32 ||
+ SimpleTy == MVT::v1f64);
}
/// Return true if this is a 128-bit vector type.
@@ -350,44 +373,50 @@ namespace llvm {
return (SimpleTy == MVT::v128i1 || SimpleTy == MVT::v16i8 ||
SimpleTy == MVT::v8i16 || SimpleTy == MVT::v4i32 ||
SimpleTy == MVT::v2i64 || SimpleTy == MVT::v1i128 ||
- SimpleTy == MVT::v8f16 || SimpleTy == MVT::v4f32 ||
- SimpleTy == MVT::v2f64);
+ SimpleTy == MVT::v8f16 || SimpleTy == MVT::v8bf16 ||
+ SimpleTy == MVT::v4f32 || SimpleTy == MVT::v2f64);
}
/// Return true if this is a 256-bit vector type.
bool is256BitVector() const {
- return (SimpleTy == MVT::v16f16 || SimpleTy == MVT::v8f32 ||
- SimpleTy == MVT::v4f64 || SimpleTy == MVT::v32i8 ||
- SimpleTy == MVT::v16i16 || SimpleTy == MVT::v8i32 ||
- SimpleTy == MVT::v4i64 || SimpleTy == MVT::v256i1);
+ return (SimpleTy == MVT::v16f16 || SimpleTy == MVT::v16bf16 ||
+ SimpleTy == MVT::v8f32 || SimpleTy == MVT::v4f64 ||
+ SimpleTy == MVT::v32i8 || SimpleTy == MVT::v16i16 ||
+ SimpleTy == MVT::v8i32 || SimpleTy == MVT::v4i64 ||
+ SimpleTy == MVT::v256i1);
}
/// Return true if this is a 512-bit vector type.
bool is512BitVector() const {
- return (SimpleTy == MVT::v32f16 || SimpleTy == MVT::v16f32 ||
- SimpleTy == MVT::v8f64 || SimpleTy == MVT::v512i1 ||
- SimpleTy == MVT::v64i8 || SimpleTy == MVT::v32i16 ||
- SimpleTy == MVT::v16i32 || SimpleTy == MVT::v8i64);
+ return (SimpleTy == MVT::v32f16 || SimpleTy == MVT::v32bf16 ||
+ SimpleTy == MVT::v16f32 || SimpleTy == MVT::v8f64 ||
+ SimpleTy == MVT::v512i1 || SimpleTy == MVT::v64i8 ||
+ SimpleTy == MVT::v32i16 || SimpleTy == MVT::v16i32 ||
+ SimpleTy == MVT::v8i64);
}
/// Return true if this is a 1024-bit vector type.
bool is1024BitVector() const {
return (SimpleTy == MVT::v1024i1 || SimpleTy == MVT::v128i8 ||
SimpleTy == MVT::v64i16 || SimpleTy == MVT::v32i32 ||
- SimpleTy == MVT::v16i64);
+ SimpleTy == MVT::v16i64 || SimpleTy == MVT::v64f16 ||
+ SimpleTy == MVT::v32f32 || SimpleTy == MVT::v16f64 ||
+ SimpleTy == MVT::v64bf16);
}
/// Return true if this is a 2048-bit vector type.
bool is2048BitVector() const {
- return (SimpleTy == MVT::v256i8 || SimpleTy == MVT::v128i16 ||
- SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64);
+ return (SimpleTy == MVT::v256i8 || SimpleTy == MVT::v128i16 ||
+ SimpleTy == MVT::v64i32 || SimpleTy == MVT::v32i64 ||
+ SimpleTy == MVT::v128f16 || SimpleTy == MVT::v64f32 ||
+ SimpleTy == MVT::v32f64 || SimpleTy == MVT::v128bf16);
}
/// Return true if this is an overloaded type for TableGen.
bool isOverloaded() const {
- return (SimpleTy==MVT::Any ||
- SimpleTy==MVT::iAny || SimpleTy==MVT::fAny ||
- SimpleTy==MVT::vAny || SimpleTy==MVT::iPTRAny);
+ return (SimpleTy == MVT::Any || SimpleTy == MVT::iAny ||
+ SimpleTy == MVT::fAny || SimpleTy == MVT::vAny ||
+ SimpleTy == MVT::iPTRAny);
}
/// Return a VT for a vector type with the same element type but
@@ -441,7 +470,8 @@ namespace llvm {
case nxv4i1:
case nxv8i1:
case nxv16i1:
- case nxv32i1: return i1;
+ case nxv32i1:
+ case nxv64i1: return i1;
case v1i8:
case v2i8:
case v4i8:
@@ -456,7 +486,8 @@ namespace llvm {
case nxv4i8:
case nxv8i8:
case nxv16i8:
- case nxv32i8: return i8;
+ case nxv32i8:
+ case nxv64i8: return i8;
case v1i16:
case v2i16:
case v3i16:
@@ -511,9 +542,25 @@ namespace llvm {
case v8f16:
case v16f16:
case v32f16:
+ case v64f16:
+ case v128f16:
+ case nxv1f16:
case nxv2f16:
case nxv4f16:
- case nxv8f16: return f16;
+ case nxv8f16:
+ case nxv16f16:
+ case nxv32f16: return f16;
+ case v2bf16:
+ case v3bf16:
+ case v4bf16:
+ case v8bf16:
+ case v16bf16:
+ case v32bf16:
+ case v64bf16:
+ case v128bf16:
+ case nxv2bf16:
+ case nxv4bf16:
+ case nxv8bf16: return bf16;
case v1f32:
case v2f32:
case v3f32:
@@ -537,6 +584,8 @@ namespace llvm {
case v2f64:
case v4f64:
case v8f64:
+ case v16f64:
+ case v32f64:
case nxv1f64:
case nxv2f64:
case nxv4f64:
@@ -564,36 +613,48 @@ namespace llvm {
case v128i8:
case v128i16:
case v128i32:
+ case v128f16:
+ case v128bf16:
case v128f32: return 128;
case v64i1:
case v64i8:
case v64i16:
case v64i32:
- case v64f32: return 64;
+ case v64f16:
+ case v64bf16:
+ case v64f32:
+ case nxv64i1:
+ case nxv64i8: return 64;
case v32i1:
case v32i8:
case v32i16:
case v32i32:
case v32i64:
case v32f16:
+ case v32bf16:
case v32f32:
+ case v32f64:
case nxv32i1:
case nxv32i8:
case nxv32i16:
case nxv32i32:
- case nxv32i64: return 32;
+ case nxv32i64:
+ case nxv32f16: return 32;
case v16i1:
case v16i8:
case v16i16:
case v16i32:
case v16i64:
case v16f16:
+ case v16bf16:
case v16f32:
+ case v16f64:
case nxv16i1:
case nxv16i8:
case nxv16i16:
case nxv16i32:
case nxv16i64:
+ case nxv16f16:
case nxv16f32: return 16;
case v8i1:
case v8i8:
@@ -601,6 +662,7 @@ namespace llvm {
case v8i32:
case v8i64:
case v8f16:
+ case v8bf16:
case v8f32:
case v8f64:
case nxv8i1:
@@ -609,6 +671,7 @@ namespace llvm {
case nxv8i32:
case nxv8i64:
case nxv8f16:
+ case nxv8bf16:
case nxv8f32:
case nxv8f64: return 8;
case v5i32:
@@ -619,6 +682,7 @@ namespace llvm {
case v4i32:
case v4i64:
case v4f16:
+ case v4bf16:
case v4f32:
case v4f64:
case nxv4i1:
@@ -627,11 +691,13 @@ namespace llvm {
case nxv4i32:
case nxv4i64:
case nxv4f16:
+ case nxv4bf16:
case nxv4f32:
case nxv4f64: return 4;
case v3i16:
case v3i32:
case v3f16:
+ case v3bf16:
case v3f32: return 3;
case v2i1:
case v2i8:
@@ -639,6 +705,7 @@ namespace llvm {
case v2i32:
case v2i64:
case v2f16:
+ case v2bf16:
case v2f32:
case v2f64:
case nxv2i1:
@@ -647,6 +714,7 @@ namespace llvm {
case nxv2i32:
case nxv2i64:
case nxv2f16:
+ case nxv2bf16:
case nxv2f32:
case nxv2f64: return 2;
case v1i1:
@@ -662,6 +730,7 @@ namespace llvm {
case nxv1i16:
case nxv1i32:
case nxv1i64:
+ case nxv1f16:
case nxv1f32:
case nxv1f64: return 1;
}
@@ -671,6 +740,11 @@ namespace llvm {
return { getVectorNumElements(), isScalableVector() };
}
+ /// Given a vector type, return the minimum number of elements it contains.
+ unsigned getVectorMinNumElements() const {
+ return getVectorElementCount().Min;
+ }
+
/// Returns the size of the specified MVT in bits.
///
/// If the value type is a scalable vector type, the scalable property will
@@ -709,18 +783,21 @@ namespace llvm {
case nxv8i1: return TypeSize::Scalable(8);
case i16 :
case f16:
+ case bf16:
case v16i1:
case v2i8:
case v1i16: return TypeSize::Fixed(16);
case nxv16i1:
case nxv2i8:
- case nxv1i16: return TypeSize::Scalable(16);
+ case nxv1i16:
+ case nxv1f16: return TypeSize::Scalable(16);
case f32 :
case i32 :
case v32i1:
case v4i8:
case v2i16:
case v2f16:
+ case v2bf16:
case v1f32:
case v1i32: return TypeSize::Fixed(32);
case nxv32i1:
@@ -728,9 +805,11 @@ namespace llvm {
case nxv2i16:
case nxv1i32:
case nxv2f16:
+ case nxv2bf16:
case nxv1f32: return TypeSize::Scalable(32);
case v3i16:
- case v3f16: return TypeSize::Fixed(48);
+ case v3f16:
+ case v3bf16: return TypeSize::Fixed(48);
case x86mmx:
case f64 :
case i64 :
@@ -740,13 +819,16 @@ namespace llvm {
case v2i32:
case v1i64:
case v4f16:
+ case v4bf16:
case v2f32:
case v1f64: return TypeSize::Fixed(64);
+ case nxv64i1:
case nxv8i8:
case nxv4i16:
case nxv2i32:
case nxv1i64:
case nxv4f16:
+ case nxv4bf16:
case nxv2f32:
case nxv1f64: return TypeSize::Scalable(64);
case f80 : return TypeSize::Fixed(80);
@@ -762,6 +844,7 @@ namespace llvm {
case v2i64:
case v1i128:
case v8f16:
+ case v8bf16:
case v4f32:
case v2f64: return TypeSize::Fixed(128);
case nxv16i8:
@@ -769,6 +852,7 @@ namespace llvm {
case nxv4i32:
case nxv2i64:
case nxv8f16:
+ case nxv8bf16:
case nxv4f32:
case nxv2f64: return TypeSize::Scalable(128);
case v5i32:
@@ -779,12 +863,14 @@ namespace llvm {
case v8i32:
case v4i64:
case v16f16:
+ case v16bf16:
case v8f32:
case v4f64: return TypeSize::Fixed(256);
case nxv32i8:
case nxv16i16:
case nxv8i32:
case nxv4i64:
+ case nxv16f16:
case nxv8f32:
case nxv4f64: return TypeSize::Scalable(256);
case v512i1:
@@ -793,11 +879,14 @@ namespace llvm {
case v16i32:
case v8i64:
case v32f16:
+ case v32bf16:
case v16f32:
case v8f64: return TypeSize::Fixed(512);
+ case nxv64i8:
case nxv32i16:
case nxv16i32:
case nxv8i64:
+ case nxv32f16:
case nxv16f32:
case nxv8f64: return TypeSize::Scalable(512);
case v1024i1:
@@ -805,14 +894,20 @@ namespace llvm {
case v64i16:
case v32i32:
case v16i64:
- case v32f32: return TypeSize::Fixed(1024);
+ case v64f16:
+ case v64bf16:
+ case v32f32:
+ case v16f64: return TypeSize::Fixed(1024);
case nxv32i32:
case nxv16i64: return TypeSize::Scalable(1024);
case v256i8:
case v128i16:
case v64i32:
case v32i64:
- case v64f32: return TypeSize::Fixed(2048);
+ case v128f16:
+ case v128bf16:
+ case v64f32:
+ case v32f64: return TypeSize::Fixed(2048);
case nxv32i64: return TypeSize::Scalable(2048);
case v128i32:
case v128f32: return TypeSize::Fixed(4096);
@@ -982,12 +1077,24 @@ namespace llvm {
if (NumElements == 1) return MVT::v1i128;
break;
case MVT::f16:
- if (NumElements == 2) return MVT::v2f16;
- if (NumElements == 3) return MVT::v3f16;
- if (NumElements == 4) return MVT::v4f16;
- if (NumElements == 8) return MVT::v8f16;
- if (NumElements == 16) return MVT::v16f16;
- if (NumElements == 32) return MVT::v32f16;
+ if (NumElements == 2) return MVT::v2f16;
+ if (NumElements == 3) return MVT::v3f16;
+ if (NumElements == 4) return MVT::v4f16;
+ if (NumElements == 8) return MVT::v8f16;
+ if (NumElements == 16) return MVT::v16f16;
+ if (NumElements == 32) return MVT::v32f16;
+ if (NumElements == 64) return MVT::v64f16;
+ if (NumElements == 128) return MVT::v128f16;
+ break;
+ case MVT::bf16:
+ if (NumElements == 2) return MVT::v2bf16;
+ if (NumElements == 3) return MVT::v3bf16;
+ if (NumElements == 4) return MVT::v4bf16;
+ if (NumElements == 8) return MVT::v8bf16;
+ if (NumElements == 16) return MVT::v16bf16;
+ if (NumElements == 32) return MVT::v32bf16;
+ if (NumElements == 64) return MVT::v64bf16;
+ if (NumElements == 128) return MVT::v128bf16;
break;
case MVT::f32:
if (NumElements == 1) return MVT::v1f32;
@@ -1010,6 +1117,8 @@ namespace llvm {
if (NumElements == 2) return MVT::v2f64;
if (NumElements == 4) return MVT::v4f64;
if (NumElements == 8) return MVT::v8f64;
+ if (NumElements == 16) return MVT::v16f64;
+ if (NumElements == 32) return MVT::v32f64;
break;
}
return (MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE);
@@ -1026,6 +1135,7 @@ namespace llvm {
if (NumElements == 8) return MVT::nxv8i1;
if (NumElements == 16) return MVT::nxv16i1;
if (NumElements == 32) return MVT::nxv32i1;
+ if (NumElements == 64) return MVT::nxv64i1;
break;
case MVT::i8:
if (NumElements == 1) return MVT::nxv1i8;
@@ -1034,6 +1144,7 @@ namespace llvm {
if (NumElements == 8) return MVT::nxv8i8;
if (NumElements == 16) return MVT::nxv16i8;
if (NumElements == 32) return MVT::nxv32i8;
+ if (NumElements == 64) return MVT::nxv64i8;
break;
case MVT::i16:
if (NumElements == 1) return MVT::nxv1i16;
@@ -1060,9 +1171,17 @@ namespace llvm {
if (NumElements == 32) return MVT::nxv32i64;
break;
case MVT::f16:
+ if (NumElements == 1) return MVT::nxv1f16;
if (NumElements == 2) return MVT::nxv2f16;
if (NumElements == 4) return MVT::nxv4f16;
if (NumElements == 8) return MVT::nxv8f16;
+ if (NumElements == 16) return MVT::nxv16f16;
+ if (NumElements == 32) return MVT::nxv32f16;
+ break;
+ case MVT::bf16:
+ if (NumElements == 2) return MVT::nxv2bf16;
+ if (NumElements == 4) return MVT::nxv4bf16;
+ if (NumElements == 8) return MVT::nxv8bf16;
break;
case MVT::f32:
if (NumElements == 1) return MVT::nxv1f32;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MathExtras.h b/contrib/llvm-project/llvm/include/llvm/Support/MathExtras.h
index 37b9669cbeed..16da3046c8ce 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MathExtras.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MathExtras.h
@@ -14,10 +14,11 @@
#define LLVM_SUPPORT_MATHEXTRAS_H
#include "llvm/Support/Compiler.h"
-#include "llvm/Support/SwapByteOrder.h"
#include <algorithm>
#include <cassert>
#include <climits>
+#include <cmath>
+#include <cstdint>
#include <cstring>
#include <limits>
#include <type_traits>
@@ -312,6 +313,34 @@ T reverseBits(T Val) {
return Val;
}
+#if __has_builtin(__builtin_bitreverse8)
+template<>
+inline uint8_t reverseBits<uint8_t>(uint8_t Val) {
+ return __builtin_bitreverse8(Val);
+}
+#endif
+
+#if __has_builtin(__builtin_bitreverse16)
+template<>
+inline uint16_t reverseBits<uint16_t>(uint16_t Val) {
+ return __builtin_bitreverse16(Val);
+}
+#endif
+
+#if __has_builtin(__builtin_bitreverse32)
+template<>
+inline uint32_t reverseBits<uint32_t>(uint32_t Val) {
+ return __builtin_bitreverse32(Val);
+}
+#endif
+
+#if __has_builtin(__builtin_bitreverse64)
+template<>
+inline uint64_t reverseBits<uint64_t>(uint64_t Val) {
+ return __builtin_bitreverse64(Val);
+}
+#endif
+
// NOTE: The following support functions use the _32/_64 extensions instead of
// type overloading so that signed and unsigned integers can be used without
// ambiguity.
@@ -364,14 +393,12 @@ constexpr inline bool isShiftedInt(int64_t x) {
/// to keep MSVC from (incorrectly) warning on isUInt<64> that we're shifting
/// left too many places.
template <unsigned N>
-constexpr inline typename std::enable_if<(N < 64), bool>::type
-isUInt(uint64_t X) {
+constexpr inline std::enable_if_t<(N < 64), bool> isUInt(uint64_t X) {
static_assert(N > 0, "isUInt<0> doesn't make sense");
return X < (UINT64_C(1) << (N));
}
template <unsigned N>
-constexpr inline typename std::enable_if<N >= 64, bool>::type
-isUInt(uint64_t X) {
+constexpr inline std::enable_if_t<N >= 64, bool> isUInt(uint64_t X) {
return true;
}
@@ -471,21 +498,6 @@ constexpr inline bool isPowerOf2_64(uint64_t Value) {
return Value && !(Value & (Value - 1));
}
-/// Return a byte-swapped representation of the 16-bit argument.
-inline uint16_t ByteSwap_16(uint16_t Value) {
- return sys::SwapByteOrder_16(Value);
-}
-
-/// Return a byte-swapped representation of the 32-bit argument.
-inline uint32_t ByteSwap_32(uint32_t Value) {
- return sys::SwapByteOrder_32(Value);
-}
-
-/// Return a byte-swapped representation of the 64-bit argument.
-inline uint64_t ByteSwap_64(uint64_t Value) {
- return sys::SwapByteOrder_64(Value);
-}
-
/// Count the number of ones from the most significant bit to the first
/// zero bit.
///
@@ -780,8 +792,7 @@ inline int64_t SignExtend64(uint64_t X, unsigned B) {
/// Subtract two unsigned integers, X and Y, of type T and return the absolute
/// value of the result.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, T>::type
-AbsoluteDifference(T X, T Y) {
+std::enable_if_t<std::is_unsigned<T>::value, T> AbsoluteDifference(T X, T Y) {
return std::max(X, Y) - std::min(X, Y);
}
@@ -789,7 +800,7 @@ AbsoluteDifference(T X, T Y) {
/// maximum representable value of T on overflow. ResultOverflowed indicates if
/// the result is larger than the maximum representable value of type T.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, T>::type
+std::enable_if_t<std::is_unsigned<T>::value, T>
SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
@@ -806,7 +817,7 @@ SaturatingAdd(T X, T Y, bool *ResultOverflowed = nullptr) {
/// maximum representable value of T on overflow. ResultOverflowed indicates if
/// the result is larger than the maximum representable value of type T.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, T>::type
+std::enable_if_t<std::is_unsigned<T>::value, T>
SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
@@ -852,7 +863,7 @@ SaturatingMultiply(T X, T Y, bool *ResultOverflowed = nullptr) {
/// overflow. ResultOverflowed indicates if the result is larger than the
/// maximum representable value of type T.
template <typename T>
-typename std::enable_if<std::is_unsigned<T>::value, T>::type
+std::enable_if_t<std::is_unsigned<T>::value, T>
SaturatingMultiplyAdd(T X, T Y, T A, bool *ResultOverflowed = nullptr) {
bool Dummy;
bool &Overflowed = ResultOverflowed ? *ResultOverflowed : Dummy;
@@ -871,13 +882,12 @@ extern const float huge_valf;
/// Add two signed integers, computing the two's complement truncated result,
/// returning true if overflow occured.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, T>::type
-AddOverflow(T X, T Y, T &Result) {
+std::enable_if_t<std::is_signed<T>::value, T> AddOverflow(T X, T Y, T &Result) {
#if __has_builtin(__builtin_add_overflow)
return __builtin_add_overflow(X, Y, &Result);
#else
// Perform the unsigned addition.
- using U = typename std::make_unsigned<T>::type;
+ using U = std::make_unsigned_t<T>;
const U UX = static_cast<U>(X);
const U UY = static_cast<U>(Y);
const U UResult = UX + UY;
@@ -898,13 +908,12 @@ AddOverflow(T X, T Y, T &Result) {
/// Subtract two signed integers, computing the two's complement truncated
/// result, returning true if an overflow ocurred.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, T>::type
-SubOverflow(T X, T Y, T &Result) {
+std::enable_if_t<std::is_signed<T>::value, T> SubOverflow(T X, T Y, T &Result) {
#if __has_builtin(__builtin_sub_overflow)
return __builtin_sub_overflow(X, Y, &Result);
#else
// Perform the unsigned addition.
- using U = typename std::make_unsigned<T>::type;
+ using U = std::make_unsigned_t<T>;
const U UX = static_cast<U>(X);
const U UY = static_cast<U>(Y);
const U UResult = UX - UY;
@@ -922,14 +931,12 @@ SubOverflow(T X, T Y, T &Result) {
#endif
}
-
/// Multiply two signed integers, computing the two's complement truncated
/// result, returning true if an overflow ocurred.
template <typename T>
-typename std::enable_if<std::is_signed<T>::value, T>::type
-MulOverflow(T X, T Y, T &Result) {
+std::enable_if_t<std::is_signed<T>::value, T> MulOverflow(T X, T Y, T &Result) {
// Perform the unsigned multiplication on absolute values.
- using U = typename std::make_unsigned<T>::type;
+ using U = std::make_unsigned_t<T>;
const U UX = X < 0 ? (0 - static_cast<U>(X)) : static_cast<U>(X);
const U UY = Y < 0 ? (0 - static_cast<U>(Y)) : static_cast<U>(Y);
const U UResult = UX * UY;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MemAlloc.h b/contrib/llvm-project/llvm/include/llvm/Support/MemAlloc.h
index 0e5869141fd3..d6012bd5a698 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MemAlloc.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MemAlloc.h
@@ -62,5 +62,26 @@ LLVM_ATTRIBUTE_RETURNS_NONNULL inline void *safe_realloc(void *Ptr, size_t Sz) {
return Result;
}
-}
+/// Allocate a buffer of memory with the given size and alignment.
+///
+/// When the compiler supports aligned operator new, this will use it to to
+/// handle even over-aligned allocations.
+///
+/// However, this doesn't make any attempt to leverage the fancier techniques
+/// like posix_memalign due to portability. It is mostly intended to allow
+/// compatibility with platforms that, after aligned allocation was added, use
+/// reduced default alignment.
+LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void *
+allocate_buffer(size_t Size, size_t Alignment);
+
+/// Deallocate a buffer of memory with the given size and alignment.
+///
+/// If supported, this will used the sized delete operator. Also if supported,
+/// this will pass the alignment to the delete operator.
+///
+/// The pointer must have been allocated with the corresponding new operator,
+/// most likely using the above helper.
+void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment);
+
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/MemoryBuffer.h b/contrib/llvm-project/llvm/include/llvm/Support/MemoryBuffer.h
index b5196cd84cb4..f47a8d2d334b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/MemoryBuffer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/MemoryBuffer.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
#include <cstddef>
#include <cstdint>
#include <memory>
@@ -28,6 +27,18 @@ namespace llvm {
class MemoryBufferRef;
+namespace sys {
+namespace fs {
+// Duplicated from FileSystem.h to avoid a dependency.
+#if defined(_WIN32)
+// A Win32 HANDLE is a typedef of void*
+using file_t = void *;
+#else
+using file_t = int;
+#endif
+} // namespace fs
+} // namespace sys
+
/// This interface provides simple read-only access to a block of memory, and
/// provides simple methods for reading files and standard input into a memory
/// buffer. In addition to basic access to the characters in the file, this
@@ -48,9 +59,6 @@ protected:
void init(const char *BufStart, const char *BufEnd,
bool RequiresNullTerminator);
- static constexpr sys::fs::mapped_file_region::mapmode Mapmode =
- sys::fs::mapped_file_region::readonly;
-
public:
MemoryBuffer(const MemoryBuffer &) = delete;
MemoryBuffer &operator=(const MemoryBuffer &) = delete;
@@ -156,9 +164,6 @@ class WritableMemoryBuffer : public MemoryBuffer {
protected:
WritableMemoryBuffer() = default;
- static constexpr sys::fs::mapped_file_region::mapmode Mapmode =
- sys::fs::mapped_file_region::priv;
-
public:
using MemoryBuffer::getBuffer;
using MemoryBuffer::getBufferEnd;
@@ -218,9 +223,6 @@ class WriteThroughMemoryBuffer : public MemoryBuffer {
protected:
WriteThroughMemoryBuffer() = default;
- static constexpr sys::fs::mapped_file_region::mapmode Mapmode =
- sys::fs::mapped_file_region::readwrite;
-
public:
using MemoryBuffer::getBuffer;
using MemoryBuffer::getBufferEnd;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/NativeFormatting.h b/contrib/llvm-project/llvm/include/llvm/Support/NativeFormatting.h
index 825a44c77c00..e664d05f24db 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/NativeFormatting.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/NativeFormatting.h
@@ -10,11 +10,10 @@
#define LLVM_SUPPORT_NATIVE_FORMATTING_H
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/raw_ostream.h"
-
#include <cstdint>
namespace llvm {
+class raw_ostream;
enum class FloatStyle { Exponent, ExponentUpper, Fixed, Percent };
enum class IntegerStyle {
Integer,
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/OptimizedStructLayout.h b/contrib/llvm-project/llvm/include/llvm/Support/OptimizedStructLayout.h
new file mode 100644
index 000000000000..773ddfeaf13a
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/OptimizedStructLayout.h
@@ -0,0 +1,142 @@
+//===-- OptimizedStructLayout.h - Struct layout algorithm ---------*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file provides an interface for laying out a sequence of fields
+/// as a struct in a way that attempts to minimizes the total space
+/// requirements of the struct while still satisfying the layout
+/// requirements of the individual fields. The resulting layout may be
+/// substantially more compact than simply laying out the fields in their
+/// original order.
+///
+/// Fields may be pre-assigned fixed offsets. They may also be given sizes
+/// that are not multiples of their alignments. There is no currently no
+/// way to describe that a field has interior padding that other fields may
+/// be allocated into.
+///
+/// This algorithm does not claim to be "optimal" for several reasons:
+///
+/// - First, it does not guarantee that the result is minimal in size.
+/// There is no known efficient algoorithm to achieve minimality for
+/// unrestricted inputs. Nonetheless, this algorithm
+///
+/// - Second, there are other ways that a struct layout could be optimized
+/// besides space usage, such as locality. This layout may have a mixed
+/// impact on locality: less overall memory may be used, but adjacent
+/// fields in the original array may be moved further from one another.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
+#define LLVM_SUPPORT_OPTIMIZEDSTRUCTLAYOUT_H
+
+#include "llvm/Support/Alignment.h"
+#include "llvm/ADT/ArrayRef.h"
+#include <utility>
+
+namespace llvm {
+
+/// A field in a structure.
+struct OptimizedStructLayoutField {
+ /// A special value for Offset indicating that the field can be moved
+ /// anywhere.
+ static constexpr uint64_t FlexibleOffset = ~(uint64_t)0;
+
+ OptimizedStructLayoutField(const void *Id, uint64_t Size, Align Alignment,
+ uint64_t FixedOffset = FlexibleOffset)
+ : Offset(FixedOffset), Size(Size), Id(Id), Alignment(Alignment) {
+ assert(Size > 0 && "adding an empty field to the layout");
+ }
+
+ /// The offset of this field in the final layout. If this is
+ /// initialized to FlexibleOffset, layout will overwrite it with
+ /// the assigned offset of the field.
+ uint64_t Offset;
+
+ /// The required size of this field in bytes. Does not have to be
+ /// a multiple of Alignment. Must be non-zero.
+ uint64_t Size;
+
+ /// A opaque value which uniquely identifies this field.
+ const void *Id;
+
+ /// Private scratch space for the algorithm. The implementation
+ /// must treat this as uninitialized memory on entry.
+ void *Scratch;
+
+ /// The required alignment of this field.
+ Align Alignment;
+
+ /// Return true if this field has been assigned a fixed offset.
+ /// After layout, this will be true of all the fields.
+ bool hasFixedOffset() const {
+ return (Offset != FlexibleOffset);
+ }
+
+ /// Given that this field has a fixed offset, return the offset
+ /// of the first byte following it.
+ uint64_t getEndOffset() const {
+ assert(hasFixedOffset());
+ return Offset + Size;
+ }
+};
+
+/// Compute a layout for a struct containing the given fields, making a
+/// best-effort attempt to minimize the amount of space required.
+///
+/// Two features are supported which require a more careful solution
+/// than the well-known "sort by decreasing alignment" solution:
+///
+/// - Fields may be assigned a fixed offset in the layout. If there are
+/// gaps among the fixed-offset fields, the algorithm may attempt
+/// to allocate flexible-offset fields into those gaps. If that's
+/// undesirable, the caller should "block out" those gaps by e.g.
+/// just creating a single fixed-offset field that represents the
+/// entire "header".
+///
+/// - The size of a field is not required to be a multiple of, or even
+/// greater than, the field's required alignment. The only constraint
+/// on fields is that they must not be zero-sized.
+///
+/// To simplify the implementation, any fixed-offset fields in the
+/// layout must appear at the start of the field array, and they must
+/// be ordered by increasing offset.
+///
+/// The algorithm will produce a guaranteed-minimal layout with no
+/// interior padding in the following "C-style" case:
+///
+/// - every field's size is a multiple of its required alignment and
+/// - either no fields have initially fixed offsets, or the fixed-offset
+/// fields have no interior padding and end at an offset that is at
+/// least as aligned as all the flexible-offset fields.
+///
+/// Otherwise, while the algorithm will make a best-effort attempt to
+/// avoid padding, it cannot guarantee a minimal layout, as there is
+/// no known efficient algorithm for doing so.
+///
+/// The layout produced by this algorithm may not be stable across LLVM
+/// releases. Do not use this anywhere where ABI stability is required.
+///
+/// Flexible-offset fields with the same size and alignment will be ordered
+/// the same way they were in the initial array. Otherwise the current
+/// algorithm makes no effort to preserve the initial order of
+/// flexible-offset fields.
+///
+/// On return, all fields will have been assigned a fixed offset, and the
+/// array will be sorted in order of ascending offsets. Note that this
+/// means that the fixed-offset fields may no longer form a strict prefix
+/// if there's any padding before they end.
+///
+/// The return value is the total size of the struct and its required
+/// alignment. Note that the total size is not rounded up to a multiple
+/// of the required alignment; clients which require this can do so easily.
+std::pair<uint64_t, Align> performOptimizedStructLayout(
+ MutableArrayRef<OptimizedStructLayoutField> Fields);
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Parallel.h b/contrib/llvm-project/llvm/include/llvm/Support/Parallel.h
index 3c0ed2c11127..2c0edfbb1db5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Parallel.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Parallel.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Threading.h"
#include <algorithm>
#include <condition_variable>
@@ -21,17 +22,11 @@
namespace llvm {
namespace parallel {
-struct sequential_execution_policy {};
-struct parallel_execution_policy {};
-template <typename T>
-struct is_execution_policy
- : public std::integral_constant<
- bool, llvm::is_one_of<T, sequential_execution_policy,
- parallel_execution_policy>::value> {};
-
-constexpr sequential_execution_policy seq{};
-constexpr parallel_execution_policy par{};
+// Strategy for the default executor used by the parallel routines provided by
+// this file. It defaults to using all hardware threads and should be
+// initialized before the first use of parallel routines.
+extern ThreadPoolStrategy strategy;
namespace detail {
@@ -163,61 +158,58 @@ void parallel_for_each_n(IndexTy Begin, IndexTy End, FuncTy Fn) {
#endif
-template <typename Iter>
-using DefComparator =
- std::less<typename std::iterator_traits<Iter>::value_type>;
-
} // namespace detail
+} // namespace parallel
-// sequential algorithm implementations.
-template <class Policy, class RandomAccessIterator,
- class Comparator = detail::DefComparator<RandomAccessIterator>>
-void sort(Policy policy, RandomAccessIterator Start, RandomAccessIterator End,
- const Comparator &Comp = Comparator()) {
- static_assert(is_execution_policy<Policy>::value,
- "Invalid execution policy!");
+template <class RandomAccessIterator,
+ class Comparator = std::less<
+ typename std::iterator_traits<RandomAccessIterator>::value_type>>
+void parallelSort(RandomAccessIterator Start, RandomAccessIterator End,
+ const Comparator &Comp = Comparator()) {
+#if LLVM_ENABLE_THREADS
+ if (parallel::strategy.ThreadsRequested != 1) {
+ parallel::detail::parallel_sort(Start, End, Comp);
+ return;
+ }
+#endif
llvm::sort(Start, End, Comp);
}
-template <class Policy, class IterTy, class FuncTy>
-void for_each(Policy policy, IterTy Begin, IterTy End, FuncTy Fn) {
- static_assert(is_execution_policy<Policy>::value,
- "Invalid execution policy!");
+template <class IterTy, class FuncTy>
+void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) {
+#if LLVM_ENABLE_THREADS
+ if (parallel::strategy.ThreadsRequested != 1) {
+ parallel::detail::parallel_for_each(Begin, End, Fn);
+ return;
+ }
+#endif
std::for_each(Begin, End, Fn);
}
-template <class Policy, class IndexTy, class FuncTy>
-void for_each_n(Policy policy, IndexTy Begin, IndexTy End, FuncTy Fn) {
- static_assert(is_execution_policy<Policy>::value,
- "Invalid execution policy!");
- for (IndexTy I = Begin; I != End; ++I)
- Fn(I);
-}
-
-// Parallel algorithm implementations, only available when LLVM_ENABLE_THREADS
-// is true.
+template <class FuncTy>
+void parallelForEachN(size_t Begin, size_t End, FuncTy Fn) {
#if LLVM_ENABLE_THREADS
-template <class RandomAccessIterator,
- class Comparator = detail::DefComparator<RandomAccessIterator>>
-void sort(parallel_execution_policy policy, RandomAccessIterator Start,
- RandomAccessIterator End, const Comparator &Comp = Comparator()) {
- detail::parallel_sort(Start, End, Comp);
+ if (parallel::strategy.ThreadsRequested != 1) {
+ parallel::detail::parallel_for_each_n(Begin, End, Fn);
+ return;
+ }
+#endif
+ for (size_t I = Begin; I != End; ++I)
+ Fn(I);
}
-template <class IterTy, class FuncTy>
-void for_each(parallel_execution_policy policy, IterTy Begin, IterTy End,
- FuncTy Fn) {
- detail::parallel_for_each(Begin, End, Fn);
+// Range wrappers.
+template <class RangeTy,
+ class Comparator = std::less<decltype(*std::begin(RangeTy()))>>
+void parallelSort(RangeTy &&R, const Comparator &Comp = Comparator()) {
+ parallelSort(std::begin(R), std::end(R), Comp);
}
-template <class IndexTy, class FuncTy>
-void for_each_n(parallel_execution_policy policy, IndexTy Begin, IndexTy End,
- FuncTy Fn) {
- detail::parallel_for_each_n(Begin, End, Fn);
+template <class RangeTy, class FuncTy>
+void parallelForEach(RangeTy &&R, FuncTy Fn) {
+ parallelForEach(std::begin(R), std::end(R), Fn);
}
-#endif
-} // namespace parallel
} // namespace llvm
#endif // LLVM_SUPPORT_PARALLEL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Path.h b/contrib/llvm-project/llvm/include/llvm/Support/Path.h
index 97955f882d51..83bca5b70bc2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Path.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Path.h
@@ -47,7 +47,7 @@ enum class Style { windows, posix, native };
/// foo/ => foo,.
/// /foo/bar => /,foo,bar
/// ../ => ..,.
-/// C:\foo\bar => C:,/,foo,bar
+/// C:\foo\bar => C:,\,foo,bar
/// @endcode
class const_iterator
: public iterator_facade_base<const_iterator, std::input_iterator_tag,
@@ -153,32 +153,26 @@ void replace_extension(SmallVectorImpl<char> &path, const Twine &extension,
/// @code
/// /foo, /old, /new => /foo
/// /old, /old, /new => /new
-/// /old, /old/, /new, false => /old
-/// /old, /old/, /new, true => /new
+/// /old, /old/, /new => /old
/// /old/foo, /old, /new => /new/foo
/// /old/foo, /old/, /new => /new/foo
/// /old/foo, /old/, /new/ => /new/foo
/// /oldfoo, /old, /new => /oldfoo
/// /foo, <empty>, /new => /new/foo
/// /foo, <empty>, new => new/foo
-/// /old/foo, /old, <empty>, false => /foo
-/// /old/foo, /old, <empty>, true => foo
+/// /old/foo, /old, <empty> => /foo
/// @endcode
///
/// @param Path If \a Path starts with \a OldPrefix modify to instead
/// start with \a NewPrefix.
-/// @param OldPrefix The path prefix to strip from \a Path. Any trailing
-/// path separator is ignored if strict is true.
+/// @param OldPrefix The path prefix to strip from \a Path.
/// @param NewPrefix The path prefix to replace \a NewPrefix with.
-/// @param style The path separator style
-/// @param strict If strict is true, a directory separator following
-/// \a OldPrefix will also be stripped. Otherwise, directory
-/// separators will only be matched and stripped when present
-/// in \a OldPrefix.
+/// @param style The style used to match the prefix. Exact match using
+/// Posix style, case/separator insensitive match for Windows style.
/// @result true if \a Path begins with OldPrefix
-bool replace_path_prefix(SmallVectorImpl<char> &Path,
- const StringRef &OldPrefix, const StringRef &NewPrefix,
- Style style = Style::native, bool strict = false);
+bool replace_path_prefix(SmallVectorImpl<char> &Path, StringRef OldPrefix,
+ StringRef NewPrefix,
+ Style style = Style::native);
/// Append to path.
///
@@ -377,6 +371,20 @@ void system_temp_directory(bool erasedOnReboot, SmallVectorImpl<char> &result);
/// @result True if a home directory is set, false otherwise.
bool home_directory(SmallVectorImpl<char> &result);
+/// Get the directory where packages should read user-specific configurations.
+/// e.g. $XDG_CONFIG_HOME.
+///
+/// @param result Holds the resulting path name.
+/// @result True if the appropriate path was determined, it need not exist.
+bool user_config_directory(SmallVectorImpl<char> &result);
+
+/// Get the directory where installed packages should put their
+/// machine-local cache, e.g. $XDG_CACHE_HOME.
+///
+/// @param result Holds the resulting path name.
+/// @result True if the appropriate path was determined, it need not exist.
+bool cache_directory(SmallVectorImpl<char> &result);
+
/// Has root name?
///
/// root_name != ""
@@ -468,10 +476,6 @@ StringRef remove_leading_dotslash(StringRef path, Style style = Style::native);
bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot = false,
Style style = Style::native);
-#if defined(_WIN32)
-std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16);
-#endif
-
} // end namespace path
} // end namespace sys
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/PointerLikeTypeTraits.h b/contrib/llvm-project/llvm/include/llvm/Support/PointerLikeTypeTraits.h
index 1e7e5b53ca65..1b15f930bd87 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/PointerLikeTypeTraits.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/PointerLikeTypeTraits.h
@@ -15,7 +15,7 @@
#define LLVM_SUPPORT_POINTERLIKETYPETRAITS_H
#include "llvm/Support/DataTypes.h"
-#include <assert.h>
+#include <cassert>
#include <type_traits>
namespace llvm {
@@ -37,8 +37,9 @@ template <typename T, typename U = void> struct HasPointerLikeTypeTraits {
};
// sizeof(T) is valid only for a complete T.
-template <typename T> struct HasPointerLikeTypeTraits<
- T, decltype((sizeof(PointerLikeTypeTraits<T>) + sizeof(T)), void())> {
+template <typename T>
+struct HasPointerLikeTypeTraits<
+ T, decltype((sizeof(PointerLikeTypeTraits<T>) + sizeof(T)), void())> {
static const bool value = true;
};
@@ -56,7 +57,8 @@ template <typename T> struct PointerLikeTypeTraits<T *> {
static inline void *getAsVoidPointer(T *P) { return P; }
static inline T *getFromVoidPointer(void *P) { return static_cast<T *>(P); }
- enum { NumLowBitsAvailable = detail::ConstantLog2<alignof(T)>::value };
+ static constexpr int NumLowBitsAvailable =
+ detail::ConstantLog2<alignof(T)>::value;
};
template <> struct PointerLikeTypeTraits<void *> {
@@ -70,7 +72,7 @@ template <> struct PointerLikeTypeTraits<void *> {
///
/// All clients should use assertions to do a run-time check to ensure that
/// this is actually true.
- enum { NumLowBitsAvailable = 2 };
+ static constexpr int NumLowBitsAvailable = 2;
};
// Provide PointerLikeTypeTraits for const things.
@@ -83,7 +85,7 @@ template <typename T> struct PointerLikeTypeTraits<const T> {
static inline const T getFromVoidPointer(const void *P) {
return NonConst::getFromVoidPointer(const_cast<void *>(P));
}
- enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+ static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
};
// Provide PointerLikeTypeTraits for const pointers.
@@ -96,7 +98,7 @@ template <typename T> struct PointerLikeTypeTraits<const T *> {
static inline const T *getFromVoidPointer(const void *P) {
return NonConst::getFromVoidPointer(const_cast<void *>(P));
}
- enum { NumLowBitsAvailable = NonConst::NumLowBitsAvailable };
+ static constexpr int NumLowBitsAvailable = NonConst::NumLowBitsAvailable;
};
// Provide PointerLikeTypeTraits for uintptr_t.
@@ -108,7 +110,7 @@ template <> struct PointerLikeTypeTraits<uintptr_t> {
return reinterpret_cast<uintptr_t>(P);
}
// No bits are available!
- enum { NumLowBitsAvailable = 0 };
+ static constexpr int NumLowBitsAvailable = 0;
};
/// Provide suitable custom traits struct for function pointers.
@@ -121,7 +123,8 @@ template <> struct PointerLikeTypeTraits<uintptr_t> {
/// potentially use alignment attributes on functions to satisfy that.
template <int Alignment, typename FunctionPointerT>
struct FunctionPointerLikeTypeTraits {
- enum { NumLowBitsAvailable = detail::ConstantLog2<Alignment>::value };
+ static constexpr int NumLowBitsAvailable =
+ detail::ConstantLog2<Alignment>::value;
static inline void *getAsVoidPointer(FunctionPointerT P) {
assert((reinterpret_cast<uintptr_t>(P) &
~((uintptr_t)-1 << NumLowBitsAvailable)) == 0 &&
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/PrettyStackTrace.h b/contrib/llvm-project/llvm/include/llvm/Support/PrettyStackTrace.h
index 6eb070b2297e..ac25cffde051 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/PrettyStackTrace.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/PrettyStackTrace.h
@@ -37,6 +37,13 @@ namespace llvm {
/// \see PrettyStackTraceEntry
void EnablePrettyStackTraceOnSigInfoForThisThread(bool ShouldEnable = true);
+ /// Replaces the generic bug report message that is output upon
+ /// a crash.
+ void setBugReportMsg(const char *Msg);
+
+ /// Get the bug report message that will be output upon a crash.
+ const char *getBugReportMsg();
+
/// PrettyStackTraceEntry - This class is used to represent a frame of the
/// "pretty" stack trace that is dumped when a program crashes. You can define
/// subclasses of this and declare them on the program stack: when they are
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Process.h b/contrib/llvm-project/llvm/include/llvm/Support/Process.h
index e934b7413c17..0ba6d58ba287 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Process.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Process.h
@@ -25,7 +25,7 @@
#define LLVM_SUPPORT_PROCESS_H
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/Allocator.h"
+#include "llvm/Support/AllocatorBase.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Error.h"
@@ -42,6 +42,11 @@ namespace sys {
/// current executing process.
class Process {
public:
+ using Pid = int32_t;
+
+ /// Get the process's identifier.
+ static Pid getProcessId();
+
/// Get the process's page size.
/// This may fail if the underlying syscall returns an error. In most cases,
/// page size information is used for optimization, and this error can be
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Program.h b/contrib/llvm-project/llvm/include/llvm/Support/Program.h
index 6b2315c5da8d..dbda064cda05 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Program.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Program.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/ErrorOr.h"
+#include <chrono>
#include <system_error>
namespace llvm {
@@ -52,6 +53,13 @@ namespace sys {
ProcessInfo();
};
+ /// This struct encapsulates information about a process execution.
+ struct ProcessStatistics {
+ std::chrono::microseconds TotalTime;
+ std::chrono::microseconds UserTime;
+ uint64_t PeakMemory = 0; ///< Maximum resident set size in KiB.
+ };
+
/// Find the first executable file \p Name in \p Paths.
///
/// This does not perform hashing as a shell would but instead stats each PATH
@@ -116,10 +124,14 @@ namespace sys {
///< string instance in which error messages will be returned. If the
///< string is non-empty upon return an error occurred while invoking the
///< program.
- bool *ExecutionFailed = nullptr);
+ bool *ExecutionFailed = nullptr,
+ Optional<ProcessStatistics> *ProcStat = nullptr ///< If non-zero, provides
+ /// a pointer to a structure in which process execution statistics will be
+ /// stored.
+ );
/// Similar to ExecuteAndWait, but returns immediately.
- /// @returns The \see ProcessInfo of the newly launced process.
+ /// @returns The \see ProcessInfo of the newly launched process.
/// \note On Microsoft Windows systems, users will need to either call
/// \see Wait until the process finished execution or win32 CloseHandle() API
/// on ProcessInfo.ProcessHandle to avoid memory leaks.
@@ -182,18 +194,24 @@ namespace sys {
/// \note Users of this function should always check the ReturnCode member of
/// the \see ProcessInfo returned from this function.
ProcessInfo Wait(
- const ProcessInfo &PI, ///< The child process that should be waited on.
+ const ProcessInfo &PI, ///< The child process that should be waited on.
unsigned SecondsToWait, ///< If non-zero, this specifies the amount of
///< time to wait for the child process to exit. If the time expires, the
///< child is killed and this function returns. If zero, this function
///< will perform a non-blocking wait on the child process.
bool WaitUntilTerminates, ///< If true, ignores \p SecondsToWait and waits
///< until child has terminated.
- std::string *ErrMsg = nullptr ///< If non-zero, provides a pointer to a
+ std::string *ErrMsg = nullptr, ///< If non-zero, provides a pointer to a
///< string instance in which error messages will be returned. If the
///< string is non-empty upon return an error occurred while invoking the
///< program.
- );
+ Optional<ProcessStatistics> *ProcStat = nullptr ///< If non-zero, provides
+ /// a pointer to a structure in which process execution statistics will be
+ /// stored.
+ );
+
+ /// Print a command argument, and optionally quote it.
+ void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote);
#if defined(_WIN32)
/// Given a list of command line arguments, quote and escape them as necessary
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributeParser.h b/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributeParser.h
new file mode 100644
index 000000000000..3e629419a7e9
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributeParser.h
@@ -0,0 +1,37 @@
+//===-- RISCVAttributeParser.h - RISCV Attribute Parser ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H
+#define LLVM_SUPPORT_RISCVATTRIBUTEPARSER_H
+
+#include "llvm/Support/ELFAttributeParser.h"
+#include "llvm/Support/RISCVAttributes.h"
+
+namespace llvm {
+class RISCVAttributeParser : public ELFAttributeParser {
+ struct DisplayHandler {
+ RISCVAttrs::AttrType attribute;
+ Error (RISCVAttributeParser::*routine)(unsigned);
+ };
+ static const DisplayHandler displayRoutines[];
+
+ Error handler(uint64_t tag, bool &handled) override;
+
+ Error unalignedAccess(unsigned tag);
+ Error stackAlign(unsigned tag);
+
+public:
+ RISCVAttributeParser(ScopedPrinter *sw)
+ : ELFAttributeParser(sw, RISCVAttrs::RISCVAttributeTags, "riscv") {}
+ RISCVAttributeParser()
+ : ELFAttributeParser(RISCVAttrs::RISCVAttributeTags, "riscv") {}
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributes.h b/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributes.h
new file mode 100644
index 000000000000..caded9519b66
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/RISCVAttributes.h
@@ -0,0 +1,44 @@
+//===-- RISCVAttributes.h - RISCV Attributes --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains enumerations for RISCV attributes as defined in RISC-V
+// ELF psABI specification.
+//
+// RISC-V ELF psABI specification
+//
+// https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_RISCVATTRIBUTES_H
+#define LLVM_SUPPORT_RISCVATTRIBUTES_H
+
+#include "llvm/Support/ELFAttributes.h"
+
+namespace llvm {
+namespace RISCVAttrs {
+
+extern const TagNameMap RISCVAttributeTags;
+
+enum AttrType : unsigned {
+ // Attribute types in ELF/.riscv.attributes.
+ STACK_ALIGN = 4,
+ ARCH = 5,
+ UNALIGNED_ACCESS = 6,
+ PRIV_SPEC = 8,
+ PRIV_SPEC_MINOR = 10,
+ PRIV_SPEC_REVISION = 12,
+};
+
+enum StackAlign { ALIGN_4 = 4, ALIGN_16 = 16 };
+
+enum { NOT_ALLOWED = 0, ALLOWED = 1 };
+
+} // namespace RISCVAttrs
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Regex.h b/contrib/llvm-project/llvm/include/llvm/Support/Regex.h
index b2620ab4cfc9..ae4b9516f194 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Regex.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Regex.h
@@ -16,6 +16,7 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
+#include "llvm/ADT/BitmaskEnum.h"
#include <string>
struct llvm_regex;
@@ -26,20 +27,22 @@ namespace llvm {
class Regex {
public:
- enum {
- NoFlags=0,
+ enum RegexFlags : unsigned {
+ NoFlags = 0,
/// Compile for matching that ignores upper/lower case distinctions.
- IgnoreCase=1,
+ IgnoreCase = 1,
/// Compile for newline-sensitive matching. With this flag '[^' bracket
/// expressions and '.' never match newline. A ^ anchor matches the
/// null string after any newline in the string in addition to its normal
/// function, and the $ anchor matches the null string before any
/// newline in the string in addition to its normal function.
- Newline=2,
+ Newline = 2,
/// By default, the POSIX extended regular expression (ERE) syntax is
/// assumed. Pass this flag to turn on basic regular expressions (BRE)
/// instead.
- BasicRegex=4
+ BasicRegex = 4,
+
+ LLVM_MARK_AS_BITMASK_ENUM(BasicRegex)
};
Regex();
@@ -47,7 +50,8 @@ namespace llvm {
///
/// \param Regex - referenced string is no longer needed after this
/// constructor does finish. Only its compiled form is kept stored.
- Regex(StringRef Regex, unsigned Flags = NoFlags);
+ Regex(StringRef Regex, RegexFlags Flags = NoFlags);
+ Regex(StringRef Regex, unsigned Flags);
Regex(const Regex &) = delete;
Regex &operator=(Regex regex) {
std::swap(preg, regex.preg);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SHA1.h b/contrib/llvm-project/llvm/include/llvm/Support/SHA1.h
index 2cfbd2179364..efd8513cc201 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SHA1.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SHA1.h
@@ -15,14 +15,12 @@
#ifndef LLVM_SUPPORT_SHA1_H
#define LLVM_SUPPORT_SHA1_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-
#include <array>
#include <cstdint>
namespace llvm {
template <typename T> class ArrayRef;
+class StringRef;
/// A class that wrap the SHA1 algorithm.
class SHA1 {
@@ -36,10 +34,7 @@ public:
void update(ArrayRef<uint8_t> Data);
/// Digest more data.
- void update(StringRef Str) {
- update(ArrayRef<uint8_t>((uint8_t *)const_cast<char *>(Str.data()),
- Str.size()));
- }
+ void update(StringRef Str);
/// Return a reference to the current raw 160-bits SHA1 for the digested data
/// since the last call to init(). This call will add data to the internal
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ScaledNumber.h b/contrib/llvm-project/llvm/include/llvm/Support/ScaledNumber.h
index 552da34f357b..a5261e419986 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ScaledNumber.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ScaledNumber.h
@@ -418,7 +418,7 @@ namespace llvm {
class raw_ostream;
class ScaledNumberBase {
public:
- static const int DefaultPrecision = 10;
+ static constexpr int DefaultPrecision = 10;
static void dump(uint64_t D, int16_t E, int Width);
static raw_ostream &print(raw_ostream &OS, uint64_t D, int16_t E, int Width,
@@ -499,7 +499,7 @@ public:
private:
typedef std::numeric_limits<DigitsType> DigitsLimits;
- static const int Width = sizeof(DigitsType) * 8;
+ static constexpr int Width = sizeof(DigitsType) * 8;
static_assert(Width <= 64, "invalid integer width for digits");
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h b/contrib/llvm-project/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
index b63b58e3a8ba..62900b740b81 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SmallVectorMemoryBuffer.h
@@ -44,7 +44,7 @@ public:
/// Construct a named SmallVectorMemoryBuffer from the given
/// SmallVector r-value and StringRef.
SmallVectorMemoryBuffer(SmallVectorImpl<char> &&SV, StringRef Name)
- : SV(std::move(SV)), BufferName(Name) {
+ : SV(std::move(SV)), BufferName(std::string(Name)) {
init(this->SV.begin(), this->SV.end(), false);
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SourceMgr.h b/contrib/llvm-project/llvm/include/llvm/Support/SourceMgr.h
index 1b005519e5d4..a0bd3ca2e0c1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SourceMgr.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SourceMgr.h
@@ -15,19 +15,9 @@
#ifndef LLVM_SUPPORT_SOURCEMGR_H
#define LLVM_SUPPORT_SOURCEMGR_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
-#include <algorithm>
-#include <cassert>
-#include <memory>
-#include <string>
-#include <utility>
#include <vector>
namespace llvm {
@@ -57,29 +47,29 @@ private:
/// The memory buffer for the file.
std::unique_ptr<MemoryBuffer> Buffer;
- /// Helper type for OffsetCache below: since we're storing many offsets
- /// into relatively small files (often smaller than 2^8 or 2^16 bytes),
- /// we select the offset vector element type dynamically based on the
- /// size of Buffer.
- using VariableSizeOffsets = PointerUnion<std::vector<uint8_t> *,
- std::vector<uint16_t> *,
- std::vector<uint32_t> *,
- std::vector<uint64_t> *>;
-
/// Vector of offsets into Buffer at which there are line-endings
/// (lazily populated). Once populated, the '\n' that marks the end of
/// line number N from [1..] is at Buffer[OffsetCache[N-1]]. Since
/// these offsets are in sorted (ascending) order, they can be
/// binary-searched for the first one after any given offset (eg. an
/// offset corresponding to a particular SMLoc).
- mutable VariableSizeOffsets OffsetCache;
-
- /// Populate \c OffsetCache and look up a given \p Ptr in it, assuming
- /// it points somewhere into \c Buffer. The static type parameter \p T
- /// must be an unsigned integer type from uint{8,16,32,64}_t large
- /// enough to store offsets inside \c Buffer.
- template<typename T>
+ ///
+ /// Since we're storing offsets into relatively small files (often smaller
+ /// than 2^8 or 2^16 bytes), we select the offset vector element type
+ /// dynamically based on the size of Buffer.
+ mutable void *OffsetCache = nullptr;
+
+ /// Look up a given \p Ptr in in the buffer, determining which line it came
+ /// from.
unsigned getLineNumber(const char *Ptr) const;
+ template <typename T>
+ unsigned getLineNumberSpecialized(const char *Ptr) const;
+
+ /// Return a pointer to the first character of the specified line number or
+ /// null if the line number is invalid.
+ const char *getPointerForLineNumber(unsigned LineNo) const;
+ template <typename T>
+ const char *getPointerForLineNumberSpecialized(unsigned LineNo) const;
/// This is the location of the parent include, or null if at the top level.
SMLoc IncludeLoc;
@@ -134,9 +124,7 @@ public:
return Buffers[i - 1].Buffer.get();
}
- unsigned getNumBuffers() const {
- return Buffers.size();
- }
+ unsigned getNumBuffers() const { return Buffers.size(); }
unsigned getMainFileID() const {
assert(getNumBuffers());
@@ -184,20 +172,24 @@ public:
std::pair<unsigned, unsigned> getLineAndColumn(SMLoc Loc,
unsigned BufferID = 0) const;
+ /// Given a line and column number in a mapped buffer, turn it into an SMLoc.
+ /// This will return a null SMLoc if the line/column location is invalid.
+ SMLoc FindLocForLineAndColumn(unsigned BufferID, unsigned LineNo,
+ unsigned ColNo);
+
/// Emit a message about the specified location with the specified string.
///
/// \param ShowColors Display colored messages if output is a terminal and
/// the default error handler is used.
- void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind,
- const Twine &Msg,
- ArrayRef<SMRange> Ranges = None,
- ArrayRef<SMFixIt> FixIts = None,
+ void PrintMessage(raw_ostream &OS, SMLoc Loc, DiagKind Kind, const Twine &Msg,
+ ArrayRef<SMRange> Ranges = {},
+ ArrayRef<SMFixIt> FixIts = {},
bool ShowColors = true) const;
/// Emits a diagnostic to llvm::errs().
void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
- ArrayRef<SMRange> Ranges = None,
- ArrayRef<SMFixIt> FixIts = None,
+ ArrayRef<SMRange> Ranges = {},
+ ArrayRef<SMFixIt> FixIts = {},
bool ShowColors = true) const;
/// Emits a manually-constructed diagnostic to the given output stream.
@@ -213,8 +205,8 @@ public:
/// \param Msg If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
- ArrayRef<SMRange> Ranges = None,
- ArrayRef<SMFixIt> FixIts = None) const;
+ ArrayRef<SMRange> Ranges = {},
+ ArrayRef<SMFixIt> FixIts = {}) const;
/// Prints the names of included files and the line of the file they were
/// included from. A diagnostic handler can use this before printing its
@@ -232,17 +224,10 @@ class SMFixIt {
std::string Text;
public:
- // FIXME: Twine.str() is not very efficient.
- SMFixIt(SMLoc Loc, const Twine &Insertion)
- : Range(Loc, Loc), Text(Insertion.str()) {
- assert(Loc.isValid());
- }
+ SMFixIt(SMRange R, const Twine &Replacement);
- // FIXME: Twine.str() is not very efficient.
- SMFixIt(SMRange R, const Twine &Replacement)
- : Range(R), Text(Replacement.str()) {
- assert(R.isValid());
- }
+ SMFixIt(SMLoc Loc, const Twine &Replacement)
+ : SMFixIt(SMRange(Loc, Loc), Replacement) {}
StringRef getText() const { return Text; }
SMRange getRange() const { return Range; }
@@ -274,14 +259,13 @@ public:
SMDiagnostic() = default;
// Diagnostic with no location (e.g. file not found, command line arg error).
SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
- : Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {}
+ : Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd), Message(Msg) {}
// Diagnostic with a location.
- SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
- int Line, int Col, SourceMgr::DiagKind Kind,
- StringRef Msg, StringRef LineStr,
- ArrayRef<std::pair<unsigned,unsigned>> Ranges,
- ArrayRef<SMFixIt> FixIts = None);
+ SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN, int Line, int Col,
+ SourceMgr::DiagKind Kind, StringRef Msg, StringRef LineStr,
+ ArrayRef<std::pair<unsigned, unsigned>> Ranges,
+ ArrayRef<SMFixIt> FixIts = {});
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
@@ -293,13 +277,9 @@ public:
StringRef getLineContents() const { return LineContents; }
ArrayRef<std::pair<unsigned, unsigned>> getRanges() const { return Ranges; }
- void addFixIt(const SMFixIt &Hint) {
- FixIts.push_back(Hint);
- }
+ void addFixIt(const SMFixIt &Hint) { FixIts.push_back(Hint); }
- ArrayRef<SMFixIt> getFixIts() const {
- return FixIts;
- }
+ ArrayRef<SMFixIt> getFixIts() const { return FixIts; }
void print(const char *ProgName, raw_ostream &S, bool ShowColors = true,
bool ShowKindLabel = true) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SpecialCaseList.h b/contrib/llvm-project/llvm/include/llvm/Support/SpecialCaseList.h
index 5b5b7f6124d6..d022a8f53706 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SpecialCaseList.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SpecialCaseList.h
@@ -7,8 +7,8 @@
//
// This is a utility class used to parse user-provided text files with
// "special case lists" for code sanitizers. Such files are used to
-// define an "ABI list" for DataFlowSanitizer and blacklists for sanitizers
-// like AddressSanitizer or UndefinedBehaviorSanitizer.
+// define an "ABI list" for DataFlowSanitizer and allow/exclusion lists for
+// sanitizers like AddressSanitizer or UndefinedBehaviorSanitizer.
//
// Empty lines and lines starting with "#" are ignored. Sections are defined
// using a '[section_name]' header and can be used to specify sanitizers the
@@ -19,18 +19,18 @@
// prefix:wildcard_expression[=category]
// If category is not specified, it is assumed to be empty string.
// Definitions of "prefix" and "category" are sanitizer-specific. For example,
-// sanitizer blacklists support prefixes "src", "fun" and "global".
+// sanitizer exclusion support prefixes "src", "fun" and "global".
// Wildcard expressions define, respectively, source files, functions or
// globals which shouldn't be instrumented.
// Examples of categories:
// "functional": used in DFSan to list functions with pure functional
// semantics.
-// "init": used in ASan blacklist to disable initialization-order bugs
+// "init": used in ASan exclusion list to disable initialization-order bugs
// detection for certain globals or source files.
// Full special case list file example:
// ---
// [address]
-// # Blacklisted items:
+// # Excluded items:
// fun:*_ZN4base6subtle*
// global:*global_with_bad_access_or_initialization*
// global:*global_with_initialization_issues*=init
@@ -52,18 +52,20 @@
#define LLVM_SUPPORT_SPECIALCASELIST_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/TrigramIndex.h"
-#include "llvm/Support/VirtualFileSystem.h"
+#include <memory>
#include <string>
#include <vector>
namespace llvm {
class MemoryBuffer;
-class Regex;
class StringRef;
+namespace vfs {
+class FileSystem;
+}
+
class SpecialCaseList {
public:
/// Parses the special case list entries from files. On failure, returns
@@ -96,7 +98,7 @@ public:
/// @Prefix:<E>=@Category
/// \endcode
/// where @Query satisfies wildcard expression <E> in a given @Section.
- /// Returns zero if there is no blacklist entry corresponding to this
+ /// Returns zero if there is no exclusion entry corresponding to this
/// expression.
unsigned inSectionBlame(StringRef Section, StringRef Prefix, StringRef Query,
StringRef Category = StringRef()) const;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/StringPool.h b/contrib/llvm-project/llvm/include/llvm/Support/StringPool.h
deleted file mode 100644
index a4f45916f53d..000000000000
--- a/contrib/llvm-project/llvm/include/llvm/Support/StringPool.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===- StringPool.h - Interned string pool ----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares an interned string pool, which helps reduce the cost of
-// strings by using the same storage for identical strings.
-//
-// To intern a string:
-//
-// StringPool Pool;
-// PooledStringPtr Str = Pool.intern("wakka wakka");
-//
-// To use the value of an interned string, use operator bool and operator*:
-//
-// if (Str)
-// cerr << "the string is" << *Str << "\n";
-//
-// Pooled strings are immutable, but you can change a PooledStringPtr to point
-// to another instance. So that interned strings can eventually be freed,
-// strings in the string pool are reference-counted (automatically).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SUPPORT_STRINGPOOL_H
-#define LLVM_SUPPORT_STRINGPOOL_H
-
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include <cassert>
-
-namespace llvm {
-
- class PooledStringPtr;
-
- /// StringPool - An interned string pool. Use the intern method to add a
- /// string. Strings are removed automatically as PooledStringPtrs are
- /// destroyed.
- class StringPool {
- /// PooledString - This is the value of an entry in the pool's interning
- /// table.
- struct PooledString {
- StringPool *Pool = nullptr; ///< So the string can remove itself.
- unsigned Refcount = 0; ///< Number of referencing PooledStringPtrs.
-
- public:
- PooledString() = default;
- };
-
- friend class PooledStringPtr;
-
- using table_t = StringMap<PooledString>;
- using entry_t = StringMapEntry<PooledString>;
- table_t InternTable;
-
- public:
- StringPool();
- ~StringPool();
-
- /// intern - Adds a string to the pool and returns a reference-counted
- /// pointer to it. No additional memory is allocated if the string already
- /// exists in the pool.
- PooledStringPtr intern(StringRef Str);
-
- /// empty - Checks whether the pool is empty. Returns true if so.
- ///
- inline bool empty() const { return InternTable.empty(); }
- };
-
- /// PooledStringPtr - A pointer to an interned string. Use operator bool to
- /// test whether the pointer is valid, and operator * to get the string if so.
- /// This is a lightweight value class with storage requirements equivalent to
- /// a single pointer, but it does have reference-counting overhead when
- /// copied.
- class PooledStringPtr {
- using entry_t = StringPool::entry_t;
-
- entry_t *S = nullptr;
-
- public:
- PooledStringPtr() = default;
-
- explicit PooledStringPtr(entry_t *E) : S(E) {
- if (S) ++S->getValue().Refcount;
- }
-
- PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
- if (S) ++S->getValue().Refcount;
- }
-
- PooledStringPtr &operator=(const PooledStringPtr &That) {
- if (S != That.S) {
- clear();
- S = That.S;
- if (S) ++S->getValue().Refcount;
- }
- return *this;
- }
-
- void clear() {
- if (!S)
- return;
- if (--S->getValue().Refcount == 0) {
- S->getValue().Pool->InternTable.remove(S);
- S->Destroy();
- }
- S = nullptr;
- }
-
- ~PooledStringPtr() { clear(); }
-
- inline const char *begin() const {
- assert(*this && "Attempt to dereference empty PooledStringPtr!");
- return S->getKeyData();
- }
-
- inline const char *end() const {
- assert(*this && "Attempt to dereference empty PooledStringPtr!");
- return S->getKeyData() + S->getKeyLength();
- }
-
- inline unsigned size() const {
- assert(*this && "Attempt to dereference empty PooledStringPtr!");
- return S->getKeyLength();
- }
-
- inline const char *operator*() const { return begin(); }
- inline explicit operator bool() const { return S != nullptr; }
-
- inline bool operator==(const PooledStringPtr &That) const { return S == That.S; }
- inline bool operator!=(const PooledStringPtr &That) const { return S != That.S; }
- };
-
-} // end namespace llvm
-
-#endif // LLVM_SUPPORT_STRINGPOOL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SuffixTree.h b/contrib/llvm-project/llvm/include/llvm/Support/SuffixTree.h
new file mode 100644
index 000000000000..67d513d032ce
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SuffixTree.h
@@ -0,0 +1,350 @@
+//===- llvm/ADT/SuffixTree.h - Tree for substrings --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Suffix Tree class and Suffix Tree Node struct.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_SUFFIXTREE_H
+#define LLVM_SUPPORT_SUFFIXTREE_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Allocator.h"
+#include <vector>
+
+namespace llvm {
+
+/// Represents an undefined index in the suffix tree.
+const unsigned EmptyIdx = -1;
+
+/// A node in a suffix tree which represents a substring or suffix.
+///
+/// Each node has either no children or at least two children, with the root
+/// being a exception in the empty tree.
+///
+/// Children are represented as a map between unsigned integers and nodes. If
+/// a node N has a child M on unsigned integer k, then the mapping represented
+/// by N is a proper prefix of the mapping represented by M. Note that this,
+/// although similar to a trie is somewhat different: each node stores a full
+/// substring of the full mapping rather than a single character state.
+///
+/// Each internal node contains a pointer to the internal node representing
+/// the same string, but with the first character chopped off. This is stored
+/// in \p Link. Each leaf node stores the start index of its respective
+/// suffix in \p SuffixIdx.
+struct SuffixTreeNode {
+
+ /// The children of this node.
+ ///
+ /// A child existing on an unsigned integer implies that from the mapping
+ /// represented by the current node, there is a way to reach another
+ /// mapping by tacking that character on the end of the current string.
+ llvm::DenseMap<unsigned, SuffixTreeNode *> Children;
+
+ /// The start index of this node's substring in the main string.
+ unsigned StartIdx = EmptyIdx;
+
+ /// The end index of this node's substring in the main string.
+ ///
+ /// Every leaf node must have its \p EndIdx incremented at the end of every
+ /// step in the construction algorithm. To avoid having to update O(N)
+ /// nodes individually at the end of every step, the end index is stored
+ /// as a pointer.
+ unsigned *EndIdx = nullptr;
+
+ /// For leaves, the start index of the suffix represented by this node.
+ ///
+ /// For all other nodes, this is ignored.
+ unsigned SuffixIdx = EmptyIdx;
+
+ /// For internal nodes, a pointer to the internal node representing
+ /// the same sequence with the first character chopped off.
+ ///
+ /// This acts as a shortcut in Ukkonen's algorithm. One of the things that
+ /// Ukkonen's algorithm does to achieve linear-time construction is
+ /// keep track of which node the next insert should be at. This makes each
+ /// insert O(1), and there are a total of O(N) inserts. The suffix link
+ /// helps with inserting children of internal nodes.
+ ///
+ /// Say we add a child to an internal node with associated mapping S. The
+ /// next insertion must be at the node representing S - its first character.
+ /// This is given by the way that we iteratively build the tree in Ukkonen's
+ /// algorithm. The main idea is to look at the suffixes of each prefix in the
+ /// string, starting with the longest suffix of the prefix, and ending with
+ /// the shortest. Therefore, if we keep pointers between such nodes, we can
+ /// move to the next insertion point in O(1) time. If we don't, then we'd
+ /// have to query from the root, which takes O(N) time. This would make the
+ /// construction algorithm O(N^2) rather than O(N).
+ SuffixTreeNode *Link = nullptr;
+
+ /// The length of the string formed by concatenating the edge labels from the
+ /// root to this node.
+ unsigned ConcatLen = 0;
+
+ /// Returns true if this node is a leaf.
+ bool isLeaf() const { return SuffixIdx != EmptyIdx; }
+
+ /// Returns true if this node is the root of its owning \p SuffixTree.
+ bool isRoot() const { return StartIdx == EmptyIdx; }
+
+ /// Return the number of elements in the substring associated with this node.
+ size_t size() const {
+
+ // Is it the root? If so, it's the empty string so return 0.
+ if (isRoot())
+ return 0;
+
+ assert(*EndIdx != EmptyIdx && "EndIdx is undefined!");
+
+ // Size = the number of elements in the string.
+ // For example, [0 1 2 3] has length 4, not 3. 3-0 = 3, so we have 3-0+1.
+ return *EndIdx - StartIdx + 1;
+ }
+
+ SuffixTreeNode(unsigned StartIdx, unsigned *EndIdx, SuffixTreeNode *Link)
+ : StartIdx(StartIdx), EndIdx(EndIdx), Link(Link) {}
+
+ SuffixTreeNode() {}
+};
+
+/// A data structure for fast substring queries.
+///
+/// Suffix trees represent the suffixes of their input strings in their leaves.
+/// A suffix tree is a type of compressed trie structure where each node
+/// represents an entire substring rather than a single character. Each leaf
+/// of the tree is a suffix.
+///
+/// A suffix tree can be seen as a type of state machine where each state is a
+/// substring of the full string. The tree is structured so that, for a string
+/// of length N, there are exactly N leaves in the tree. This structure allows
+/// us to quickly find repeated substrings of the input string.
+///
+/// In this implementation, a "string" is a vector of unsigned integers.
+/// These integers may result from hashing some data type. A suffix tree can
+/// contain 1 or many strings, which can then be queried as one large string.
+///
+/// The suffix tree is implemented using Ukkonen's algorithm for linear-time
+/// suffix tree construction. Ukkonen's algorithm is explained in more detail
+/// in the paper by Esko Ukkonen "On-line construction of suffix trees. The
+/// paper is available at
+///
+/// https://www.cs.helsinki.fi/u/ukkonen/SuffixT1withFigs.pdf
+class SuffixTree {
+public:
+ /// Each element is an integer representing an instruction in the module.
+ llvm::ArrayRef<unsigned> Str;
+
+ /// A repeated substring in the tree.
+ struct RepeatedSubstring {
+ /// The length of the string.
+ unsigned Length;
+
+ /// The start indices of each occurrence.
+ std::vector<unsigned> StartIndices;
+ };
+
+private:
+ /// Maintains each node in the tree.
+ llvm::SpecificBumpPtrAllocator<SuffixTreeNode> NodeAllocator;
+
+ /// The root of the suffix tree.
+ ///
+ /// The root represents the empty string. It is maintained by the
+ /// \p NodeAllocator like every other node in the tree.
+ SuffixTreeNode *Root = nullptr;
+
+ /// Maintains the end indices of the internal nodes in the tree.
+ ///
+ /// Each internal node is guaranteed to never have its end index change
+ /// during the construction algorithm; however, leaves must be updated at
+ /// every step. Therefore, we need to store leaf end indices by reference
+ /// to avoid updating O(N) leaves at every step of construction. Thus,
+ /// every internal node must be allocated its own end index.
+ llvm::BumpPtrAllocator InternalEndIdxAllocator;
+
+ /// The end index of each leaf in the tree.
+ unsigned LeafEndIdx = -1;
+
+ /// Helper struct which keeps track of the next insertion point in
+ /// Ukkonen's algorithm.
+ struct ActiveState {
+ /// The next node to insert at.
+ SuffixTreeNode *Node = nullptr;
+
+ /// The index of the first character in the substring currently being added.
+ unsigned Idx = EmptyIdx;
+
+ /// The length of the substring we have to add at the current step.
+ unsigned Len = 0;
+ };
+
+ /// The point the next insertion will take place at in the
+ /// construction algorithm.
+ ActiveState Active;
+
+ /// Allocate a leaf node and add it to the tree.
+ ///
+ /// \param Parent The parent of this node.
+ /// \param StartIdx The start index of this node's associated string.
+ /// \param Edge The label on the edge leaving \p Parent to this node.
+ ///
+ /// \returns A pointer to the allocated leaf node.
+ SuffixTreeNode *insertLeaf(SuffixTreeNode &Parent, unsigned StartIdx,
+ unsigned Edge);
+
+ /// Allocate an internal node and add it to the tree.
+ ///
+ /// \param Parent The parent of this node. Only null when allocating the root.
+ /// \param StartIdx The start index of this node's associated string.
+ /// \param EndIdx The end index of this node's associated string.
+ /// \param Edge The label on the edge leaving \p Parent to this node.
+ ///
+ /// \returns A pointer to the allocated internal node.
+ SuffixTreeNode *insertInternalNode(SuffixTreeNode *Parent, unsigned StartIdx,
+ unsigned EndIdx, unsigned Edge);
+
+ /// Set the suffix indices of the leaves to the start indices of their
+ /// respective suffixes.
+ void setSuffixIndices();
+
+ /// Construct the suffix tree for the prefix of the input ending at
+ /// \p EndIdx.
+ ///
+ /// Used to construct the full suffix tree iteratively. At the end of each
+ /// step, the constructed suffix tree is either a valid suffix tree, or a
+ /// suffix tree with implicit suffixes. At the end of the final step, the
+ /// suffix tree is a valid tree.
+ ///
+ /// \param EndIdx The end index of the current prefix in the main string.
+ /// \param SuffixesToAdd The number of suffixes that must be added
+ /// to complete the suffix tree at the current phase.
+ ///
+ /// \returns The number of suffixes that have not been added at the end of
+ /// this step.
+ unsigned extend(unsigned EndIdx, unsigned SuffixesToAdd);
+
+public:
+ /// Construct a suffix tree from a sequence of unsigned integers.
+ ///
+ /// \param Str The string to construct the suffix tree for.
+ SuffixTree(const std::vector<unsigned> &Str);
+
+ /// Iterator for finding all repeated substrings in the suffix tree.
+ struct RepeatedSubstringIterator {
+ private:
+ /// The current node we're visiting.
+ SuffixTreeNode *N = nullptr;
+
+ /// The repeated substring associated with this node.
+ RepeatedSubstring RS;
+
+ /// The nodes left to visit.
+ std::vector<SuffixTreeNode *> ToVisit;
+
+ /// The minimum length of a repeated substring to find.
+ /// Since we're outlining, we want at least two instructions in the range.
+ /// FIXME: This may not be true for targets like X86 which support many
+ /// instruction lengths.
+ const unsigned MinLength = 2;
+
+ /// Move the iterator to the next repeated substring.
+ void advance() {
+ // Clear the current state. If we're at the end of the range, then this
+ // is the state we want to be in.
+ RS = RepeatedSubstring();
+ N = nullptr;
+
+ // Each leaf node represents a repeat of a string.
+ std::vector<SuffixTreeNode *> LeafChildren;
+
+ // Continue visiting nodes until we find one which repeats more than once.
+ while (!ToVisit.empty()) {
+ SuffixTreeNode *Curr = ToVisit.back();
+ ToVisit.pop_back();
+ LeafChildren.clear();
+
+ // Keep track of the length of the string associated with the node. If
+ // it's too short, we'll quit.
+ unsigned Length = Curr->ConcatLen;
+
+ // Iterate over each child, saving internal nodes for visiting, and
+ // leaf nodes in LeafChildren. Internal nodes represent individual
+ // strings, which may repeat.
+ for (auto &ChildPair : Curr->Children) {
+ // Save all of this node's children for processing.
+ if (!ChildPair.second->isLeaf())
+ ToVisit.push_back(ChildPair.second);
+
+ // It's not an internal node, so it must be a leaf. If we have a
+ // long enough string, then save the leaf children.
+ else if (Length >= MinLength)
+ LeafChildren.push_back(ChildPair.second);
+ }
+
+ // The root never represents a repeated substring. If we're looking at
+ // that, then skip it.
+ if (Curr->isRoot())
+ continue;
+
+ // Do we have any repeated substrings?
+ if (LeafChildren.size() >= 2) {
+ // Yes. Update the state to reflect this, and then bail out.
+ N = Curr;
+ RS.Length = Length;
+ for (SuffixTreeNode *Leaf : LeafChildren)
+ RS.StartIndices.push_back(Leaf->SuffixIdx);
+ break;
+ }
+ }
+
+ // At this point, either NewRS is an empty RepeatedSubstring, or it was
+ // set in the above loop. Similarly, N is either nullptr, or the node
+ // associated with NewRS.
+ }
+
+ public:
+ /// Return the current repeated substring.
+ RepeatedSubstring &operator*() { return RS; }
+
+ RepeatedSubstringIterator &operator++() {
+ advance();
+ return *this;
+ }
+
+ RepeatedSubstringIterator operator++(int I) {
+ RepeatedSubstringIterator It(*this);
+ advance();
+ return It;
+ }
+
+ bool operator==(const RepeatedSubstringIterator &Other) {
+ return N == Other.N;
+ }
+ bool operator!=(const RepeatedSubstringIterator &Other) {
+ return !(*this == Other);
+ }
+
+ RepeatedSubstringIterator(SuffixTreeNode *N) : N(N) {
+ // Do we have a non-null node?
+ if (N) {
+ // Yes. At the first step, we need to visit all of N's children.
+ // Note: This means that we visit N last.
+ ToVisit.push_back(N);
+ advance();
+ }
+ }
+ };
+
+ typedef RepeatedSubstringIterator iterator;
+ iterator begin() { return iterator(Root); }
+ iterator end() { return iterator(nullptr); }
+};
+
+} // namespace llvm
+
+#endif // LLVM_SUPPORT_SUFFIXTREE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SwapByteOrder.h b/contrib/llvm-project/llvm/include/llvm/Support/SwapByteOrder.h
index 6cec87006c02..0e544fc7e71e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SwapByteOrder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SwapByteOrder.h
@@ -14,15 +14,15 @@
#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
#define LLVM_SUPPORT_SWAPBYTEORDER_H
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
#include <cstddef>
+#include <cstdint>
#include <type_traits>
#if defined(_MSC_VER) && !defined(_DEBUG)
#include <stdlib.h>
#endif
-#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__)
+#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
+ defined(__EMSCRIPTEN__)
#include <endian.h>
#elif defined(_AIX)
#include <sys/machine.h>
@@ -36,6 +36,10 @@
#else
#define BYTE_ORDER LITTLE_ENDIAN
#endif
+#elif defined(__MVS__)
+#define BIG_ENDIAN 4321
+#define LITTLE_ENDIAN 1234
+#define BYTE_ORDER BIG_ENDIAN
#else
#if !defined(BYTE_ORDER) && !defined(_WIN32)
#include <machine/endian.h>
@@ -43,19 +47,10 @@
#endif
namespace llvm {
-namespace sys {
-#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
-constexpr bool IsBigEndianHost = true;
-#else
-constexpr bool IsBigEndianHost = false;
-#endif
-
-static const bool IsLittleEndianHost = !IsBigEndianHost;
-
-/// SwapByteOrder_16 - This function returns a byte-swapped representation of
+/// ByteSwap_16 - This function returns a byte-swapped representation of
/// the 16-bit argument.
-inline uint16_t SwapByteOrder_16(uint16_t value) {
+inline uint16_t ByteSwap_16(uint16_t value) {
#if defined(_MSC_VER) && !defined(_DEBUG)
// The DLL version of the runtime lacks these functions (bug!?), but in a
// release build they're replaced with BSWAP instructions anyway.
@@ -68,7 +63,7 @@ inline uint16_t SwapByteOrder_16(uint16_t value) {
}
/// This function returns a byte-swapped representation of the 32-bit argument.
-inline uint32_t SwapByteOrder_32(uint32_t value) {
+inline uint32_t ByteSwap_32(uint32_t value) {
#if defined(__llvm__) || (defined(__GNUC__) && !defined(__ICC))
return __builtin_bswap32(value);
#elif defined(_MSC_VER) && !defined(_DEBUG)
@@ -83,43 +78,54 @@ inline uint32_t SwapByteOrder_32(uint32_t value) {
}
/// This function returns a byte-swapped representation of the 64-bit argument.
-inline uint64_t SwapByteOrder_64(uint64_t value) {
+inline uint64_t ByteSwap_64(uint64_t value) {
#if defined(__llvm__) || (defined(__GNUC__) && !defined(__ICC))
return __builtin_bswap64(value);
#elif defined(_MSC_VER) && !defined(_DEBUG)
return _byteswap_uint64(value);
#else
- uint64_t Hi = SwapByteOrder_32(uint32_t(value));
- uint32_t Lo = SwapByteOrder_32(uint32_t(value >> 32));
+ uint64_t Hi = ByteSwap_32(uint32_t(value));
+ uint32_t Lo = ByteSwap_32(uint32_t(value >> 32));
return (Hi << 32) | Lo;
#endif
}
+namespace sys {
+
+#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
+constexpr bool IsBigEndianHost = true;
+#else
+constexpr bool IsBigEndianHost = false;
+#endif
+
+static const bool IsLittleEndianHost = !IsBigEndianHost;
+
inline unsigned char getSwappedBytes(unsigned char C) { return C; }
inline signed char getSwappedBytes(signed char C) { return C; }
inline char getSwappedBytes(char C) { return C; }
-inline unsigned short getSwappedBytes(unsigned short C) { return SwapByteOrder_16(C); }
-inline signed short getSwappedBytes( signed short C) { return SwapByteOrder_16(C); }
+inline unsigned short getSwappedBytes(unsigned short C) { return ByteSwap_16(C); }
+inline signed short getSwappedBytes( signed short C) { return ByteSwap_16(C); }
-inline unsigned int getSwappedBytes(unsigned int C) { return SwapByteOrder_32(C); }
-inline signed int getSwappedBytes( signed int C) { return SwapByteOrder_32(C); }
+inline unsigned int getSwappedBytes(unsigned int C) { return ByteSwap_32(C); }
+inline signed int getSwappedBytes( signed int C) { return ByteSwap_32(C); }
-#if __LONG_MAX__ == __INT_MAX__
-inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_32(C); }
-inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_32(C); }
-#elif __LONG_MAX__ == __LONG_LONG_MAX__
-inline unsigned long getSwappedBytes(unsigned long C) { return SwapByteOrder_64(C); }
-inline signed long getSwappedBytes( signed long C) { return SwapByteOrder_64(C); }
-#else
-#error "Unknown long size!"
-#endif
+inline unsigned long getSwappedBytes(unsigned long C) {
+ // Handle LLP64 and LP64 platforms.
+ return sizeof(long) == sizeof(int) ? ByteSwap_32((uint32_t)C)
+ : ByteSwap_64((uint64_t)C);
+}
+inline signed long getSwappedBytes(signed long C) {
+ // Handle LLP64 and LP64 platforms.
+ return sizeof(long) == sizeof(int) ? ByteSwap_32((uint32_t)C)
+ : ByteSwap_64((uint64_t)C);
+}
inline unsigned long long getSwappedBytes(unsigned long long C) {
- return SwapByteOrder_64(C);
+ return ByteSwap_64(C);
}
inline signed long long getSwappedBytes(signed long long C) {
- return SwapByteOrder_64(C);
+ return ByteSwap_64(C);
}
inline float getSwappedBytes(float C) {
@@ -128,7 +134,7 @@ inline float getSwappedBytes(float C) {
float f;
} in, out;
in.f = C;
- out.i = SwapByteOrder_32(in.i);
+ out.i = ByteSwap_32(in.i);
return out.f;
}
@@ -138,15 +144,14 @@ inline double getSwappedBytes(double C) {
double d;
} in, out;
in.d = C;
- out.i = SwapByteOrder_64(in.i);
+ out.i = ByteSwap_64(in.i);
return out.d;
}
template <typename T>
-inline typename std::enable_if<std::is_enum<T>::value, T>::type
-getSwappedBytes(T C) {
+inline std::enable_if_t<std::is_enum<T>::value, T> getSwappedBytes(T C) {
return static_cast<T>(
- getSwappedBytes(static_cast<typename std::underlying_type<T>::type>(C)));
+ getSwappedBytes(static_cast<std::underlying_type_t<T>>(C)));
}
template<typename T>
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/SystemUtils.h b/contrib/llvm-project/llvm/include/llvm/Support/SystemUtils.h
index 77deddb9ee1c..786bea3fcfae 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/SystemUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/SystemUtils.h
@@ -15,17 +15,16 @@
#define LLVM_SUPPORT_SYSTEMUTILS_H
namespace llvm {
- class raw_ostream;
+class raw_ostream;
/// Determine if the raw_ostream provided is connected to a terminal. If so,
/// generate a warning message to errs() advising against display of bitcode
/// and return true. Otherwise just return false.
/// Check for output written to a console
bool CheckBitcodeOutputToConsole(
- raw_ostream &stream_to_check, ///< The stream to be checked
- bool print_warning = true ///< Control whether warnings are printed
+ raw_ostream &stream_to_check ///< The stream to be checked
);
-} // End llvm namespace
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TargetOpcodes.def b/contrib/llvm-project/llvm/include/llvm/Support/TargetOpcodes.def
index e004550059d4..c069f5d22ba8 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TargetOpcodes.def
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TargetOpcodes.def
@@ -127,6 +127,12 @@ HANDLE_TARGET_OPCODE(PATCHPOINT)
/// additionally expand this pseudo after register allocation.
HANDLE_TARGET_OPCODE(LOAD_STACK_GUARD)
+/// These are used to support call sites that must have the stack adjusted
+/// before the call (e.g. to initialize an argument passed by value).
+/// See llvm.call.preallocated.{setup,arg} in the LangRef for more details.
+HANDLE_TARGET_OPCODE(PREALLOCATED_SETUP)
+HANDLE_TARGET_OPCODE(PREALLOCATED_ARG)
+
/// Call instruction with associated vm state for deoptimization and list
/// of live pointers for relocation by the garbage collector. It is
/// intended to support garbage collection with fully precise relocating
@@ -279,6 +285,9 @@ HANDLE_TARGET_OPCODE(G_INTTOPTR)
/// COPY is the relevant instruction.
HANDLE_TARGET_OPCODE(G_BITCAST)
+/// Generic freeze.
+HANDLE_TARGET_OPCODE(G_FREEZE)
+
/// INTRINSIC trunc intrinsic.
HANDLE_TARGET_OPCODE(G_INTRINSIC_TRUNC)
@@ -385,6 +394,12 @@ HANDLE_TARGET_OPCODE(G_LSHR)
// Generic arithmetic right-shift
HANDLE_TARGET_OPCODE(G_ASHR)
+// Generic funnel left shift
+HANDLE_TARGET_OPCODE(G_FSHL)
+
+// Generic funnel right shift
+HANDLE_TARGET_OPCODE(G_FSHR)
+
/// Generic integer-base comparison, also applicable to vectors of integers.
HANDLE_TARGET_OPCODE(G_ICMP)
@@ -442,6 +457,18 @@ HANDLE_TARGET_OPCODE(G_UMULH)
// the high half of the result.
HANDLE_TARGET_OPCODE(G_SMULH)
+/// Generic saturating unsigned addition.
+HANDLE_TARGET_OPCODE(G_UADDSAT)
+
+/// Generic saturating signed addition.
+HANDLE_TARGET_OPCODE(G_SADDSAT)
+
+/// Generic saturating unsigned subtraction.
+HANDLE_TARGET_OPCODE(G_USUBSAT)
+
+/// Generic saturating signed subtraction.
+HANDLE_TARGET_OPCODE(G_SSUBSAT)
+
/// Generic FP addition.
HANDLE_TARGET_OPCODE(G_FADD)
@@ -529,9 +556,8 @@ HANDLE_TARGET_OPCODE(G_FMAXIMUM)
/// Generic pointer offset
HANDLE_TARGET_OPCODE(G_PTR_ADD)
-/// Clear the specified number of low bits in a pointer. This rounds the value
-/// *down* to the given alignment.
-HANDLE_TARGET_OPCODE(G_PTR_MASK)
+/// Clear the specified bits in a pointer.
+HANDLE_TARGET_OPCODE(G_PTRMASK)
/// Generic signed integer minimum.
HANDLE_TARGET_OPCODE(G_SMIN)
@@ -614,6 +640,15 @@ HANDLE_TARGET_OPCODE(G_JUMP_TABLE)
/// Generic dynamic stack allocation.
HANDLE_TARGET_OPCODE(G_DYN_STACKALLOC)
+/// Strict floating point instructions.
+HANDLE_TARGET_OPCODE(G_STRICT_FADD)
+HANDLE_TARGET_OPCODE(G_STRICT_FSUB)
+HANDLE_TARGET_OPCODE(G_STRICT_FMUL)
+HANDLE_TARGET_OPCODE(G_STRICT_FDIV)
+HANDLE_TARGET_OPCODE(G_STRICT_FREM)
+HANDLE_TARGET_OPCODE(G_STRICT_FMA)
+HANDLE_TARGET_OPCODE(G_STRICT_FSQRT)
+
/// read_register intrinsic
HANDLE_TARGET_OPCODE(G_READ_REGISTER)
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h b/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
index a7e1a752d081..a0bd88c153b6 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TargetParser.h
@@ -25,55 +25,12 @@ namespace llvm {
class StringRef;
// Target specific information in their own namespaces.
-// (ARM/AArch64 are declared in ARM/AArch64TargetParser.h)
+// (ARM/AArch64/X86 are declared in ARM/AArch64/X86TargetParser.h)
// These should be generated from TableGen because the information is already
// there, and there is where new information about targets will be added.
// FIXME: To TableGen this we need to make some table generated files available
// even if the back-end is not compiled with LLVM, plus we need to create a new
// back-end to TableGen to create these clean tables.
-namespace X86 {
-
-// This should be kept in sync with libcc/compiler-rt as its included by clang
-// as a proxy for what's in libgcc/compiler-rt.
-enum ProcessorVendors : unsigned {
- VENDOR_DUMMY,
-#define X86_VENDOR(ENUM, STRING) \
- ENUM,
-#include "llvm/Support/X86TargetParser.def"
- VENDOR_OTHER
-};
-
-// This should be kept in sync with libcc/compiler-rt as its included by clang
-// as a proxy for what's in libgcc/compiler-rt.
-enum ProcessorTypes : unsigned {
- CPU_TYPE_DUMMY,
-#define X86_CPU_TYPE(ARCHNAME, ENUM) \
- ENUM,
-#include "llvm/Support/X86TargetParser.def"
- CPU_TYPE_MAX
-};
-
-// This should be kept in sync with libcc/compiler-rt as its included by clang
-// as a proxy for what's in libgcc/compiler-rt.
-enum ProcessorSubtypes : unsigned {
- CPU_SUBTYPE_DUMMY,
-#define X86_CPU_SUBTYPE(ARCHNAME, ENUM) \
- ENUM,
-#include "llvm/Support/X86TargetParser.def"
- CPU_SUBTYPE_MAX
-};
-
-// This should be kept in sync with libcc/compiler-rt as it should be used
-// by clang as a proxy for what's in libgcc/compiler-rt.
-enum ProcessorFeatures {
-#define X86_FEATURE(VAL, ENUM) \
- ENUM = VAL,
-#include "llvm/Support/X86TargetParser.def"
-
-};
-
-} // namespace X86
-
namespace AMDGPU {
/// GPU kinds supported by the AMDGPU target.
@@ -127,9 +84,10 @@ enum GPUKind : uint32_t {
GK_GFX1010 = 71,
GK_GFX1011 = 72,
GK_GFX1012 = 73,
+ GK_GFX1030 = 75,
GK_AMDGCN_FIRST = GK_GFX600,
- GK_AMDGCN_LAST = GK_GFX1012,
+ GK_AMDGCN_LAST = GK_GFX1030,
};
/// Instruction set architecture version.
@@ -151,7 +109,10 @@ enum ArchFeatureKind : uint32_t {
// Common features.
FEATURE_FAST_FMA_F32 = 1 << 4,
- FEATURE_FAST_DENORMAL_F32 = 1 << 5
+ FEATURE_FAST_DENORMAL_F32 = 1 << 5,
+
+ // Wavefront 32 is available.
+ FEATURE_WAVE32 = 1 << 6
};
StringRef getArchNameAMDGCN(GPUKind AK);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TaskQueue.h b/contrib/llvm-project/llvm/include/llvm/Support/TaskQueue.h
index df2ffdee2cc2..4ceb056391af 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TaskQueue.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TaskQueue.h
@@ -38,7 +38,7 @@ class TaskQueue {
// type-specialized domain (before type erasure) and then erase this into a
// std::function.
template <typename Callable> struct Task {
- using ResultTy = typename std::result_of<Callable()>::type;
+ using ResultTy = std::result_of_t<Callable()>;
explicit Task(Callable C, TaskQueue &Parent)
: C(std::move(C)), P(std::make_shared<std::promise<ResultTy>>()),
Parent(&Parent) {}
@@ -78,13 +78,13 @@ public:
/// used to wait for the task (and all previous tasks that have not yet
/// completed) to finish.
template <typename Callable>
- std::future<typename std::result_of<Callable()>::type> async(Callable &&C) {
+ std::future<std::result_of_t<Callable()>> async(Callable &&C) {
#if !LLVM_ENABLE_THREADS
static_assert(false,
"TaskQueue requires building with LLVM_ENABLE_THREADS!");
#endif
Task<Callable> T{std::move(C), *this};
- using ResultTy = typename std::result_of<Callable()>::type;
+ using ResultTy = std::result_of_t<Callable()>;
std::future<ResultTy> F = T.P->get_future();
{
std::lock_guard<std::mutex> Lock(QueueLock);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ThreadPool.h b/contrib/llvm-project/llvm/include/llvm/Support/ThreadPool.h
index 4bcbaa3142fd..528fb32525eb 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ThreadPool.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ThreadPool.h
@@ -14,6 +14,7 @@
#define LLVM_SUPPORT_THREAD_POOL_H
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Threading.h"
#include "llvm/Support/thread.h"
#include <future>
@@ -38,12 +39,11 @@ public:
using TaskTy = std::function<void()>;
using PackagedTaskTy = std::packaged_task<void()>;
- /// Construct a pool with the number of threads found by
- /// hardware_concurrency().
- ThreadPool();
-
- /// Construct a pool of \p ThreadCount threads
- ThreadPool(unsigned ThreadCount);
+ /// Construct a pool using the hardware strategy \p S for mapping hardware
+ /// execution resources (threads, cores, CPUs)
+ /// Defaults to using the maximum execution resources in the system, but
+ /// accounting for the affinity mask.
+ ThreadPool(ThreadPoolStrategy S = hardware_concurrency());
/// Blocking destructor: the pool will wait for all the threads to complete.
~ThreadPool();
@@ -68,7 +68,11 @@ public:
/// It is an error to try to add new tasks while blocking on this call.
void wait();
+ unsigned getThreadCount() const { return ThreadCount; }
+
private:
+ bool workCompletedUnlocked() { return !ActiveThreads && Tasks.empty(); }
+
/// Asynchronous submission of a task to the pool. The returned future can be
/// used to wait for the task to finish and is *non-blocking* on destruction.
std::shared_future<void> asyncImpl(TaskTy F);
@@ -83,17 +87,18 @@ private:
std::mutex QueueLock;
std::condition_variable QueueCondition;
- /// Locking and signaling for job completion
- std::mutex CompletionLock;
+ /// Signaling for job completion
std::condition_variable CompletionCondition;
/// Keep track of the number of thread actually busy
- std::atomic<unsigned> ActiveThreads;
+ unsigned ActiveThreads = 0;
#if LLVM_ENABLE_THREADS // avoids warning for unused variable
/// Signal for the destruction of the pool, asking thread to exit.
- bool EnableFlag;
+ bool EnableFlag = true;
#endif
+
+ unsigned ThreadCount;
};
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Threading.h b/contrib/llvm-project/llvm/include/llvm/Support/Threading.h
index bacab8fa23b6..13000575f270 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Threading.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Threading.h
@@ -14,6 +14,7 @@
#ifndef LLVM_SUPPORT_THREADING_H
#define LLVM_SUPPORT_THREADING_H
+#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/FunctionExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
@@ -143,20 +144,81 @@ void llvm_execute_on_thread_async(
#endif
}
- /// Get the amount of currency to use for tasks requiring significant
- /// memory or other resources. Currently based on physical cores, if
- /// available for the host system, otherwise falls back to
- /// thread::hardware_concurrency().
- /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF
- unsigned heavyweight_hardware_concurrency();
-
- /// Get the number of threads that the current program can execute
- /// concurrently. On some systems std::thread::hardware_concurrency() returns
- /// the total number of cores, without taking affinity into consideration.
- /// Returns 1 when LLVM is configured with LLVM_ENABLE_THREADS=OFF.
- /// Fallback to std::thread::hardware_concurrency() if sched_getaffinity is
- /// not available.
- unsigned hardware_concurrency();
+ /// This tells how a thread pool will be used
+ class ThreadPoolStrategy {
+ public:
+ // The default value (0) means all available threads should be used,
+ // taking the affinity mask into account. If set, this value only represents
+ // a suggested high bound, the runtime might choose a lower value (not
+ // higher).
+ unsigned ThreadsRequested = 0;
+
+ // If SMT is active, use hyper threads. If false, there will be only one
+ // std::thread per core.
+ bool UseHyperThreads = true;
+
+ // If set, will constrain 'ThreadsRequested' to the number of hardware
+ // threads, or hardware cores.
+ bool Limit = false;
+
+ /// Retrieves the max available threads for the current strategy. This
+ /// accounts for affinity masks and takes advantage of all CPU sockets.
+ unsigned compute_thread_count() const;
+
+ /// Assign the current thread to an ideal hardware CPU or NUMA node. In a
+ /// multi-socket system, this ensures threads are assigned to all CPU
+ /// sockets. \p ThreadPoolNum represents a number bounded by [0,
+ /// compute_thread_count()).
+ void apply_thread_strategy(unsigned ThreadPoolNum) const;
+
+ /// Finds the CPU socket where a thread should go. Returns 'None' if the
+ /// thread shall remain on the actual CPU socket.
+ Optional<unsigned> compute_cpu_socket(unsigned ThreadPoolNum) const;
+ };
+
+ /// Build a strategy from a number of threads as a string provided in \p Num.
+ /// When Num is above the max number of threads specified by the \p Default
+ /// strategy, we attempt to equally allocate the threads on all CPU sockets.
+ /// "0" or an empty string will return the \p Default strategy.
+ /// "all" for using all hardware threads.
+ Optional<ThreadPoolStrategy>
+ get_threadpool_strategy(StringRef Num, ThreadPoolStrategy Default = {});
+
+ /// Returns a thread strategy for tasks requiring significant memory or other
+ /// resources. To be used for workloads where hardware_concurrency() proves to
+ /// be less efficient. Avoid this strategy if doing lots of I/O. Currently
+ /// based on physical cores, if available for the host system, otherwise falls
+ /// back to hardware_concurrency(). Returns 1 when LLVM is configured with
+ /// LLVM_ENABLE_THREADS = OFF.
+ inline ThreadPoolStrategy
+ heavyweight_hardware_concurrency(unsigned ThreadCount = 0) {
+ ThreadPoolStrategy S;
+ S.UseHyperThreads = false;
+ S.ThreadsRequested = ThreadCount;
+ return S;
+ }
+
+ /// Like heavyweight_hardware_concurrency() above, but builds a strategy
+ /// based on the rules described for get_threadpool_strategy().
+ /// If \p Num is invalid, returns a default strategy where one thread per
+ /// hardware core is used.
+ inline ThreadPoolStrategy heavyweight_hardware_concurrency(StringRef Num) {
+ Optional<ThreadPoolStrategy> S =
+ get_threadpool_strategy(Num, heavyweight_hardware_concurrency());
+ if (S)
+ return *S;
+ return heavyweight_hardware_concurrency();
+ }
+
+ /// Returns a default thread strategy where all available hardware ressources
+ /// are to be used, except for those initially excluded by an affinity mask.
+ /// This function takes affinity into consideration. Returns 1 when LLVM is
+ /// configured with LLVM_ENABLE_THREADS=OFF.
+ inline ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount = 0) {
+ ThreadPoolStrategy S;
+ S.ThreadsRequested = ThreadCount;
+ return S;
+ }
/// Return the current thread id, as used in various OS system calls.
/// Note that not all platforms guarantee that the value returned will be
@@ -184,6 +246,14 @@ void llvm_execute_on_thread_async(
/// the operation succeeded or failed is returned.
void get_thread_name(SmallVectorImpl<char> &Name);
+ /// Returns a mask that represents on which hardware thread, core, CPU, NUMA
+ /// group, the calling thread can be executed. On Windows, threads cannot
+ /// cross CPU sockets boundaries.
+ llvm::BitVector get_thread_affinity_mask();
+
+ /// Returns how many physical CPUs or NUMA groups the system has.
+ unsigned get_cpus();
+
enum class ThreadPriority {
Background = 0,
Default = 1,
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TimeProfiler.h b/contrib/llvm-project/llvm/include/llvm/Support/TimeProfiler.h
index 678f8c136811..b6f8a647e3ee 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TimeProfiler.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TimeProfiler.h
@@ -9,12 +9,13 @@
#ifndef LLVM_SUPPORT_TIME_PROFILER_H
#define LLVM_SUPPORT_TIME_PROFILER_H
+#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
struct TimeTraceProfiler;
-extern TimeTraceProfiler *TimeTraceProfilerInstance;
+TimeTraceProfiler *getTimeTraceProfilerInstance();
/// Initialize the time trace profiler.
/// This sets up the global \p TimeTraceProfilerInstance
@@ -25,16 +26,27 @@ void timeTraceProfilerInitialize(unsigned TimeTraceGranularity,
/// Cleanup the time trace profiler, if it was initialized.
void timeTraceProfilerCleanup();
+/// Finish a time trace profiler running on a worker thread.
+void timeTraceProfilerFinishThread();
+
/// Is the time trace profiler enabled, i.e. initialized?
inline bool timeTraceProfilerEnabled() {
- return TimeTraceProfilerInstance != nullptr;
+ return getTimeTraceProfilerInstance() != nullptr;
}
-/// Write profiling data to output file.
+/// Write profiling data to output stream.
/// Data produced is JSON, in Chrome "Trace Event" format, see
/// https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
void timeTraceProfilerWrite(raw_pwrite_stream &OS);
+/// Write profiling data to a file.
+/// The function will write to \p PreferredFileName if provided, if not
+/// then will write to \p FallbackFileName appending .time-trace.
+/// Returns a StringError indicating a failure if the function is
+/// unable to open the file for writing.
+Error timeTraceProfilerWrite(StringRef PreferredFileName,
+ StringRef FallbackFileName);
+
/// Manually begin a time section, with the given \p Name and \p Detail.
/// Profiler copies the string data, so the pointers can be given into
/// temporaries. Time sections can be hierarchical; every Begin must have a
@@ -59,19 +71,19 @@ struct TimeTraceScope {
TimeTraceScope &operator=(TimeTraceScope &&) = delete;
TimeTraceScope(StringRef Name) {
- if (TimeTraceProfilerInstance != nullptr)
+ if (getTimeTraceProfilerInstance() != nullptr)
timeTraceProfilerBegin(Name, StringRef(""));
}
TimeTraceScope(StringRef Name, StringRef Detail) {
- if (TimeTraceProfilerInstance != nullptr)
+ if (getTimeTraceProfilerInstance() != nullptr)
timeTraceProfilerBegin(Name, Detail);
}
TimeTraceScope(StringRef Name, llvm::function_ref<std::string()> Detail) {
- if (TimeTraceProfilerInstance != nullptr)
+ if (getTimeTraceProfilerInstance() != nullptr)
timeTraceProfilerBegin(Name, Detail);
}
~TimeTraceScope() {
- if (TimeTraceProfilerInstance != nullptr)
+ if (getTimeTraceProfilerInstance() != nullptr)
timeTraceProfilerEnd();
}
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/ToolOutputFile.h b/contrib/llvm-project/llvm/include/llvm/Support/ToolOutputFile.h
index a99e327f8db7..cf01b9ecefc5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/ToolOutputFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/ToolOutputFile.h
@@ -13,6 +13,7 @@
#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
+#include "llvm/ADT/Optional.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -38,8 +39,12 @@ class ToolOutputFile {
~CleanupInstaller();
} Installer;
- /// The contained stream. This is intentionally declared after Installer.
- raw_fd_ostream OS;
+ /// Storage for the stream, if we're owning our own stream. This is
+ /// intentionally declared after Installer.
+ Optional<raw_fd_ostream> OSHolder;
+
+ /// The actual stream to use.
+ raw_fd_ostream *OS;
public:
/// This constructor's arguments are passed to raw_fd_ostream's
@@ -50,7 +55,7 @@ public:
ToolOutputFile(StringRef Filename, int FD);
/// Return the contained raw_fd_ostream.
- raw_fd_ostream &os() { return OS; }
+ raw_fd_ostream &os() { return *OS; }
/// Indicate that the tool's job wrt this output file has been successful and
/// the file should not be deleted.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TrailingObjects.h b/contrib/llvm-project/llvm/include/llvm/Support/TrailingObjects.h
index 49be89613c43..0d9c4503aa9b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TrailingObjects.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TrailingObjects.h
@@ -326,8 +326,8 @@ public:
/// used in the class; they are supplied here redundantly only so
/// that it's clear what the counts are counting in callers.
template <typename... Tys>
- static constexpr typename std::enable_if<
- std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>::type
+ static constexpr std::enable_if_t<
+ std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>
additionalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType<
TrailingTys, size_t>::type... Counts) {
return ParentType::additionalSizeToAllocImpl(0, Counts...);
@@ -338,8 +338,8 @@ public:
/// additionalSizeToAlloc, except it *does* include the size of the base
/// object.
template <typename... Tys>
- static constexpr typename std::enable_if<
- std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>::type
+ static constexpr std::enable_if_t<
+ std::is_same<Foo<TrailingTys...>, Foo<Tys...>>::value, size_t>
totalSizeToAlloc(typename trailing_objects_internal::ExtractSecondType<
TrailingTys, size_t>::type... Counts) {
return sizeof(BaseTy) + ParentType::additionalSizeToAllocImpl(0, Counts...);
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TrigramIndex.h b/contrib/llvm-project/llvm/include/llvm/Support/TrigramIndex.h
index 9351c2db169a..d635694eb5fd 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TrigramIndex.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TrigramIndex.h
@@ -27,7 +27,6 @@
#define LLVM_SUPPORT_TRIGRAMINDEX_H
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
#include <string>
#include <unordered_map>
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/TypeSize.h b/contrib/llvm-project/llvm/include/llvm/Support/TypeSize.h
index 7ea651f0f22c..76564c401e8e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/TypeSize.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/TypeSize.h
@@ -15,17 +15,24 @@
#ifndef LLVM_SUPPORT_TYPESIZE_H
#define LLVM_SUPPORT_TYPESIZE_H
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/WithColor.h"
+
+#include <cstdint>
#include <cassert>
-#include <tuple>
namespace llvm {
+template <typename T> struct DenseMapInfo;
+
class ElementCount {
public:
unsigned Min; // Minimum number of vector elements.
bool Scalable; // If true, NumElements is a multiple of 'Min' determined
// at runtime rather than compile time.
+ ElementCount() = default;
+
ElementCount(unsigned Min, bool Scalable)
: Min(Min), Scalable(Scalable) {}
@@ -33,6 +40,7 @@ public:
return { Min * RHS, Scalable };
}
ElementCount operator/(unsigned RHS) {
+ assert(Min % RHS == 0 && "Min is not a multiple of RHS.");
return { Min / RHS, Scalable };
}
@@ -42,6 +50,12 @@ public:
bool operator!=(const ElementCount& RHS) const {
return !(*this == RHS);
}
+ bool operator==(unsigned RHS) const { return Min == RHS && !Scalable; }
+ bool operator!=(unsigned RHS) const { return !(*this == RHS); }
+
+ ElementCount NextPowerOf2() const {
+ return ElementCount(llvm::NextPowerOf2(Min), Scalable);
+ }
};
// This class is used to represent the size of types. If the type is of fixed
@@ -68,8 +82,7 @@ public:
// not guaranteed to be the same size at runtime, so they are never
// considered to be equal.
friend bool operator==(const TypeSize &LHS, const TypeSize &RHS) {
- return std::tie(LHS.MinSize, LHS.IsScalable) ==
- std::tie(RHS.MinSize, RHS.IsScalable);
+ return LHS.MinSize == RHS.MinSize && LHS.IsScalable == RHS.IsScalable;
}
friend bool operator!=(const TypeSize &LHS, const TypeSize &RHS) {
@@ -143,12 +156,40 @@ public:
return (MinSize & 7) == 0;
}
+ // Returns true if the type size is non-zero.
+ bool isNonZero() const { return MinSize != 0; }
+
+ // Returns true if the type size is zero.
+ bool isZero() const { return MinSize == 0; }
+
// Casts to a uint64_t if this is a fixed-width size.
//
- // NOTE: This interface is obsolete and will be removed in a future version
- // of LLVM in favour of calling getFixedSize() directly.
+ // This interface is deprecated and will be removed in a future version
+ // of LLVM in favour of upgrading uses that rely on this implicit conversion
+ // to uint64_t. Calls to functions that return a TypeSize should use the
+ // proper interfaces to TypeSize.
+ // In practice this is mostly calls to MVT/EVT::getSizeInBits().
+ //
+ // To determine how to upgrade the code:
+ //
+ // if (<algorithm works for both scalable and fixed-width vectors>)
+ // use getKnownMinSize()
+ // else if (<algorithm works only for fixed-width vectors>) {
+ // if <algorithm can be adapted for both scalable and fixed-width vectors>
+ // update the algorithm and use getKnownMinSize()
+ // else
+ // bail out early for scalable vectors and use getFixedSize()
+ // }
operator uint64_t() const {
+#ifdef STRICT_FIXED_SIZE_VECTORS
return getFixedSize();
+#else
+ if (isScalable())
+ WithColor::warning() << "Compiler has made implicit assumption that "
+ "TypeSize is not scalable. This may or may not "
+ "lead to broken code.\n";
+ return getKnownMinSize();
+#endif
}
// Additional convenience operators needed to avoid ambiguous parses.
@@ -188,6 +229,10 @@ public:
TypeSize operator/(int64_t RHS) const {
return { MinSize / RHS, IsScalable };
}
+
+ TypeSize NextPowerOf2() const {
+ return TypeSize(llvm::NextPowerOf2(MinSize), IsScalable);
+ }
};
/// Returns a TypeSize with a known minimum size that is the next integer
@@ -201,6 +246,21 @@ inline TypeSize alignTo(TypeSize Size, uint64_t Align) {
Size.isScalable()};
}
+template <> struct DenseMapInfo<ElementCount> {
+ static inline ElementCount getEmptyKey() { return {~0U, true}; }
+ static inline ElementCount getTombstoneKey() { return {~0U - 1, false}; }
+ static unsigned getHashValue(const ElementCount& EltCnt) {
+ if (EltCnt.Scalable)
+ return (EltCnt.Min * 37U) - 1U;
+
+ return EltCnt.Min * 37U;
+ }
+
+ static bool isEqual(const ElementCount& LHS, const ElementCount& RHS) {
+ return LHS == RHS;
+ }
+};
+
} // end namespace llvm
#endif // LLVM_SUPPORT_TypeSize_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/VersionTuple.h b/contrib/llvm-project/llvm/include/llvm/Support/VersionTuple.h
index f3eeea2f7b44..6f3711f06f1a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/VersionTuple.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/VersionTuple.h
@@ -14,13 +14,14 @@
#ifndef LLVM_SUPPORT_VERSIONTUPLE_H
#define LLVM_SUPPORT_VERSIONTUPLE_H
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
#include <string>
#include <tuple>
namespace llvm {
+class raw_ostream;
+class StringRef;
/// Represents a version number in the form major[.minor[.subminor[.build]]].
class VersionTuple {
@@ -144,6 +145,10 @@ public:
return !(X < Y);
}
+ friend llvm::hash_code hash_value(const VersionTuple &VT) {
+ return llvm::hash_combine(VT.Major, VT.Minor, VT.Subminor, VT.Build);
+ }
+
/// Retrieve a string representation of the version number.
std::string getAsString() const;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/VirtualFileSystem.h b/contrib/llvm-project/llvm/include/llvm/Support/VirtualFileSystem.h
index e45e6e756786..af09c21085c5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/VirtualFileSystem.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/VirtualFileSystem.h
@@ -19,7 +19,6 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Twine.h"
#include "llvm/Support/Chrono.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/FileSystem.h"
@@ -38,6 +37,7 @@
namespace llvm {
class MemoryBuffer;
+class Twine;
namespace vfs {
@@ -506,10 +506,12 @@ getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer,
struct YAMLVFSEntry {
template <typename T1, typename T2>
- YAMLVFSEntry(T1 &&VPath, T2 &&RPath)
- : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)) {}
+ YAMLVFSEntry(T1 &&VPath, T2 &&RPath, bool IsDirectory = false)
+ : VPath(std::forward<T1>(VPath)), RPath(std::forward<T2>(RPath)),
+ IsDirectory(IsDirectory) {}
std::string VPath;
std::string RPath;
+ bool IsDirectory = false;
};
class VFSFromYamlDirIterImpl;
@@ -654,7 +656,7 @@ private:
// In a RedirectingFileSystem, keys can be specified in Posix or Windows
// style (or even a mixture of both), so this comparison helper allows
// slashes (representing a root) to match backslashes (and vice versa). Note
- // that, other than the root, patch components should not contain slashes or
+ // that, other than the root, path components should not contain slashes or
// backslashes.
bool pathComponentMatches(llvm::StringRef lhs, llvm::StringRef rhs) const {
if ((CaseSensitive ? lhs.equals(rhs) : lhs.equals_lower(rhs)))
@@ -705,16 +707,6 @@ private:
bool IsFallthrough = true;
/// @}
- /// Virtual file paths and external files could be canonicalized without "..",
- /// "." and "./" in their paths. FIXME: some unittests currently fail on
- /// win32 when using remove_dots and remove_leading_dotslash on paths.
- bool UseCanonicalizedPaths =
-#ifdef _WIN32
- false;
-#else
- true;
-#endif
-
RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS);
/// Looks up the path <tt>[Start, End)</tt> in \p From, possibly
@@ -781,10 +773,13 @@ class YAMLVFSWriter {
Optional<bool> UseExternalNames;
std::string OverlayDir;
+ void addEntry(StringRef VirtualPath, StringRef RealPath, bool IsDirectory);
+
public:
YAMLVFSWriter() = default;
void addFileMapping(StringRef VirtualPath, StringRef RealPath);
+ void addDirectoryMapping(StringRef VirtualPath, StringRef RealPath);
void setCaseSensitivity(bool CaseSensitive) {
IsCaseSensitive = CaseSensitive;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/Windows/WindowsSupport.h b/contrib/llvm-project/llvm/include/llvm/Support/Windows/WindowsSupport.h
index bb7e79b86018..bd5a90c2c3f0 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/Windows/WindowsSupport.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/Windows/WindowsSupport.h
@@ -236,6 +236,12 @@ namespace windows {
// UTF-8 regardless of the current code page setting.
std::error_code GetCommandLineArguments(SmallVectorImpl<const char *> &Args,
BumpPtrAllocator &Alloc);
+
+/// Convert UTF-8 path to a suitable UTF-16 path for use with the Win32 Unicode
+/// File API.
+std::error_code widenPath(const Twine &Path8, SmallVectorImpl<wchar_t> &Path16,
+ size_t MaxPathLen = MAX_PATH);
+
} // end namespace windows
} // end namespace sys
} // end namespace llvm.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/WithColor.h b/contrib/llvm-project/llvm/include/llvm/Support/WithColor.h
index f4e107581179..eea4a7229339 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/WithColor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/WithColor.h
@@ -9,14 +9,18 @@
#ifndef LLVM_SUPPORT_WITHCOLOR_H
#define LLVM_SUPPORT_WITHCOLOR_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
-extern cl::OptionCategory ColorCategory;
+class Error;
+class StringRef;
+
+namespace cl {
+class OptionCategory;
+}
-class raw_ostream;
+extern cl::OptionCategory ColorCategory;
// Symbolic names for various syntax elements.
enum class HighlightColor {
@@ -32,31 +36,43 @@ enum class HighlightColor {
Remark
};
+enum class ColorMode {
+ /// Determine whether to use color based on the command line argument and the
+ /// raw_ostream.
+ Auto,
+ /// Enable colors. Because raw_ostream is the one implementing colors, this
+ /// has no effect if the stream does not support colors or has colors
+ /// disabled.
+ Enable,
+ /// Disable colors.
+ Disable,
+};
+
/// An RAII object that temporarily switches an output stream to a specific
/// color.
class WithColor {
raw_ostream &OS;
- bool DisableColors;
+ ColorMode Mode;
public:
/// To be used like this: WithColor(OS, HighlightColor::String) << "text";
/// @param OS The output stream
/// @param S Symbolic name for syntax element to color
- /// @param DisableColors Whether to ignore color changes regardless of -color
- /// and support in OS
- WithColor(raw_ostream &OS, HighlightColor S, bool DisableColors = false);
+ /// @param Mode Enable, disable or compute whether to use colors.
+ WithColor(raw_ostream &OS, HighlightColor S,
+ ColorMode Mode = ColorMode::Auto);
/// To be used like this: WithColor(OS, raw_ostream::Black) << "text";
/// @param OS The output stream
/// @param Color ANSI color to use, the special SAVEDCOLOR can be used to
/// change only the bold attribute, and keep colors untouched
/// @param Bold Bold/brighter text, default false
/// @param BG If true, change the background, default: change foreground
- /// @param DisableColors Whether to ignore color changes regardless of -color
- /// and support in OS
+ /// @param Mode Enable, disable or compute whether to use colors.
WithColor(raw_ostream &OS,
raw_ostream::Colors Color = raw_ostream::SAVEDCOLOR,
- bool Bold = false, bool BG = false, bool DisableColors = false)
- : OS(OS), DisableColors(DisableColors) {
+ bool Bold = false, bool BG = false,
+ ColorMode Mode = ColorMode::Auto)
+ : OS(OS), Mode(Mode) {
changeColor(Color, Bold, BG);
}
~WithColor();
@@ -108,6 +124,14 @@ public:
/// Reset the colors to terminal defaults. Call this when you are done
/// outputting colored text, or before program exit.
WithColor &resetColor();
+
+ /// Implement default handling for Error.
+ /// Print "error: " to stderr.
+ static void defaultErrorHandler(Error Err);
+
+ /// Implement default handling for Warning.
+ /// Print "warning: " to stderr.
+ static void defaultWarningHandler(Error Warning);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h b/contrib/llvm-project/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
index baf842b12a27..5697ff9a01dc 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/X86DisassemblerDecoderCommon.h
@@ -361,6 +361,7 @@ enum ModRMDecisionType {
ENUM_ENTRY(ENCODING_RM_CD16,"R/M operand with CDisp scaling of 16") \
ENUM_ENTRY(ENCODING_RM_CD32,"R/M operand with CDisp scaling of 32") \
ENUM_ENTRY(ENCODING_RM_CD64,"R/M operand with CDisp scaling of 64") \
+ ENUM_ENTRY(ENCODING_SIB, "Force SIB operand in ModR/M byte.") \
ENUM_ENTRY(ENCODING_VSIB, "VSIB operand in ModR/M byte.") \
ENUM_ENTRY(ENCODING_VSIB_CD2, "VSIB operand with CDisp scaling of 2") \
ENUM_ENTRY(ENCODING_VSIB_CD4, "VSIB operand with CDisp scaling of 4") \
@@ -374,7 +375,7 @@ enum ModRMDecisionType {
ENUM_ENTRY(ENCODING_IW, "2-byte") \
ENUM_ENTRY(ENCODING_ID, "4-byte") \
ENUM_ENTRY(ENCODING_IO, "8-byte") \
- ENUM_ENTRY(ENCODING_RB, "(AL..DIL, R8L..R15L) Register code added to " \
+ ENUM_ENTRY(ENCODING_RB, "(AL..DIL, R8B..R15B) Register code added to " \
"the opcode byte") \
ENUM_ENTRY(ENCODING_RW, "(AX..DI, R8W..R15W)") \
ENUM_ENTRY(ENCODING_RD, "(EAX..EDI, R8D..R15D)") \
@@ -411,6 +412,7 @@ enum OperandEncoding {
ENUM_ENTRY(TYPE_IMM, "immediate operand") \
ENUM_ENTRY(TYPE_UIMM8, "1-byte unsigned immediate operand") \
ENUM_ENTRY(TYPE_M, "Memory operand") \
+ ENUM_ENTRY(TYPE_MSIB, "Memory operand force sib encoding") \
ENUM_ENTRY(TYPE_MVSIBX, "Memory operand using XMM index") \
ENUM_ENTRY(TYPE_MVSIBY, "Memory operand using YMM index") \
ENUM_ENTRY(TYPE_MVSIBZ, "Memory operand using ZMM index") \
@@ -424,6 +426,7 @@ enum OperandEncoding {
ENUM_ENTRY(TYPE_ZMM, "64-byte") \
ENUM_ENTRY(TYPE_VK, "mask register") \
ENUM_ENTRY(TYPE_VK_PAIR, "mask register pair") \
+ ENUM_ENTRY(TYPE_TMM, "tile") \
ENUM_ENTRY(TYPE_SEGMENTREG, "Segment register operand") \
ENUM_ENTRY(TYPE_DEBUGREG, "Debug register operand") \
ENUM_ENTRY(TYPE_CONTROLREG, "Control register operand") \
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.def b/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.def
index 4ebf2d79cb8d..697f8c70f962 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.def
+++ b/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.def
@@ -19,155 +19,176 @@ X86_VENDOR(VENDOR_INTEL, "intel")
X86_VENDOR(VENDOR_AMD, "amd")
#undef X86_VENDOR
-// This macro is used to implement CPU types that have an alias. As of now
-// there is only ever one alias.
-#ifndef X86_CPU_TYPE_COMPAT_WITH_ALIAS
-#define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS) X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR)
-#endif
-
// This macro is used for cpu types present in compiler-rt/libgcc.
-#ifndef X86_CPU_TYPE_COMPAT
-#define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) X86_CPU_TYPE(ARCHNAME, ENUM)
+#ifndef X86_CPU_TYPE
+#define X86_CPU_TYPE(ENUM, STR)
#endif
-#ifndef X86_CPU_TYPE
-#define X86_CPU_TYPE(ARCHNAME, ENUM)
+#ifndef X86_CPU_TYPE_ALIAS
+#define X86_CPU_TYPE_ALIAS(ENUM, STR)
#endif
-// The first part of this list must match what is implemented in libgcc and
-// compilert-rt. Clang uses this to know how to implement __builtin_cpu_is.
-X86_CPU_TYPE_COMPAT_WITH_ALIAS("bonnell", INTEL_BONNELL, "bonnell", "atom")
-X86_CPU_TYPE_COMPAT ("core2", INTEL_CORE2, "core2")
-X86_CPU_TYPE_COMPAT ("nehalem", INTEL_COREI7, "corei7")
-X86_CPU_TYPE_COMPAT_WITH_ALIAS("amdfam10", AMDFAM10H, "amdfam10h", "amdfam10")
-X86_CPU_TYPE_COMPAT_WITH_ALIAS("bdver1", AMDFAM15H, "amdfam15h", "amdfam15")
-X86_CPU_TYPE_COMPAT_WITH_ALIAS("silvermont", INTEL_SILVERMONT, "silvermont", "slm")
-X86_CPU_TYPE_COMPAT ("knl", INTEL_KNL, "knl")
-X86_CPU_TYPE_COMPAT ("btver1", AMD_BTVER1, "btver1")
-X86_CPU_TYPE_COMPAT ("btver2", AMD_BTVER2, "btver2")
-X86_CPU_TYPE_COMPAT ("znver1", AMDFAM17H, "amdfam17h")
-X86_CPU_TYPE_COMPAT ("knm", INTEL_KNM, "knm")
-X86_CPU_TYPE_COMPAT ("goldmont", INTEL_GOLDMONT, "goldmont")
-X86_CPU_TYPE_COMPAT ("goldmont-plus", INTEL_GOLDMONT_PLUS, "goldmont-plus")
-X86_CPU_TYPE_COMPAT ("tremont", INTEL_TREMONT, "tremont")
-// Entries below this are not in libgcc/compiler-rt.
-X86_CPU_TYPE ("i386", INTEL_i386)
-X86_CPU_TYPE ("i486", INTEL_i486)
-X86_CPU_TYPE ("pentium", INTEL_PENTIUM)
-X86_CPU_TYPE ("pentium-mmx", INTEL_PENTIUM_MMX)
-X86_CPU_TYPE ("pentiumpro", INTEL_PENTIUM_PRO)
-X86_CPU_TYPE ("pentium2", INTEL_PENTIUM_II)
-X86_CPU_TYPE ("pentium3", INTEL_PENTIUM_III)
-X86_CPU_TYPE ("pentium4", INTEL_PENTIUM_IV)
-X86_CPU_TYPE ("pentium-m", INTEL_PENTIUM_M)
-X86_CPU_TYPE ("yonah", INTEL_CORE_DUO)
-X86_CPU_TYPE ("nocona", INTEL_NOCONA)
-X86_CPU_TYPE ("prescott", INTEL_PRESCOTT)
-X86_CPU_TYPE ("i486", AMD_i486)
-X86_CPU_TYPE ("pentium", AMDPENTIUM)
-X86_CPU_TYPE ("athlon", AMD_ATHLON)
-X86_CPU_TYPE ("athlon-xp", AMD_ATHLON_XP)
-X86_CPU_TYPE ("k8", AMD_K8)
-X86_CPU_TYPE ("k8-sse3", AMD_K8SSE3)
-#undef X86_CPU_TYPE_COMPAT_WITH_ALIAS
-#undef X86_CPU_TYPE_COMPAT
+
+// This list must match what is implemented in libgcc and compilert-rt. Clang
+// uses this to know how to implement __builtin_cpu_is.
+X86_CPU_TYPE(INTEL_BONNELL, "bonnell")
+X86_CPU_TYPE(INTEL_CORE2, "core2")
+X86_CPU_TYPE(INTEL_COREI7, "corei7")
+X86_CPU_TYPE(AMDFAM10H, "amdfam10h")
+X86_CPU_TYPE(AMDFAM15H, "amdfam15h")
+X86_CPU_TYPE(INTEL_SILVERMONT, "silvermont")
+X86_CPU_TYPE(INTEL_KNL, "knl")
+X86_CPU_TYPE(AMD_BTVER1, "btver1")
+X86_CPU_TYPE(AMD_BTVER2, "btver2")
+X86_CPU_TYPE(AMDFAM17H, "amdfam17h")
+X86_CPU_TYPE(INTEL_KNM, "knm")
+X86_CPU_TYPE(INTEL_GOLDMONT, "goldmont")
+X86_CPU_TYPE(INTEL_GOLDMONT_PLUS, "goldmont-plus")
+X86_CPU_TYPE(INTEL_TREMONT, "tremont")
+
+// Alternate names supported by __builtin_cpu_is and target multiversioning.
+X86_CPU_TYPE_ALIAS(INTEL_BONNELL, "atom")
+X86_CPU_TYPE_ALIAS(AMDFAM10H, "amdfam10")
+X86_CPU_TYPE_ALIAS(AMDFAM15H, "amdfam15")
+X86_CPU_TYPE_ALIAS(INTEL_SILVERMONT, "slm")
+
+#undef X86_CPU_TYPE_ALIAS
#undef X86_CPU_TYPE
// This macro is used for cpu subtypes present in compiler-rt/libgcc.
-#ifndef X86_CPU_SUBTYPE_COMPAT
-#define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) X86_CPU_SUBTYPE(ARCHNAME, ENUM)
-#endif
-
#ifndef X86_CPU_SUBTYPE
-#define X86_CPU_SUBTYPE(ARCHNAME, ENUM)
+#define X86_CPU_SUBTYPE(ENUM, STR)
#endif
-// The first part of this list must match what is implemented in libgcc and
-// compilert-rt. Clang uses this to know how to implement __builtin_cpu_is.
-X86_CPU_SUBTYPE_COMPAT("nehalem", INTEL_COREI7_NEHALEM, "nehalem")
-X86_CPU_SUBTYPE_COMPAT("westmere", INTEL_COREI7_WESTMERE, "westmere")
-X86_CPU_SUBTYPE_COMPAT("sandybridge", INTEL_COREI7_SANDYBRIDGE, "sandybridge")
-X86_CPU_SUBTYPE_COMPAT("amdfam10", AMDFAM10H_BARCELONA, "barcelona")
-X86_CPU_SUBTYPE_COMPAT("amdfam10", AMDFAM10H_SHANGHAI, "shanghai")
-X86_CPU_SUBTYPE_COMPAT("amdfam10", AMDFAM10H_ISTANBUL, "istanbul")
-X86_CPU_SUBTYPE_COMPAT("bdver1", AMDFAM15H_BDVER1, "bdver1")
-X86_CPU_SUBTYPE_COMPAT("bdver2", AMDFAM15H_BDVER2, "bdver2")
-X86_CPU_SUBTYPE_COMPAT("bdver3", AMDFAM15H_BDVER3, "bdver3")
-X86_CPU_SUBTYPE_COMPAT("bdver4", AMDFAM15H_BDVER4, "bdver4")
-X86_CPU_SUBTYPE_COMPAT("znver1", AMDFAM17H_ZNVER1, "znver1")
-X86_CPU_SUBTYPE_COMPAT("ivybridge", INTEL_COREI7_IVYBRIDGE, "ivybridge")
-X86_CPU_SUBTYPE_COMPAT("haswell", INTEL_COREI7_HASWELL, "haswell")
-X86_CPU_SUBTYPE_COMPAT("broadwell", INTEL_COREI7_BROADWELL, "broadwell")
-X86_CPU_SUBTYPE_COMPAT("skylake", INTEL_COREI7_SKYLAKE, "skylake")
-X86_CPU_SUBTYPE_COMPAT("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512, "skylake-avx512")
-X86_CPU_SUBTYPE_COMPAT("cannonlake", INTEL_COREI7_CANNONLAKE, "cannonlake")
-X86_CPU_SUBTYPE_COMPAT("icelake-client", INTEL_COREI7_ICELAKE_CLIENT, "icelake-client")
-X86_CPU_SUBTYPE_COMPAT("icelake-server", INTEL_COREI7_ICELAKE_SERVER, "icelake-server")
-X86_CPU_SUBTYPE_COMPAT("znver2", AMDFAM17H_ZNVER2, "znver2")
-X86_CPU_SUBTYPE_COMPAT("cascadelake", INTEL_COREI7_CASCADELAKE, "cascadelake")
-// Entries below this are not in libgcc/compiler-rt.
-X86_CPU_SUBTYPE ("core2", INTEL_CORE2_65)
-X86_CPU_SUBTYPE ("penryn", INTEL_CORE2_45)
-X86_CPU_SUBTYPE ("k6", AMDPENTIUM_K6)
-X86_CPU_SUBTYPE ("k6-2", AMDPENTIUM_K62)
-X86_CPU_SUBTYPE ("k6-3", AMDPENTIUM_K63)
-X86_CPU_SUBTYPE ("geode", AMDPENTIUM_GEODE)
-X86_CPU_SUBTYPE ("cooperlake", INTEL_COREI7_COOPERLAKE)
-X86_CPU_SUBTYPE ("tigerlake", INTEL_COREI7_TIGERLAKE)
-#undef X86_CPU_SUBTYPE_COMPAT
+// This list must match what is implemented in libgcc and compilert-rt. Clang
+// uses this to know how to implement __builtin_cpu_is.
+X86_CPU_SUBTYPE(INTEL_COREI7_NEHALEM, "nehalem")
+X86_CPU_SUBTYPE(INTEL_COREI7_WESTMERE, "westmere")
+X86_CPU_SUBTYPE(INTEL_COREI7_SANDYBRIDGE, "sandybridge")
+X86_CPU_SUBTYPE(AMDFAM10H_BARCELONA, "barcelona")
+X86_CPU_SUBTYPE(AMDFAM10H_SHANGHAI, "shanghai")
+X86_CPU_SUBTYPE(AMDFAM10H_ISTANBUL, "istanbul")
+X86_CPU_SUBTYPE(AMDFAM15H_BDVER1, "bdver1")
+X86_CPU_SUBTYPE(AMDFAM15H_BDVER2, "bdver2")
+X86_CPU_SUBTYPE(AMDFAM15H_BDVER3, "bdver3")
+X86_CPU_SUBTYPE(AMDFAM15H_BDVER4, "bdver4")
+X86_CPU_SUBTYPE(AMDFAM17H_ZNVER1, "znver1")
+X86_CPU_SUBTYPE(INTEL_COREI7_IVYBRIDGE, "ivybridge")
+X86_CPU_SUBTYPE(INTEL_COREI7_HASWELL, "haswell")
+X86_CPU_SUBTYPE(INTEL_COREI7_BROADWELL, "broadwell")
+X86_CPU_SUBTYPE(INTEL_COREI7_SKYLAKE, "skylake")
+X86_CPU_SUBTYPE(INTEL_COREI7_SKYLAKE_AVX512, "skylake-avx512")
+X86_CPU_SUBTYPE(INTEL_COREI7_CANNONLAKE, "cannonlake")
+X86_CPU_SUBTYPE(INTEL_COREI7_ICELAKE_CLIENT, "icelake-client")
+X86_CPU_SUBTYPE(INTEL_COREI7_ICELAKE_SERVER, "icelake-server")
+X86_CPU_SUBTYPE(AMDFAM17H_ZNVER2, "znver2")
+X86_CPU_SUBTYPE(INTEL_COREI7_CASCADELAKE, "cascadelake")
+X86_CPU_SUBTYPE(INTEL_COREI7_TIGERLAKE, "tigerlake")
+X86_CPU_SUBTYPE(INTEL_COREI7_COOPERLAKE, "cooperlake")
#undef X86_CPU_SUBTYPE
// This macro is used for cpu types present in compiler-rt/libgcc.
#ifndef X86_FEATURE_COMPAT
-#define X86_FEATURE_COMPAT(VAL, ENUM, STR) X86_FEATURE(VAL, ENUM)
+#define X86_FEATURE_COMPAT(ENUM, STR) X86_FEATURE(ENUM, STR)
#endif
#ifndef X86_FEATURE
-#define X86_FEATURE(VAL, ENUM)
+#define X86_FEATURE(ENUM, STR)
#endif
-X86_FEATURE_COMPAT( 0, FEATURE_CMOV, "cmov")
-X86_FEATURE_COMPAT( 1, FEATURE_MMX, "mmx")
-X86_FEATURE_COMPAT( 2, FEATURE_POPCNT, "popcnt")
-X86_FEATURE_COMPAT( 3, FEATURE_SSE, "sse")
-X86_FEATURE_COMPAT( 4, FEATURE_SSE2, "sse2")
-X86_FEATURE_COMPAT( 5, FEATURE_SSE3, "sse3")
-X86_FEATURE_COMPAT( 6, FEATURE_SSSE3, "ssse3")
-X86_FEATURE_COMPAT( 7, FEATURE_SSE4_1, "sse4.1")
-X86_FEATURE_COMPAT( 8, FEATURE_SSE4_2, "sse4.2")
-X86_FEATURE_COMPAT( 9, FEATURE_AVX, "avx")
-X86_FEATURE_COMPAT(10, FEATURE_AVX2, "avx2")
-X86_FEATURE_COMPAT(11, FEATURE_SSE4_A, "sse4a")
-X86_FEATURE_COMPAT(12, FEATURE_FMA4, "fma4")
-X86_FEATURE_COMPAT(13, FEATURE_XOP, "xop")
-X86_FEATURE_COMPAT(14, FEATURE_FMA, "fma")
-X86_FEATURE_COMPAT(15, FEATURE_AVX512F, "avx512f")
-X86_FEATURE_COMPAT(16, FEATURE_BMI, "bmi")
-X86_FEATURE_COMPAT(17, FEATURE_BMI2, "bmi2")
-X86_FEATURE_COMPAT(18, FEATURE_AES, "aes")
-X86_FEATURE_COMPAT(19, FEATURE_PCLMUL, "pclmul")
-X86_FEATURE_COMPAT(20, FEATURE_AVX512VL, "avx512vl")
-X86_FEATURE_COMPAT(21, FEATURE_AVX512BW, "avx512bw")
-X86_FEATURE_COMPAT(22, FEATURE_AVX512DQ, "avx512dq")
-X86_FEATURE_COMPAT(23, FEATURE_AVX512CD, "avx512cd")
-X86_FEATURE_COMPAT(24, FEATURE_AVX512ER, "avx512er")
-X86_FEATURE_COMPAT(25, FEATURE_AVX512PF, "avx512pf")
-X86_FEATURE_COMPAT(26, FEATURE_AVX512VBMI, "avx512vbmi")
-X86_FEATURE_COMPAT(27, FEATURE_AVX512IFMA, "avx512ifma")
-X86_FEATURE_COMPAT(28, FEATURE_AVX5124VNNIW, "avx5124vnniw")
-X86_FEATURE_COMPAT(29, FEATURE_AVX5124FMAPS, "avx5124fmaps")
-X86_FEATURE_COMPAT(30, FEATURE_AVX512VPOPCNTDQ, "avx512vpopcntdq")
-X86_FEATURE_COMPAT(31, FEATURE_AVX512VBMI2, "avx512vbmi2")
-X86_FEATURE_COMPAT(32, FEATURE_GFNI, "gfni")
-X86_FEATURE_COMPAT(33, FEATURE_VPCLMULQDQ, "vpclmulqdq")
-X86_FEATURE_COMPAT(34, FEATURE_AVX512VNNI, "avx512vnni")
-X86_FEATURE_COMPAT(35, FEATURE_AVX512BITALG, "avx512bitalg")
-X86_FEATURE_COMPAT(36, FEATURE_AVX512BF16, "avx512bf16")
+
+X86_FEATURE_COMPAT(CMOV, "cmov")
+X86_FEATURE_COMPAT(MMX, "mmx")
+X86_FEATURE_COMPAT(POPCNT, "popcnt")
+X86_FEATURE_COMPAT(SSE, "sse")
+X86_FEATURE_COMPAT(SSE2, "sse2")
+X86_FEATURE_COMPAT(SSE3, "sse3")
+X86_FEATURE_COMPAT(SSSE3, "ssse3")
+X86_FEATURE_COMPAT(SSE4_1, "sse4.1")
+X86_FEATURE_COMPAT(SSE4_2, "sse4.2")
+X86_FEATURE_COMPAT(AVX, "avx")
+X86_FEATURE_COMPAT(AVX2, "avx2")
+X86_FEATURE_COMPAT(SSE4_A, "sse4a")
+X86_FEATURE_COMPAT(FMA4, "fma4")
+X86_FEATURE_COMPAT(XOP, "xop")
+X86_FEATURE_COMPAT(FMA, "fma")
+X86_FEATURE_COMPAT(AVX512F, "avx512f")
+X86_FEATURE_COMPAT(BMI, "bmi")
+X86_FEATURE_COMPAT(BMI2, "bmi2")
+X86_FEATURE_COMPAT(AES, "aes")
+X86_FEATURE_COMPAT(PCLMUL, "pclmul")
+X86_FEATURE_COMPAT(AVX512VL, "avx512vl")
+X86_FEATURE_COMPAT(AVX512BW, "avx512bw")
+X86_FEATURE_COMPAT(AVX512DQ, "avx512dq")
+X86_FEATURE_COMPAT(AVX512CD, "avx512cd")
+X86_FEATURE_COMPAT(AVX512ER, "avx512er")
+X86_FEATURE_COMPAT(AVX512PF, "avx512pf")
+X86_FEATURE_COMPAT(AVX512VBMI, "avx512vbmi")
+X86_FEATURE_COMPAT(AVX512IFMA, "avx512ifma")
+X86_FEATURE_COMPAT(AVX5124VNNIW, "avx5124vnniw")
+X86_FEATURE_COMPAT(AVX5124FMAPS, "avx5124fmaps")
+X86_FEATURE_COMPAT(AVX512VPOPCNTDQ, "avx512vpopcntdq")
+X86_FEATURE_COMPAT(AVX512VBMI2, "avx512vbmi2")
+X86_FEATURE_COMPAT(GFNI, "gfni")
+X86_FEATURE_COMPAT(VPCLMULQDQ, "vpclmulqdq")
+X86_FEATURE_COMPAT(AVX512VNNI, "avx512vnni")
+X86_FEATURE_COMPAT(AVX512BITALG, "avx512bitalg")
+X86_FEATURE_COMPAT(AVX512BF16, "avx512bf16")
+X86_FEATURE_COMPAT(AVX512VP2INTERSECT, "avx512vp2intersect")
// Features below here are not in libgcc/compiler-rt.
-X86_FEATURE (64, FEATURE_MOVBE)
-X86_FEATURE (65, FEATURE_ADX)
-X86_FEATURE (66, FEATURE_EM64T)
-X86_FEATURE (67, FEATURE_CLFLUSHOPT)
-X86_FEATURE (68, FEATURE_SHA)
-X86_FEATURE (69, FEATURE_AVX512VP2INTERSECT)
+X86_FEATURE (3DNOW, "3dnow")
+X86_FEATURE (3DNOWA, "3dnowa")
+X86_FEATURE (64BIT, "64bit")
+X86_FEATURE (ADX, "adx")
+X86_FEATURE (AMX_BF16, "amx-bf16")
+X86_FEATURE (AMX_INT8, "amx-int8")
+X86_FEATURE (AMX_TILE, "amx-tile")
+X86_FEATURE (CLDEMOTE, "cldemote")
+X86_FEATURE (CLFLUSHOPT, "clflushopt")
+X86_FEATURE (CLWB, "clwb")
+X86_FEATURE (CLZERO, "clzero")
+X86_FEATURE (CMPXCHG16B, "cx16")
+X86_FEATURE (CMPXCHG8B, "cx8")
+X86_FEATURE (ENQCMD, "enqcmd")
+X86_FEATURE (F16C, "f16c")
+X86_FEATURE (FSGSBASE, "fsgsbase")
+X86_FEATURE (FXSR, "fxsr")
+X86_FEATURE (INVPCID, "invpcid")
+X86_FEATURE (LWP, "lwp")
+X86_FEATURE (LZCNT, "lzcnt")
+X86_FEATURE (MOVBE, "movbe")
+X86_FEATURE (MOVDIR64B, "movdir64b")
+X86_FEATURE (MOVDIRI, "movdiri")
+X86_FEATURE (MWAITX, "mwaitx")
+X86_FEATURE (PCONFIG, "pconfig")
+X86_FEATURE (PKU, "pku")
+X86_FEATURE (PREFETCHWT1, "prefetchwt1")
+X86_FEATURE (PRFCHW, "prfchw")
+X86_FEATURE (PTWRITE, "ptwrite")
+X86_FEATURE (RDPID, "rdpid")
+X86_FEATURE (RDRND, "rdrnd")
+X86_FEATURE (RDSEED, "rdseed")
+X86_FEATURE (RTM, "rtm")
+X86_FEATURE (SAHF, "sahf")
+X86_FEATURE (SERIALIZE, "serialize")
+X86_FEATURE (SGX, "sgx")
+X86_FEATURE (SHA, "sha")
+X86_FEATURE (SHSTK, "shstk")
+X86_FEATURE (TBM, "tbm")
+X86_FEATURE (TSXLDTRK, "tsxldtrk")
+X86_FEATURE (VAES, "vaes")
+X86_FEATURE (VZEROUPPER, "vzeroupper")
+X86_FEATURE (WAITPKG, "waitpkg")
+X86_FEATURE (WBNOINVD, "wbnoinvd")
+X86_FEATURE (X87, "x87")
+X86_FEATURE (XSAVE, "xsave")
+X86_FEATURE (XSAVEC, "xsavec")
+X86_FEATURE (XSAVEOPT, "xsaveopt")
+X86_FEATURE (XSAVES, "xsaves")
+// These features aren't really CPU features, but the frontend can set them.
+X86_FEATURE (RETPOLINE_EXTERNAL_THUNK, "retpoline-external-thunk")
+X86_FEATURE (RETPOLINE_INDIRECT_BRANCHES, "retpoline-indirect-branches")
+X86_FEATURE (RETPOLINE_INDIRECT_CALLS, "retpoline-indirect-calls")
+X86_FEATURE (LVI_CFI, "lvi-cfi")
+X86_FEATURE (LVI_LOAD_HARDENING, "lvi-load-hardening")
#undef X86_FEATURE_COMPAT
#undef X86_FEATURE
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.h b/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.h
new file mode 100644
index 000000000000..66c474b5c275
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Support/X86TargetParser.h
@@ -0,0 +1,148 @@
+//===-- X86TargetParser - Parser for X86 features ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a target parser to recognise X86 hardware features.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_X86TARGETPARSERCOMMON_H
+#define LLVM_SUPPORT_X86TARGETPARSERCOMMON_H
+
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+class StringRef;
+
+namespace X86 {
+
+// This should be kept in sync with libcc/compiler-rt as its included by clang
+// as a proxy for what's in libgcc/compiler-rt.
+enum ProcessorVendors : unsigned {
+ VENDOR_DUMMY,
+#define X86_VENDOR(ENUM, STRING) \
+ ENUM,
+#include "llvm/Support/X86TargetParser.def"
+ VENDOR_OTHER
+};
+
+// This should be kept in sync with libcc/compiler-rt as its included by clang
+// as a proxy for what's in libgcc/compiler-rt.
+enum ProcessorTypes : unsigned {
+ CPU_TYPE_DUMMY,
+#define X86_CPU_TYPE(ENUM, STRING) \
+ ENUM,
+#include "llvm/Support/X86TargetParser.def"
+ CPU_TYPE_MAX
+};
+
+// This should be kept in sync with libcc/compiler-rt as its included by clang
+// as a proxy for what's in libgcc/compiler-rt.
+enum ProcessorSubtypes : unsigned {
+ CPU_SUBTYPE_DUMMY,
+#define X86_CPU_SUBTYPE(ENUM, STRING) \
+ ENUM,
+#include "llvm/Support/X86TargetParser.def"
+ CPU_SUBTYPE_MAX
+};
+
+// This should be kept in sync with libcc/compiler-rt as it should be used
+// by clang as a proxy for what's in libgcc/compiler-rt.
+enum ProcessorFeatures {
+#define X86_FEATURE(ENUM, STRING) FEATURE_##ENUM,
+#include "llvm/Support/X86TargetParser.def"
+ CPU_FEATURE_MAX
+};
+
+enum CPUKind {
+ CK_None,
+ CK_i386,
+ CK_i486,
+ CK_WinChipC6,
+ CK_WinChip2,
+ CK_C3,
+ CK_i586,
+ CK_Pentium,
+ CK_PentiumMMX,
+ CK_PentiumPro,
+ CK_i686,
+ CK_Pentium2,
+ CK_Pentium3,
+ CK_PentiumM,
+ CK_C3_2,
+ CK_Yonah,
+ CK_Pentium4,
+ CK_Prescott,
+ CK_Nocona,
+ CK_Core2,
+ CK_Penryn,
+ CK_Bonnell,
+ CK_Silvermont,
+ CK_Goldmont,
+ CK_GoldmontPlus,
+ CK_Tremont,
+ CK_Nehalem,
+ CK_Westmere,
+ CK_SandyBridge,
+ CK_IvyBridge,
+ CK_Haswell,
+ CK_Broadwell,
+ CK_SkylakeClient,
+ CK_SkylakeServer,
+ CK_Cascadelake,
+ CK_Cooperlake,
+ CK_Cannonlake,
+ CK_IcelakeClient,
+ CK_IcelakeServer,
+ CK_Tigerlake,
+ CK_KNL,
+ CK_KNM,
+ CK_Lakemont,
+ CK_K6,
+ CK_K6_2,
+ CK_K6_3,
+ CK_Athlon,
+ CK_AthlonXP,
+ CK_K8,
+ CK_K8SSE3,
+ CK_AMDFAM10,
+ CK_BTVER1,
+ CK_BTVER2,
+ CK_BDVER1,
+ CK_BDVER2,
+ CK_BDVER3,
+ CK_BDVER4,
+ CK_ZNVER1,
+ CK_ZNVER2,
+ CK_x86_64,
+ CK_Geode,
+};
+
+/// Parse \p CPU string into a CPUKind. Will only accept 64-bit capable CPUs if
+/// \p Only64Bit is true.
+CPUKind parseArchX86(StringRef CPU, bool Only64Bit = false);
+
+/// Provide a list of valid CPU names. If \p Only64Bit is true, the list will
+/// only contain 64-bit capable CPUs.
+void fillValidCPUArchList(SmallVectorImpl<StringRef> &Values,
+ bool ArchIs32Bit);
+
+/// Get the key feature prioritizing target multiversioning.
+ProcessorFeatures getKeyFeature(CPUKind Kind);
+
+/// Fill in the features that \p CPU supports into \p Features.
+void getFeaturesForCPU(StringRef CPU, SmallVectorImpl<StringRef> &Features);
+
+/// Fill \p Features with the features that are implied to be enabled/disabled
+/// by the provided \p Feature.
+void getImpliedFeatures(StringRef Feature, bool Enabled,
+ SmallVectorImpl<StringRef> &Features);
+
+} // namespace X86
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/YAMLParser.h b/contrib/llvm-project/llvm/include/llvm/Support/YAMLParser.h
index 3570119a3bfd..53009d7ff4aa 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/YAMLParser.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/YAMLParser.h
@@ -139,7 +139,7 @@ public:
void operator delete(void *Ptr, BumpPtrAllocator &Alloc,
size_t Size) noexcept {
- Alloc.Deallocate(Ptr, Size);
+ Alloc.Deallocate(Ptr, Size, 0);
}
void operator delete(void *) noexcept = delete;
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h b/contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h
index 8642069ad540..44e34a4a09b4 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/YAMLTraits.h
@@ -649,24 +649,25 @@ inline bool isBool(StringRef S) {
inline QuotingType needsQuotes(StringRef S) {
if (S.empty())
return QuotingType::Single;
- if (isspace(static_cast<unsigned char>(S.front())) ||
- isspace(static_cast<unsigned char>(S.back())))
- return QuotingType::Single;
+
+ QuotingType MaxQuotingNeeded = QuotingType::None;
+ if (isSpace(static_cast<unsigned char>(S.front())) ||
+ isSpace(static_cast<unsigned char>(S.back())))
+ MaxQuotingNeeded = QuotingType::Single;
if (isNull(S))
- return QuotingType::Single;
+ MaxQuotingNeeded = QuotingType::Single;
if (isBool(S))
- return QuotingType::Single;
+ MaxQuotingNeeded = QuotingType::Single;
if (isNumeric(S))
- return QuotingType::Single;
+ MaxQuotingNeeded = QuotingType::Single;
// 7.3.3 Plain Style
// Plain scalars must not begin with most indicators, as this would cause
// ambiguity with other YAML constructs.
static constexpr char Indicators[] = R"(-?:\,[]{}#&*!|>'"%@`)";
if (S.find_first_of(Indicators) == 0)
- return QuotingType::Single;
+ MaxQuotingNeeded = QuotingType::Single;
- QuotingType MaxQuotingNeeded = QuotingType::None;
for (unsigned char C : S) {
// Alphanum is safe.
if (isAlnum(C))
@@ -684,11 +685,11 @@ inline QuotingType needsQuotes(StringRef S) {
case 0x9:
continue;
// LF(0xA) and CR(0xD) may delimit values and so require at least single
- // quotes.
+ // quotes. LLVM YAML parser cannot handle single quoted multiline so use
+ // double quoting to produce valid YAML.
case 0xA:
case 0xD:
- MaxQuotingNeeded = QuotingType::Single;
- continue;
+ return QuotingType::Double;
// DEL (0x7F) are excluded from the allowed character range.
case 0x7F:
return QuotingType::Double;
@@ -868,7 +869,7 @@ public:
}
template <typename T, typename Context>
- typename std::enable_if<has_SequenceTraits<T>::value, void>::type
+ std::enable_if_t<has_SequenceTraits<T>::value, void>
mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
// omit key/value instead of outputting empty sequence
if (this->canElideEmptySequence() && !(Val.begin() != Val.end()))
@@ -883,7 +884,7 @@ public:
}
template <typename T, typename Context>
- typename std::enable_if<!has_SequenceTraits<T>::value, void>::type
+ std::enable_if_t<!has_SequenceTraits<T>::value, void>
mapOptionalWithContext(const char *Key, T &Val, Context &Ctx) {
this->processKey(Key, Val, false, Ctx);
}
@@ -965,7 +966,7 @@ template <typename T> void doMapping(IO &io, T &Val, EmptyContext &Ctx) {
} // end namespace detail
template <typename T>
-typename std::enable_if<has_ScalarEnumerationTraits<T>::value, void>::type
+std::enable_if_t<has_ScalarEnumerationTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
io.beginEnumScalar();
ScalarEnumerationTraits<T>::enumeration(io, Val);
@@ -973,7 +974,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<has_ScalarBitSetTraits<T>::value, void>::type
+std::enable_if_t<has_ScalarBitSetTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
bool DoClear;
if ( io.beginBitSetScalar(DoClear) ) {
@@ -985,8 +986,8 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<has_ScalarTraits<T>::value, void>::type
-yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
+std::enable_if_t<has_ScalarTraits<T>::value, void> yamlize(IO &io, T &Val, bool,
+ EmptyContext &Ctx) {
if ( io.outputting() ) {
std::string Storage;
raw_string_ostream Buffer(Storage);
@@ -1005,7 +1006,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<has_BlockScalarTraits<T>::value, void>::type
+std::enable_if_t<has_BlockScalarTraits<T>::value, void>
yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
if (YamlIO.outputting()) {
std::string Storage;
@@ -1024,7 +1025,7 @@ yamlize(IO &YamlIO, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<has_TaggedScalarTraits<T>::value, void>::type
+std::enable_if_t<has_TaggedScalarTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
if (io.outputting()) {
std::string ScalarStorage, TagStorage;
@@ -1049,7 +1050,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T, typename Context>
-typename std::enable_if<validatedMappingTraits<T, Context>::value, void>::type
+std::enable_if_t<validatedMappingTraits<T, Context>::value, void>
yamlize(IO &io, T &Val, bool, Context &Ctx) {
if (has_FlowTraits<MappingTraits<T>>::value)
io.beginFlowMapping();
@@ -1075,7 +1076,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
}
template <typename T, typename Context>
-typename std::enable_if<unvalidatedMappingTraits<T, Context>::value, void>::type
+std::enable_if_t<unvalidatedMappingTraits<T, Context>::value, void>
yamlize(IO &io, T &Val, bool, Context &Ctx) {
if (has_FlowTraits<MappingTraits<T>>::value) {
io.beginFlowMapping();
@@ -1089,7 +1090,7 @@ yamlize(IO &io, T &Val, bool, Context &Ctx) {
}
template <typename T>
-typename std::enable_if<has_CustomMappingTraits<T>::value, void>::type
+std::enable_if_t<has_CustomMappingTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
if ( io.outputting() ) {
io.beginMapping();
@@ -1104,7 +1105,7 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<has_PolymorphicTraits<T>::value, void>::type
+std::enable_if_t<has_PolymorphicTraits<T>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
switch (io.outputting() ? PolymorphicTraits<T>::getKind(Val)
: io.getNodeKind()) {
@@ -1118,13 +1119,13 @@ yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
}
template <typename T>
-typename std::enable_if<missingTraits<T, EmptyContext>::value, void>::type
+std::enable_if_t<missingTraits<T, EmptyContext>::value, void>
yamlize(IO &io, T &Val, bool, EmptyContext &Ctx) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
}
template <typename T, typename Context>
-typename std::enable_if<has_SequenceTraits<T>::value, void>::type
+std::enable_if_t<has_SequenceTraits<T>::value, void>
yamlize(IO &io, T &Seq, bool, Context &Ctx) {
if ( has_FlowTraits< SequenceTraits<T>>::value ) {
unsigned incnt = io.beginFlowSequence();
@@ -1247,10 +1248,9 @@ struct ScalarTraits<double> {
// type. This way endian aware types are supported whenever the traits are
// defined for the underlying type.
template <typename value_type, support::endianness endian, size_t alignment>
-struct ScalarTraits<
- support::detail::packed_endian_specific_integral<value_type, endian,
- alignment>,
- typename std::enable_if<has_ScalarTraits<value_type>::value>::type> {
+struct ScalarTraits<support::detail::packed_endian_specific_integral<
+ value_type, endian, alignment>,
+ std::enable_if_t<has_ScalarTraits<value_type>::value>> {
using endian_type =
support::detail::packed_endian_specific_integral<value_type, endian,
alignment>;
@@ -1275,8 +1275,7 @@ template <typename value_type, support::endianness endian, size_t alignment>
struct ScalarEnumerationTraits<
support::detail::packed_endian_specific_integral<value_type, endian,
alignment>,
- typename std::enable_if<
- has_ScalarEnumerationTraits<value_type>::value>::type> {
+ std::enable_if_t<has_ScalarEnumerationTraits<value_type>::value>> {
using endian_type =
support::detail::packed_endian_specific_integral<value_type, endian,
alignment>;
@@ -1292,7 +1291,7 @@ template <typename value_type, support::endianness endian, size_t alignment>
struct ScalarBitSetTraits<
support::detail::packed_endian_specific_integral<value_type, endian,
alignment>,
- typename std::enable_if<has_ScalarBitSetTraits<value_type>::value>::type> {
+ std::enable_if_t<has_ScalarBitSetTraits<value_type>::value>> {
using endian_type =
support::detail::packed_endian_specific_integral<value_type, endian,
alignment>;
@@ -1688,8 +1687,7 @@ struct ScalarTraits<Hex64> {
// Define non-member operator>> so that Input can stream in a document list.
template <typename T>
-inline
-typename std::enable_if<has_DocumentListTraits<T>::value, Input &>::type
+inline std::enable_if_t<has_DocumentListTraits<T>::value, Input &>
operator>>(Input &yin, T &docList) {
int i = 0;
EmptyContext Ctx;
@@ -1705,8 +1703,7 @@ operator>>(Input &yin, T &docList) {
// Define non-member operator>> so that Input can stream in a map as a document.
template <typename T>
-inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
- Input &>::type
+inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Input &>
operator>>(Input &yin, T &docMap) {
EmptyContext Ctx;
yin.setCurrentDocument();
@@ -1717,8 +1714,7 @@ operator>>(Input &yin, T &docMap) {
// Define non-member operator>> so that Input can stream in a sequence as
// a document.
template <typename T>
-inline
-typename std::enable_if<has_SequenceTraits<T>::value, Input &>::type
+inline std::enable_if_t<has_SequenceTraits<T>::value, Input &>
operator>>(Input &yin, T &docSeq) {
EmptyContext Ctx;
if (yin.setCurrentDocument())
@@ -1728,8 +1724,7 @@ operator>>(Input &yin, T &docSeq) {
// Define non-member operator>> so that Input can stream in a block scalar.
template <typename T>
-inline
-typename std::enable_if<has_BlockScalarTraits<T>::value, Input &>::type
+inline std::enable_if_t<has_BlockScalarTraits<T>::value, Input &>
operator>>(Input &In, T &Val) {
EmptyContext Ctx;
if (In.setCurrentDocument())
@@ -1739,8 +1734,7 @@ operator>>(Input &In, T &Val) {
// Define non-member operator>> so that Input can stream in a string map.
template <typename T>
-inline
-typename std::enable_if<has_CustomMappingTraits<T>::value, Input &>::type
+inline std::enable_if_t<has_CustomMappingTraits<T>::value, Input &>
operator>>(Input &In, T &Val) {
EmptyContext Ctx;
if (In.setCurrentDocument())
@@ -1750,7 +1744,7 @@ operator>>(Input &In, T &Val) {
// Define non-member operator>> so that Input can stream in a polymorphic type.
template <typename T>
-inline typename std::enable_if<has_PolymorphicTraits<T>::value, Input &>::type
+inline std::enable_if_t<has_PolymorphicTraits<T>::value, Input &>
operator>>(Input &In, T &Val) {
EmptyContext Ctx;
if (In.setCurrentDocument())
@@ -1760,8 +1754,7 @@ operator>>(Input &In, T &Val) {
// Provide better error message about types missing a trait specialization
template <typename T>
-inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
- Input &>::type
+inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Input &>
operator>>(Input &yin, T &docSeq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yin;
@@ -1769,8 +1762,7 @@ operator>>(Input &yin, T &docSeq) {
// Define non-member operator<< so that Output can stream out document list.
template <typename T>
-inline
-typename std::enable_if<has_DocumentListTraits<T>::value, Output &>::type
+inline std::enable_if_t<has_DocumentListTraits<T>::value, Output &>
operator<<(Output &yout, T &docList) {
EmptyContext Ctx;
yout.beginDocuments();
@@ -1788,8 +1780,7 @@ operator<<(Output &yout, T &docList) {
// Define non-member operator<< so that Output can stream out a map.
template <typename T>
-inline typename std::enable_if<has_MappingTraits<T, EmptyContext>::value,
- Output &>::type
+inline std::enable_if_t<has_MappingTraits<T, EmptyContext>::value, Output &>
operator<<(Output &yout, T &map) {
EmptyContext Ctx;
yout.beginDocuments();
@@ -1803,8 +1794,7 @@ operator<<(Output &yout, T &map) {
// Define non-member operator<< so that Output can stream out a sequence.
template <typename T>
-inline
-typename std::enable_if<has_SequenceTraits<T>::value, Output &>::type
+inline std::enable_if_t<has_SequenceTraits<T>::value, Output &>
operator<<(Output &yout, T &seq) {
EmptyContext Ctx;
yout.beginDocuments();
@@ -1818,8 +1808,7 @@ operator<<(Output &yout, T &seq) {
// Define non-member operator<< so that Output can stream out a block scalar.
template <typename T>
-inline
-typename std::enable_if<has_BlockScalarTraits<T>::value, Output &>::type
+inline std::enable_if_t<has_BlockScalarTraits<T>::value, Output &>
operator<<(Output &Out, T &Val) {
EmptyContext Ctx;
Out.beginDocuments();
@@ -1833,8 +1822,7 @@ operator<<(Output &Out, T &Val) {
// Define non-member operator<< so that Output can stream out a string map.
template <typename T>
-inline
-typename std::enable_if<has_CustomMappingTraits<T>::value, Output &>::type
+inline std::enable_if_t<has_CustomMappingTraits<T>::value, Output &>
operator<<(Output &Out, T &Val) {
EmptyContext Ctx;
Out.beginDocuments();
@@ -1849,7 +1837,7 @@ operator<<(Output &Out, T &Val) {
// Define non-member operator<< so that Output can stream out a polymorphic
// type.
template <typename T>
-inline typename std::enable_if<has_PolymorphicTraits<T>::value, Output &>::type
+inline std::enable_if_t<has_PolymorphicTraits<T>::value, Output &>
operator<<(Output &Out, T &Val) {
EmptyContext Ctx;
Out.beginDocuments();
@@ -1866,8 +1854,7 @@ operator<<(Output &Out, T &Val) {
// Provide better error message about types missing a trait specialization
template <typename T>
-inline typename std::enable_if<missingTraits<T, EmptyContext>::value,
- Output &>::type
+inline std::enable_if_t<missingTraits<T, EmptyContext>::value, Output &>
operator<<(Output &yout, T &seq) {
char missing_yaml_trait_for_type[sizeof(MissingTrait<T>)];
return yout;
@@ -1898,25 +1885,25 @@ template <bool> struct CheckIsBool { static const bool value = true; };
// If T has SequenceElementTraits, then vector<T> and SmallVector<T, N> have
// SequenceTraits that do the obvious thing.
template <typename T>
-struct SequenceTraits<std::vector<T>,
- typename std::enable_if<CheckIsBool<
- SequenceElementTraits<T>::flow>::value>::type>
+struct SequenceTraits<
+ std::vector<T>,
+ std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
: SequenceTraitsImpl<std::vector<T>, SequenceElementTraits<T>::flow> {};
template <typename T, unsigned N>
-struct SequenceTraits<SmallVector<T, N>,
- typename std::enable_if<CheckIsBool<
- SequenceElementTraits<T>::flow>::value>::type>
+struct SequenceTraits<
+ SmallVector<T, N>,
+ std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
: SequenceTraitsImpl<SmallVector<T, N>, SequenceElementTraits<T>::flow> {};
template <typename T>
-struct SequenceTraits<SmallVectorImpl<T>,
- typename std::enable_if<CheckIsBool<
- SequenceElementTraits<T>::flow>::value>::type>
+struct SequenceTraits<
+ SmallVectorImpl<T>,
+ std::enable_if_t<CheckIsBool<SequenceElementTraits<T>::flow>::value>>
: SequenceTraitsImpl<SmallVectorImpl<T>, SequenceElementTraits<T>::flow> {};
// Sequences of fundamental types use flow formatting.
template <typename T>
-struct SequenceElementTraits<
- T, typename std::enable_if<std::is_fundamental<T>::value>::type> {
+struct SequenceElementTraits<T,
+ std::enable_if_t<std::is_fundamental<T>::value>> {
static const bool flow = true;
};
@@ -1936,7 +1923,7 @@ template <typename T> struct StdMapStringCustomMappingTraitsImpl {
using map_type = std::map<std::string, T>;
static void inputOne(IO &io, StringRef key, map_type &v) {
- io.mapRequired(key.str().c_str(), v[key]);
+ io.mapRequired(key.str().c_str(), v[std::string(key)]);
}
static void output(IO &io, map_type &v) {
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h b/contrib/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h
index a72acd4fe002..d2f01ea6a7f2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/circular_raw_ostream.h
@@ -27,12 +27,12 @@ namespace llvm {
/// stream and is responsible for cleanup, memory management
/// issues, etc.
///
- static const bool TAKE_OWNERSHIP = true;
+ static constexpr bool TAKE_OWNERSHIP = true;
/// REFERENCE_ONLY - Tell this stream it should not manage the
/// held stream.
///
- static const bool REFERENCE_ONLY = false;
+ static constexpr bool REFERENCE_ONLY = false;
private:
/// TheStream - The real stream we output to. We set it to be
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h b/contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h
index c8770c337588..8d289f7c765f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/raw_ostream.h
@@ -64,6 +64,11 @@ private:
/// for a \see write_impl() call to handle the data which has been put into
/// this buffer.
char *OutBufStart, *OutBufEnd, *OutBufCur;
+ bool ColorEnabled = false;
+
+ /// Optional stream this stream is tied to. If this stream is written to, the
+ /// tied-to stream will be flushed first.
+ raw_ostream *TiedStream = nullptr;
enum class BufferKind {
Unbuffered = 0,
@@ -86,16 +91,16 @@ public:
RESET,
};
- static const Colors BLACK = Colors::BLACK;
- static const Colors RED = Colors::RED;
- static const Colors GREEN = Colors::GREEN;
- static const Colors YELLOW = Colors::YELLOW;
- static const Colors BLUE = Colors::BLUE;
- static const Colors MAGENTA = Colors::MAGENTA;
- static const Colors CYAN = Colors::CYAN;
- static const Colors WHITE = Colors::WHITE;
- static const Colors SAVEDCOLOR = Colors::SAVEDCOLOR;
- static const Colors RESET = Colors::RESET;
+ static constexpr Colors BLACK = Colors::BLACK;
+ static constexpr Colors RED = Colors::RED;
+ static constexpr Colors GREEN = Colors::GREEN;
+ static constexpr Colors YELLOW = Colors::YELLOW;
+ static constexpr Colors BLUE = Colors::BLUE;
+ static constexpr Colors MAGENTA = Colors::MAGENTA;
+ static constexpr Colors CYAN = Colors::CYAN;
+ static constexpr Colors WHITE = Colors::WHITE;
+ static constexpr Colors SAVEDCOLOR = Colors::SAVEDCOLOR;
+ static constexpr Colors RESET = Colors::RESET;
explicit raw_ostream(bool unbuffered = false)
: BufferMode(unbuffered ? BufferKind::Unbuffered
@@ -270,21 +275,15 @@ public:
/// @param Bold bold/brighter text, default false
/// @param BG if true change the background, default: change foreground
/// @returns itself so it can be used within << invocations
- virtual raw_ostream &changeColor(enum Colors Color,
- bool Bold = false,
- bool BG = false) {
- (void)Color;
- (void)Bold;
- (void)BG;
- return *this;
- }
+ virtual raw_ostream &changeColor(enum Colors Color, bool Bold = false,
+ bool BG = false);
/// Resets the colors to terminal defaults. Call this when you are done
/// outputting colored text, or before program exit.
- virtual raw_ostream &resetColor() { return *this; }
+ virtual raw_ostream &resetColor();
/// Reverses the foreground and background colors.
- virtual raw_ostream &reverseColor() { return *this; }
+ virtual raw_ostream &reverseColor();
/// This function determines if this stream is connected to a "tty" or
/// "console" window. That is, the output would be displayed to the user
@@ -292,11 +291,16 @@ public:
virtual bool is_displayed() const { return false; }
/// This function determines if this stream is displayed and supports colors.
+ /// The result is unaffected by calls to enable_color().
virtual bool has_colors() const { return is_displayed(); }
- // Enable or disable colors. Once disable_colors() is called,
- // changeColor() has no effect until enable_colors() is called.
- virtual void enable_colors(bool /*enable*/) {}
+ // Enable or disable colors. Once enable_colors(false) is called,
+ // changeColor() has no effect until enable_colors(true) is called.
+ virtual void enable_colors(bool enable) { ColorEnabled = enable; }
+
+ /// Tie this stream to the specified stream. Replaces any existing tied-to
+ /// stream. Specifying a nullptr unties the stream.
+ void tie(raw_ostream *TieTo) { TiedStream = TieTo; }
//===--------------------------------------------------------------------===//
// Subclass Interface
@@ -352,15 +356,22 @@ private:
/// unused bytes in the buffer.
void copy_to_buffer(const char *Ptr, size_t Size);
+ /// Compute whether colors should be used and do the necessary work such as
+ /// flushing. The result is affected by calls to enable_color().
+ bool prepare_colors();
+
+ /// Flush the tied-to stream (if present) and then write the required data.
+ void flush_tied_then_write(const char *Ptr, size_t Size);
+
virtual void anchor();
};
/// Call the appropriate insertion operator, given an rvalue reference to a
/// raw_ostream object and return a stream of the same type as the argument.
template <typename OStream, typename T>
-typename std::enable_if<!std::is_reference<OStream>::value &&
- std::is_base_of<raw_ostream, OStream>::value,
- OStream &&>::type
+std::enable_if_t<!std::is_reference<OStream>::value &&
+ std::is_base_of<raw_ostream, OStream>::value,
+ OStream &&>
operator<<(OStream &&OS, const T &Value) {
OS << Value;
return std::move(OS);
@@ -398,7 +409,6 @@ class raw_fd_ostream : public raw_pwrite_stream {
int FD;
bool ShouldClose;
bool SupportsSeeking = false;
- bool ColorEnabled = true;
#ifdef _WIN32
/// True if this fd refers to a Windows console device. Mintty and other
@@ -464,18 +474,10 @@ public:
/// to the offset specified from the beginning of the file.
uint64_t seek(uint64_t off);
- raw_ostream &changeColor(enum Colors colors, bool bold=false,
- bool bg=false) override;
- raw_ostream &resetColor() override;
-
- raw_ostream &reverseColor() override;
-
bool is_displayed() const override;
bool has_colors() const override;
- void enable_colors(bool enable) override { ColorEnabled = enable; }
-
std::error_code error() const { return EC; }
/// Return the value of the flag in this raw_fd_ostream indicating whether an
@@ -496,13 +498,16 @@ public:
void clear_error() { EC = std::error_code(); }
};
-/// This returns a reference to a raw_ostream for standard output. Use it like:
-/// outs() << "foo" << "bar";
-raw_ostream &outs();
+/// This returns a reference to a raw_fd_ostream for standard output. Use it
+/// like: outs() << "foo" << "bar";
+raw_fd_ostream &outs();
-/// This returns a reference to a raw_ostream for standard error. Use it like:
-/// errs() << "foo" << "bar";
-raw_ostream &errs();
+/// This returns a reference to a raw_ostream for standard error.
+/// Use it like: errs() << "foo" << "bar";
+/// By default, the stream is tied to stdout to ensure stdout is flushed before
+/// stderr is written, to ensure the error messages are written in their
+/// expected place.
+raw_fd_ostream &errs();
/// This returns a reference to a raw_ostream which simply discards output.
raw_ostream &nulls();
@@ -524,7 +529,9 @@ class raw_string_ostream : public raw_ostream {
uint64_t current_pos() const override { return OS.size(); }
public:
- explicit raw_string_ostream(std::string &O) : OS(O) {}
+ explicit raw_string_ostream(std::string &O) : OS(O) {
+ SetUnbuffered();
+ }
~raw_string_ostream() override;
/// Flushes the stream contents to the target string and returns the string's
@@ -565,7 +572,7 @@ public:
void flush() = delete;
/// Return a StringRef for the vector contents.
- StringRef str() { return StringRef(OS.data(), OS.size()); }
+ StringRef str() const { return StringRef(OS.data(), OS.size()); }
};
/// A raw_ostream that discards all output.
diff --git a/contrib/llvm-project/llvm/include/llvm/Support/type_traits.h b/contrib/llvm-project/llvm/include/llvm/Support/type_traits.h
index b7d48e8e1ade..7b7d5d991f3f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Support/type_traits.h
+++ b/contrib/llvm-project/llvm/include/llvm/Support/type_traits.h
@@ -28,7 +28,7 @@ namespace llvm {
/// Also note that enum classes aren't implicitly convertible to integral types,
/// the value may therefore need to be explicitly converted before being used.
template <typename T> class is_integral_or_enum {
- using UnderlyingT = typename std::remove_reference<T>::type;
+ using UnderlyingT = std::remove_reference_t<T>;
public:
static const bool value =
@@ -45,7 +45,7 @@ struct add_lvalue_reference_if_not_pointer { using type = T &; };
template <typename T>
struct add_lvalue_reference_if_not_pointer<
- T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+ T, std::enable_if_t<std::is_pointer<T>::value>> {
using type = T;
};
@@ -55,9 +55,8 @@ template<typename T, typename Enable = void>
struct add_const_past_pointer { using type = const T; };
template <typename T>
-struct add_const_past_pointer<
- T, typename std::enable_if<std::is_pointer<T>::value>::type> {
- using type = const typename std::remove_pointer<T>::type *;
+struct add_const_past_pointer<T, std::enable_if_t<std::is_pointer<T>::value>> {
+ using type = const std::remove_pointer_t<T> *;
};
template <typename T, typename Enable = void>
@@ -65,8 +64,8 @@ struct const_pointer_or_const_ref {
using type = const T &;
};
template <typename T>
-struct const_pointer_or_const_ref<
- T, typename std::enable_if<std::is_pointer<T>::value>::type> {
+struct const_pointer_or_const_ref<T,
+ std::enable_if_t<std::is_pointer<T>::value>> {
using type = typename add_const_past_pointer<T>::type;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/TableGen/Main.h b/contrib/llvm-project/llvm/include/llvm/TableGen/Main.h
index e464cd4d4fb5..4e05da36168f 100644
--- a/contrib/llvm-project/llvm/include/llvm/TableGen/Main.h
+++ b/contrib/llvm-project/llvm/include/llvm/TableGen/Main.h
@@ -22,7 +22,7 @@ class RecordKeeper;
/// Returns true on error, false otherwise.
using TableGenMainFn = bool (raw_ostream &OS, RecordKeeper &Records);
-int TableGenMain(char *argv0, TableGenMainFn *MainFn);
+int TableGenMain(const char *argv0, TableGenMainFn *MainFn);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/TableGen/Record.h b/contrib/llvm-project/llvm/include/llvm/TableGen/Record.h
index a553ec99aaa4..a082fe5d74a1 100644
--- a/contrib/llvm-project/llvm/include/llvm/TableGen/Record.h
+++ b/contrib/llvm-project/llvm/include/llvm/TableGen/Record.h
@@ -614,7 +614,9 @@ public:
bool isConcrete() const override { return true; }
std::string getAsString() const override { return "\"" + Value.str() + "\""; }
- std::string getAsUnquotedString() const override { return Value; }
+ std::string getAsUnquotedString() const override {
+ return std::string(Value);
+ }
Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off string");
@@ -649,7 +651,9 @@ public:
return "[{" + Value.str() + "}]";
}
- std::string getAsUnquotedString() const override { return Value; }
+ std::string getAsUnquotedString() const override {
+ return std::string(Value);
+ }
Init *getBit(unsigned Bit) const override {
llvm_unreachable("Illegal bit reference off string");
@@ -1098,7 +1102,7 @@ public:
Init *getBit(unsigned Bit) const override;
- std::string getAsString() const override { return getName(); }
+ std::string getAsString() const override { return std::string(getName()); }
};
/// Opcode{0} - Represent access to one bit of a variable or field.
@@ -1291,6 +1295,7 @@ public:
Init *resolveReferences(Resolver &R) const override;
Init *Fold(Record *CurRec) const;
+ bool isConcrete() const override;
std::string getAsString() const override {
return Rec->getAsString() + "." + FieldName->getValue().str();
}
@@ -1599,11 +1604,6 @@ public:
/// recursion / infinite loops.
void resolveReferences(Resolver &R, const RecordVal *SkipVal = nullptr);
- /// If anything in this record refers to RV, replace the
- /// reference to RV with the RHS of RV. If RV is null, we resolve all
- /// possible references.
- void resolveReferencesTo(const RecordVal *RV);
-
RecordKeeper &getRecords() const {
return TrackedRecords;
}
@@ -1722,21 +1722,21 @@ public:
}
void addClass(std::unique_ptr<Record> R) {
- bool Ins = Classes.insert(std::make_pair(R->getName(),
+ bool Ins = Classes.insert(std::make_pair(std::string(R->getName()),
std::move(R))).second;
(void)Ins;
assert(Ins && "Class already exists");
}
void addDef(std::unique_ptr<Record> R) {
- bool Ins = Defs.insert(std::make_pair(R->getName(),
+ bool Ins = Defs.insert(std::make_pair(std::string(R->getName()),
std::move(R))).second;
(void)Ins;
assert(Ins && "Record already exists");
}
void addExtraGlobal(StringRef Name, Init *I) {
- bool Ins = ExtraGlobals.insert(std::make_pair(Name, I)).second;
+ bool Ins = ExtraGlobals.insert(std::make_pair(std::string(Name), I)).second;
(void)Ins;
assert(!getDef(Name));
assert(Ins && "Global already exists");
diff --git a/contrib/llvm-project/llvm/include/llvm/TableGen/StringToOffsetTable.h b/contrib/llvm-project/llvm/include/llvm/TableGen/StringToOffsetTable.h
index 76ce51893907..7fcf20abed61 100644
--- a/contrib/llvm-project/llvm/include/llvm/TableGen/StringToOffsetTable.h
+++ b/contrib/llvm-project/llvm/include/llvm/TableGen/StringToOffsetTable.h
@@ -45,7 +45,7 @@ public:
// Escape the string.
SmallString<256> Str;
raw_svector_ostream(Str).write_escaped(AggregateString);
- AggregateString = Str.str();
+ AggregateString = std::string(Str.str());
O << " \"";
unsigned CharsPrinted = 0;
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/GenericOpcodes.td b/contrib/llvm-project/llvm/include/llvm/Target/GenericOpcodes.td
index 0ee9c3916c10..3d8262b2404f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/GenericOpcodes.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/GenericOpcodes.td
@@ -19,6 +19,22 @@ class GenericInstruction : StandardPseudoInstruction {
let isPreISelOpcode = 1;
}
+// Provide a variant of an instruction with the same operands, but
+// different instruction flags. This is intended to provide a
+// convenient way to define strict floating point variants of ordinary
+// floating point instructions.
+class ConstrainedIntruction<GenericInstruction baseInst> :
+ GenericInstruction {
+ let OutOperandList = baseInst.OutOperandList;
+ let InOperandList = baseInst.InOperandList;
+ let isCommutable = baseInst.isCommutable;
+
+ // TODO: Do we need a better way to mark reads from FP mode than
+ // hasSideEffects?
+ let hasSideEffects = 1;
+ let mayRaiseFPException = 1;
+}
+
// Extend the underlying scalar type of an operation, leaving the high bits
// unspecified.
def G_ANYEXT : GenericInstruction {
@@ -203,6 +219,12 @@ def G_DYN_STACKALLOC : GenericInstruction {
let hasSideEffects = 1;
}
+def G_FREEZE : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src);
+ let hasSideEffects = 0;
+}
+
//------------------------------------------------------------------------------
// Binary ops.
//------------------------------------------------------------------------------
@@ -308,6 +330,22 @@ def G_ASHR : GenericInstruction {
let hasSideEffects = 0;
}
+/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
+/// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
+def G_FSHL : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
+ let hasSideEffects = 0;
+}
+
+/// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
+/// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
+def G_FSHR : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
+ let hasSideEffects = 0;
+}
+
// Generic integer comparison.
def G_ICMP : GenericInstruction {
let OutOperandList = (outs type0:$dst);
@@ -336,9 +374,11 @@ def G_PTR_ADD : GenericInstruction {
let hasSideEffects = 0;
}
-def G_PTR_MASK : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, unknown:$bits);
+// Generic pointer mask. type1 should be an integer with the same
+// bitwidth as the pointer type.
+def G_PTRMASK : GenericInstruction {
+ let OutOperandList = (outs ptype0:$dst);
+ let InOperandList = (ins ptype0:$src, type1:$bits);
let hasSideEffects = 0;
}
@@ -470,6 +510,42 @@ def G_SMULH : GenericInstruction {
}
//------------------------------------------------------------------------------
+// Saturating ops
+//------------------------------------------------------------------------------
+
+// Generic saturating unsigned addition.
+def G_UADDSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
+// Generic saturating signed addition.
+def G_SADDSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 1;
+}
+
+// Generic saturating unsigned subtraction.
+def G_USUBSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 0;
+}
+
+// Generic saturating signed subtraction.
+def G_SSUBSAT : GenericInstruction {
+ let OutOperandList = (outs type0:$dst);
+ let InOperandList = (ins type0:$src1, type0:$src2);
+ let hasSideEffects = 0;
+ let isCommutable = 0;
+}
+
+//------------------------------------------------------------------------------
// Floating Point Unary Ops.
//------------------------------------------------------------------------------
@@ -898,7 +974,7 @@ def G_FENCE : GenericInstruction {
// register banks have been selected.
def G_EXTRACT : GenericInstruction {
let OutOperandList = (outs type0:$res);
- let InOperandList = (ins type1:$src, unknown:$offset);
+ let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
let hasSideEffects = 0;
}
@@ -917,7 +993,7 @@ def G_UNMERGE_VALUES : GenericInstruction {
// Insert a smaller register into a larger one at the specified bit-index.
def G_INSERT : GenericInstruction {
let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$op, unknown:$offset);
+ let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
let hasSideEffects = 0;
}
@@ -960,6 +1036,10 @@ def G_INTRINSIC : GenericInstruction {
let OutOperandList = (outs);
let InOperandList = (ins unknown:$intrin, variable_ops);
let hasSideEffects = 0;
+
+ // Conservatively assume this is convergent. If there turnes out to
+ // be a need, there should be separate convergent intrinsic opcode.s
+ let isConvergent = 1;
}
// Intrinsic with side effects.
@@ -969,6 +1049,10 @@ def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
let hasSideEffects = 1;
let mayLoad = 1;
let mayStore = 1;
+
+ // Conservatively assume this is convergent. If there turnes out to
+ // be a need, there should be separate convergent intrinsic opcode.s
+ let isConvergent = 1;
}
//------------------------------------------------------------------------------
@@ -1001,6 +1085,8 @@ def G_BRINDIRECT : GenericInstruction {
let hasSideEffects = 0;
let isBranch = 1;
let isTerminator = 1;
+ let isBarrier = 1;
+ let isIndirectBranch = 1;
}
// Generic branch to jump table entry
@@ -1010,6 +1096,8 @@ def G_BRJT : GenericInstruction {
let hasSideEffects = 0;
let isBranch = 1;
let isTerminator = 1;
+ let isBarrier = 1;
+ let isIndirectBranch = 1;
}
def G_READ_REGISTER : GenericInstruction {
@@ -1060,4 +1148,14 @@ def G_SHUFFLE_VECTOR: GenericInstruction {
let hasSideEffects = 0;
}
-// TODO: Add the other generic opcodes.
+//------------------------------------------------------------------------------
+// Constrained floating point ops
+//------------------------------------------------------------------------------
+
+def G_STRICT_FADD : ConstrainedIntruction<G_FADD>;
+def G_STRICT_FSUB : ConstrainedIntruction<G_FSUB>;
+def G_STRICT_FMUL : ConstrainedIntruction<G_FMUL>;
+def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>;
+def G_STRICT_FREM : ConstrainedIntruction<G_FREM>;
+def G_STRICT_FMA : ConstrainedIntruction<G_FMA>;
+def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>;
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Combine.td b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Combine.td
index 35f7a41e1cbf..1dd3e374b524 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -27,6 +27,11 @@ class GICombineGroup<list<GICombine> rules> : GICombine {
let Rules = rules;
}
+class GICombinerHelperArg<string type, string name> {
+ string Type = type;
+ string Name = name;
+}
+
// Declares a combiner helper class
class GICombinerHelper<string classname, list<GICombine> rules>
: GICombineGroup<rules> {
@@ -35,6 +40,12 @@ class GICombinerHelper<string classname, list<GICombine> rules>
// The name of a run-time compiler option that will be generated to disable
// specific rules within this combiner.
string DisableRuleOption = ?;
+ // The state class to inherit from (if any). The generated helper will inherit
+ // from this class and will forward arguments to its constructors.
+ string StateClass = "";
+ // Any additional arguments that should be appended to the tryCombine*().
+ list<GICombinerHelperArg> AdditionalArguments =
+ [GICombinerHelperArg<"CombinerHelper &", "Helper">];
}
class GICombineRule<dag defs, dag match, dag apply> : GICombine {
/// Defines the external interface of the match rule. This includes:
@@ -106,7 +117,6 @@ def copy_prop : GICombineRule<
(match (COPY $d, $s):$mi,
[{ return Helper.matchCombineCopy(*${mi}); }]),
(apply [{ Helper.applyCombineCopy(*${mi}); }])>;
-def trivial_combines : GICombineGroup<[copy_prop]>;
def extending_loads : GICombineRule<
(defs root:$root, extending_load_matchdata:$matchinfo),
@@ -115,6 +125,12 @@ def extending_loads : GICombineRule<
(apply [{ Helper.applyCombineExtendingLoads(*${root}, ${matchinfo}); }])>;
def combines_for_extload: GICombineGroup<[extending_loads]>;
+def sext_already_extended : GICombineRule<
+ (defs root:$d),
+ (match (wip_match_opcode G_SEXT_INREG):$d,
+ [{ return Helper.matchSextAlreadyExtended(*${d}); }]),
+ (apply [{ Helper.applySextAlreadyExtended(*${d}); }])>;
+
def combine_indexed_load_store : GICombineRule<
(defs root:$root, indexed_load_store_matchdata:$matchinfo),
(match (wip_match_opcode G_LOAD, G_SEXTLOAD, G_ZEXTLOAD, G_STORE):$root,
@@ -136,5 +152,124 @@ def ptr_add_immed_chain : GICombineRule<
[{ return Helper.matchPtrAddImmedChain(*${d}, ${matchinfo}); }]),
(apply [{ Helper.applyPtrAddImmedChain(*${d}, ${matchinfo}); }])>;
+def mul_to_shl_matchdata : GIDefMatchData<"unsigned">;
+def mul_to_shl : GICombineRule<
+ (defs root:$d, mul_to_shl_matchdata:$matchinfo),
+ (match (G_MUL $d, $op1, $op2):$mi,
+ [{ return Helper.matchCombineMulToShl(*${mi}, ${matchinfo}); }]),
+ (apply [{ Helper.applyCombineMulToShl(*${mi}, ${matchinfo}); }])>;
+
+// [us]itofp(undef) = 0, because the result value is bounded.
+def undef_to_fp_zero : GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_UITOFP, G_SITOFP):$root,
+ [{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithFConstant(*${root}, 0.0); }])>;
+
+def undef_to_int_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_AND, G_MUL):$root,
+ [{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${root}, 0); }])>;
+
+def undef_to_negative_one: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_OR):$root,
+ [{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithConstant(*${root}, -1); }])>;
+
+// Instructions where if any source operand is undef, the instruction can be
+// replaced with undef.
+def propagate_undef_any_op: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_ADD, G_FPTOSI, G_FPTOUI, G_SUB, G_XOR):$root,
+ [{ return Helper.matchAnyExplicitUseIsUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+
+// Instructions where if all source operands are undef, the instruction can be
+// replaced with undef.
+def propagate_undef_all_ops: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ [{ return Helper.matchAllExplicitUsesAreUndef(*${root}); }]),
+ (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+
+// Replace a G_SHUFFLE_VECTOR with an undef mask with a G_IMPLICIT_DEF.
+def propagate_undef_shuffle_mask: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
+ [{ return Helper.matchUndefShuffleVectorMask(*${root}); }]),
+ (apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
+
+// Fold (cond ? x : x) -> x
+def select_same_val: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SELECT):$root,
+ [{ return Helper.matchSelectSameVal(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+>;
+
+// Fold x op 0 -> x
+def right_identity_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SUB, G_ADD, G_OR, G_XOR, G_SHL, G_ASHR, G_LSHR):$root,
+ [{ return Helper.matchConstantOp(${root}->getOperand(2), 0); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
+// Fold (x op x) - > x
+def binop_same_val: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_AND, G_OR):$root,
+ [{ return Helper.matchBinOpSameVal(*${root}); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
+// Fold (0 op x) - > 0
+def binop_left_to_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_SDIV, G_UDIV, G_SREM, G_UREM):$root,
+ [{ return Helper.matchOperandIsZero(*${root}, 1); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 1); }])
+>;
+
+// Fold (x op 0) - > 0
+def binop_right_to_zero: GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_MUL):$root,
+ [{ return Helper.matchOperandIsZero(*${root}, 2); }]),
+ (apply [{ return Helper.replaceSingleDefInstWithOperand(*${root}, 2); }])
+>;
+
+// Erase stores of undef values.
+def erase_undef_store : GICombineRule<
+ (defs root:$root),
+ (match (wip_match_opcode G_STORE):$root,
+ [{ return Helper.matchUndefStore(*${root}); }]),
+ (apply [{ return Helper.eraseInst(*${root}); }])
+>;
+
+def simplify_add_to_sub_matchinfo: GIDefMatchData<"std::tuple<Register, Register>">;
+def simplify_add_to_sub: GICombineRule <
+ (defs root:$root, simplify_add_to_sub_matchinfo:$info),
+ (match (wip_match_opcode G_ADD):$root,
+ [{ return Helper.matchSimplifyAddToSub(*${root}, ${info}); }]),
+ (apply [{ return Helper.applySimplifyAddToSub(*${root}, ${info});}])
+>;
+
+// FIXME: These should use the custom predicate feature once it lands.
+def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
+ undef_to_negative_one,
+ propagate_undef_any_op,
+ propagate_undef_all_ops,
+ propagate_undef_shuffle_mask,
+ erase_undef_store]>;
+
+def identity_combines : GICombineGroup<[select_same_val, right_identity_zero,
+ binop_same_val, binop_left_to_zero,
+ binop_right_to_zero]>;
+
+def trivial_combines : GICombineGroup<[copy_prop, mul_to_shl]>;
def all_combines : GICombineGroup<[trivial_combines, ptr_add_immed_chain,
- combines_for_extload, combine_indexed_load_store]>;
+ combines_for_extload, combine_indexed_load_store, undef_combines,
+ identity_combines, simplify_add_to_sub]>;
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index 2129588d4aed..150834e65b2d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -67,6 +67,10 @@ def : GINodeEquiv<G_XOR, xor>;
def : GINodeEquiv<G_SHL, shl>;
def : GINodeEquiv<G_LSHR, srl>;
def : GINodeEquiv<G_ASHR, sra>;
+def : GINodeEquiv<G_SADDSAT, saddsat>;
+def : GINodeEquiv<G_UADDSAT, uaddsat>;
+def : GINodeEquiv<G_SSUBSAT, ssubsat>;
+def : GINodeEquiv<G_USUBSAT, usubsat>;
def : GINodeEquiv<G_SELECT, select>;
def : GINodeEquiv<G_FNEG, fneg>;
def : GINodeEquiv<G_FPEXT, fpextend>;
@@ -93,6 +97,8 @@ def : GINodeEquiv<G_INTRINSIC_W_SIDE_EFFECTS, intrinsic_w_chain>;
def : GINodeEquiv<G_BR, br>;
def : GINodeEquiv<G_BSWAP, bswap>;
def : GINodeEquiv<G_BITREVERSE, bitreverse>;
+def : GINodeEquiv<G_FSHL, fshl>;
+def : GINodeEquiv<G_FSHR, fshr>;
def : GINodeEquiv<G_CTLZ, ctlz>;
def : GINodeEquiv<G_CTTZ, cttz>;
def : GINodeEquiv<G_CTLZ_ZERO_UNDEF, ctlz_zero_undef>;
@@ -122,6 +128,14 @@ def : GINodeEquiv<G_FMINNUM_IEEE, fminnum_ieee>;
def : GINodeEquiv<G_FMAXNUM_IEEE, fmaxnum_ieee>;
def : GINodeEquiv<G_READCYCLECOUNTER, readcyclecounter>;
+def : GINodeEquiv<G_STRICT_FADD, strict_fadd>;
+def : GINodeEquiv<G_STRICT_FSUB, strict_fsub>;
+def : GINodeEquiv<G_STRICT_FMUL, strict_fmul>;
+def : GINodeEquiv<G_STRICT_FDIV, strict_fdiv>;
+def : GINodeEquiv<G_STRICT_FREM, strict_frem>;
+def : GINodeEquiv<G_STRICT_FMA, strict_fma>;
+def : GINodeEquiv<G_STRICT_FSQRT, strict_fsqrt>;
+
// Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some
// complications that tablegen must take care of. For example, Predicates such
// as isSignExtLoad require that this is not a perfect 1:1 mapping since a
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Target.td b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Target.td
index 8e868c4c207b..135d4a5e0dd0 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Target.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/GlobalISel/Target.td
@@ -38,11 +38,10 @@ class GIComplexOperandMatcher<LLT type, string matcherfn> {
// The function that determines whether the operand matches. It should be of
// the form:
- // bool select(const MatchOperand &Root, MatchOperand &Result1)
- // and should have the same number of ResultX arguments as the number of
- // result operands. It must return true on successful match and false
- // otherwise. If it returns true, then all the ResultX arguments must be
- // overwritten.
+ // ComplexRendererFn select(MachineOperand &Root) const;
+ // where Root is the root of the match. The function should return nullptr
+ // on match failure, or a ComplexRendererFn that renders the operand in case
+ // of a successful match.
string MatcherFn = matcherfn;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/Target.td b/contrib/llvm-project/llvm/include/llvm/Target/Target.td
index cdc9b640e74e..aab5376db453 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/Target.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/Target.td
@@ -166,8 +166,9 @@ class Register<string n, list<string> altNames = []> {
// CostPerUse - Additional cost of instructions using this register compared
// to other registers in its class. The register allocator will try to
// minimize the number of instructions using a register with a CostPerUse.
- // This is used by the x86-64 and ARM Thumb targets where some registers
- // require larger instruction encodings.
+ // This is used by the ARC target, by the ARM Thumb and x86-64 targets, where
+ // some registers require larger instruction encodings, by the RISC-V target,
+ // where some registers preclude using some C instructions.
int CostPerUse = 0;
// CoveredBySubRegs - When this bit is set, the value of this register is
@@ -223,7 +224,7 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
list<ValueType> RegTypes = regTypes;
// Size - Specify the spill size in bits of the registers. A default value of
- // zero lets tablgen pick an appropriate size.
+ // zero lets tablegen pick an appropriate size.
int Size = 0;
// Alignment - Specify the alignment required of the registers when they are
@@ -275,6 +276,17 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
// constrained classes first. The value has to be in the range [0,63].
int AllocationPriority = 0;
+ // Generate register pressure set for this register class and any class
+ // synthesized from it. Set to 0 to inhibit unneeded pressure sets.
+ bit GeneratePressureSet = 1;
+
+ // Weight override for register pressure calculation. This is the value
+ // TargetRegisterClass::getRegClassWeight() will return. The weight is in
+ // units of pressure for this register class. If unset tablegen will
+ // calculate a weight based on a number of register units in this register
+ // class registers. The weight is per register.
+ int Weight = ?;
+
// The diagnostic type to present when referencing this operand in a match
// failure error message. If this is empty, the default Match_InvalidOperand
// diagnostic type will be used. If this is "<name>", a Match_<name> enum
@@ -652,14 +664,21 @@ class Predicate<string cond> {
/// feature from the AssemblerPredicate class in addition to Predicate.
bit AssemblerMatcherPredicate = 0;
- /// AssemblerCondString - Name of the subtarget feature being tested used
- /// as alternative condition string used for assembler matcher.
- /// e.g. "ModeThumb" is translated to "(Bits & ModeThumb) != 0".
- /// "!ModeThumb" is translated to "(Bits & ModeThumb) == 0".
- /// It can also list multiple features separated by ",".
- /// e.g. "ModeThumb,FeatureThumb2" is translated to
+ /// AssemblerCondDag - Set of subtarget features being tested used
+ /// as alternative condition string used for assembler matcher. Must be used
+ /// with (all_of) to indicate that all features must be present, or (any_of)
+ /// to indicate that at least one must be. The required lack of presence of
+ /// a feature can be tested using a (not) node including the feature.
+ /// e.g. "(all_of ModeThumb)" is translated to "(Bits & ModeThumb) != 0".
+ /// "(all_of (not ModeThumb))" is translated to
+ /// "(Bits & ModeThumb) == 0".
+ /// "(all_of ModeThumb, FeatureThumb2)" is translated to
/// "(Bits & ModeThumb) != 0 && (Bits & FeatureThumb2) != 0".
- string AssemblerCondString = "";
+ /// "(any_of ModeTumb, FeatureThumb2)" is translated to
+ /// "(Bits & ModeThumb) != 0 || (Bits & FeatureThumb2) != 0".
+ /// all_of and any_of cannot be combined in a single dag, instead multiple
+ /// predicates can be placed onto Instruction definitions.
+ dag AssemblerCondDag;
/// PredicateName - User-level name to use for the predicate. Mainly for use
/// in diagnostics such as missing feature errors in the asm matcher.
@@ -684,7 +703,7 @@ class Requires<list<Predicate> preds> {
/// ops definition - This is just a simple marker used to identify the operand
/// list for an instruction. outs and ins are identical both syntactically and
/// semantically; they are used to define def operands and use operands to
-/// improve readibility. This should be used like this:
+/// improve readability. This should be used like this:
/// (outs R32:$dst), (ins R32:$src1, R32:$src2) or something similar.
def ops;
def outs;
@@ -888,6 +907,10 @@ def untyped_imm_0 : TypedOperand<"OPERAND_GENERIC_IMM_0"> {
///
def zero_reg;
+/// undef_tied_input - Special node to indicate an input register tied
+/// to an output which defaults to IMPLICIT_DEF.
+def undef_tied_input;
+
/// All operands which the MC layer classifies as predicates should inherit from
/// this class in some manner. This is already handled for the most commonly
/// used PredicateOperand, but may be useful in other circumstances.
@@ -994,10 +1017,10 @@ def INLINEASM_BR : StandardPseudoInstruction {
let OutOperandList = (outs);
let InOperandList = (ins variable_ops);
let AsmString = "";
- let hasSideEffects = 0; // Note side effect is encoded in an operand.
- let isTerminator = 1;
- let isBranch = 1;
- let isIndirectBranch = 1;
+ // Unlike INLINEASM, this is always treated as having side-effects.
+ let hasSideEffects = 1;
+ // Despite potentially branching, this instruction is intentionally _not_
+ // marked as a terminator or a branch.
}
def CFI_INSTRUCTION : StandardPseudoInstruction {
let OutOperandList = (outs);
@@ -1150,6 +1173,18 @@ def LOAD_STACK_GUARD : StandardPseudoInstruction {
let hasSideEffects = 0;
bit isPseudo = 1;
}
+def PREALLOCATED_SETUP : StandardPseudoInstruction {
+ let OutOperandList = (outs);
+ let InOperandList = (ins i32imm:$a);
+ let usesCustomInserter = 1;
+ let hasSideEffects = 1;
+}
+def PREALLOCATED_ARG : StandardPseudoInstruction {
+ let OutOperandList = (outs ptr_rc:$loc);
+ let InOperandList = (ins i32imm:$a, i32imm:$b);
+ let usesCustomInserter = 1;
+ let hasSideEffects = 1;
+}
def LOCAL_ESCAPE : StandardPseudoInstruction {
// This instruction is really just a label. It has to be part of the chain so
// that it doesn't get dropped from the DAG, but it produces nothing and has
@@ -1336,11 +1371,15 @@ class AsmParserVariant {
}
def DefaultAsmParserVariant : AsmParserVariant;
+// Operators for combining SubtargetFeatures in AssemblerPredicates
+def any_of;
+def all_of;
+
/// AssemblerPredicate - This is a Predicate that can be used when the assembler
/// matches instructions and aliases.
-class AssemblerPredicate<string cond, string name = ""> {
+class AssemblerPredicate<dag cond, string name = ""> {
bit AssemblerMatcherPredicate = 1;
- string AssemblerCondString = cond;
+ dag AssemblerCondDag = cond;
string PredicateName = name;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetCallingConv.td b/contrib/llvm-project/llvm/include/llvm/Target/TargetCallingConv.td
index d5f3931c3d5d..057f33083e08 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetCallingConv.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetCallingConv.td
@@ -41,6 +41,11 @@ class CCIf<string predicate, CCAction A> : CCPredicateAction<A> {
class CCIfByVal<CCAction A> : CCIf<"ArgFlags.isByVal()", A> {
}
+/// CCIfPreallocated - If the current argument has Preallocated parameter attribute,
+/// apply Action A.
+class CCIfPreallocated<CCAction A> : CCIf<"ArgFlags.isPreallocated()", A> {
+}
+
/// CCIfSwiftSelf - If the current argument has swiftself parameter attribute,
/// apply Action A.
class CCIfSwiftSelf<CCAction A> : CCIf<"ArgFlags.isSwiftSelf()", A> {
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetIntrinsicInfo.h b/contrib/llvm-project/llvm/include/llvm/Target/TargetIntrinsicInfo.h
index ef571b15153e..dc59f11c8d9a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetIntrinsicInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetIntrinsicInfo.h
@@ -14,7 +14,6 @@
#define LLVM_TARGET_TARGETINTRINSICINFO_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include <string>
namespace llvm {
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetItinerary.td b/contrib/llvm-project/llvm/include/llvm/Target/TargetItinerary.td
index 89e5abd947d0..d364fab038b5 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetItinerary.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetItinerary.td
@@ -1,4 +1,4 @@
-//===- TargetItinerary.td - Target Itinierary Description --*- tablegen -*-===//
+//===- TargetItinerary.td - Target Itinerary Description --*- tablegen -*-====//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetLoweringObjectFile.h b/contrib/llvm-project/llvm/include/llvm/Target/TargetLoweringObjectFile.h
index d74341b23fb1..cc6c93b6ee2b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetLoweringObjectFile.h
@@ -14,16 +14,17 @@
#ifndef LLVM_CODEGEN_TARGETLOWERINGOBJECTFILE_H
#define LLVM_CODEGEN_TARGETLOWERINGOBJECTFILE_H
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/Module.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/SectionKind.h"
#include <cstdint>
namespace llvm {
+class Constant;
+class DataLayout;
+class Function;
+class GlobalObject;
class GlobalValue;
+class MachineBasicBlock;
class MachineModuleInfo;
class Mangler;
class MCContext;
@@ -33,11 +34,12 @@ class MCSymbol;
class MCSymbolRefExpr;
class MCStreamer;
class MCValue;
+class Module;
+class SectionKind;
+class StringRef;
class TargetMachine;
class TargetLoweringObjectFile : public MCObjectFileInfo {
- MCContext *Ctx = nullptr;
-
/// Name-mangler for global names.
Mangler *Mang = nullptr;
@@ -66,7 +68,6 @@ public:
operator=(const TargetLoweringObjectFile &) = delete;
virtual ~TargetLoweringObjectFile();
- MCContext &getContext() const { return *Ctx; }
Mangler &getMangler() const { return *Mang; }
/// This method must be called before any actual lowering is done. This
@@ -86,9 +87,13 @@ public:
/// Given a constant with the SectionKind, return a section that it should be
/// placed in.
virtual MCSection *getSectionForConstant(const DataLayout &DL,
- SectionKind Kind,
- const Constant *C,
- unsigned &Align) const;
+ SectionKind Kind, const Constant *C,
+ Align &Alignment) const;
+
+ virtual MCSection *
+ getSectionForMachineBasicBlock(const Function &F,
+ const MachineBasicBlock &MBB,
+ const TargetMachine &TM) const;
/// Classify the specified global variable into a set of target independent
/// categories embodied in SectionKind.
@@ -105,9 +110,7 @@ public:
/// variable or function definition. This should not be passed external (or
/// available externally) globals.
MCSection *SectionForGlobal(const GlobalObject *GO,
- const TargetMachine &TM) const {
- return SectionForGlobal(GO, getKindForGlobal(GO, TM), TM);
- }
+ const TargetMachine &TM) const;
virtual void getNameWithPrefix(SmallVectorImpl<char> &OutName,
const GlobalValue *GV,
@@ -212,6 +215,43 @@ public:
return nullptr;
}
+ /// On targets that use separate function descriptor symbols, return a section
+ /// for the descriptor given its symbol. Use only with defined functions.
+ virtual MCSection *
+ getSectionForFunctionDescriptor(const Function *F,
+ const TargetMachine &TM) const {
+ return nullptr;
+ }
+
+ /// On targets that support TOC entries, return a section for the entry given
+ /// the symbol it refers to.
+ /// TODO: Implement this interface for existing ELF targets.
+ virtual MCSection *getSectionForTOCEntry(const MCSymbol *S) const {
+ return nullptr;
+ }
+
+ /// On targets that associate external references with a section, return such
+ /// a section for the given external global.
+ virtual MCSection *
+ getSectionForExternalReference(const GlobalObject *GO,
+ const TargetMachine &TM) const {
+ return nullptr;
+ }
+
+ /// Targets that have a special convention for their symbols could use
+ /// this hook to return a specialized symbol.
+ virtual MCSymbol *getTargetSymbol(const GlobalValue *GV,
+ const TargetMachine &TM) const {
+ return nullptr;
+ }
+
+ /// If supported, return the function entry point symbol.
+ /// Otherwise, returns nulltpr.
+ virtual MCSymbol *getFunctionEntryPointSymbol(const Function *F,
+ const TargetMachine &TM) const {
+ return nullptr;
+ }
+
protected:
virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
SectionKind Kind,
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetMachine.h b/contrib/llvm-project/llvm/include/llvm/Target/TargetMachine.h
index 176ae39b17a7..6d539f1145ee 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetMachine.h
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetMachine.h
@@ -237,11 +237,19 @@ public:
void setSupportsDefaultOutlining(bool Enable) {
Options.SupportsDefaultOutlining = Enable;
}
+ void setSupportsDebugEntryValues(bool Enable) {
+ Options.SupportsDebugEntryValues = Enable;
+ }
bool shouldPrintMachineCode() const { return Options.PrintMachineCode; }
bool getUniqueSectionNames() const { return Options.UniqueSectionNames; }
+ /// Return true if unique basic block section names must be generated.
+ bool getUniqueBasicBlockSectionNames() const {
+ return Options.UniqueBasicBlockSectionNames;
+ }
+
/// Return true if data objects should be emitted into their own section,
/// corresponds to -fdata-sections.
bool getDataSections() const {
@@ -254,6 +262,17 @@ public:
return Options.FunctionSections;
}
+ /// If basic blocks should be emitted into their own section,
+ /// corresponding to -fbasic-block-sections.
+ llvm::BasicBlockSection getBBSectionsType() const {
+ return Options.BBSections;
+ }
+
+ /// Get the list of functions and basic block ids that need unique sections.
+ const MemoryBuffer *getBBSectionsFuncListBuf() const {
+ return Options.BBSectionsFuncListBuf.get();
+ }
+
/// Get a \c TargetIRAnalysis appropriate for the target.
///
/// This is used to construct the new pass manager's target IR analysis pass,
@@ -306,6 +325,10 @@ public:
void getNameWithPrefix(SmallVectorImpl<char> &Name, const GlobalValue *GV,
Mangler &Mang, bool MayAlwaysUsePrivate = false) const;
MCSymbol *getSymbol(const GlobalValue *GV) const;
+
+ /// The integer bit size to use for SjLj based exception handling.
+ static constexpr unsigned DefaultSjLjDataSize = 32;
+ virtual unsigned getSjLjDataSize() const { return DefaultSjLjDataSize; }
};
/// This class describes a target machine that is implemented with the LLVM
@@ -361,11 +384,13 @@ public:
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
MCContext &Context);
- /// True if the target uses physical regs at Prolog/Epilog insertion
- /// time. If true (most machines), all vregs must be allocated before
- /// PEI. If false (virtual-register machines), then callee-save register
- /// spilling and scavenging are not needed or used.
- virtual bool usesPhysRegsForPEI() const { return true; }
+ /// True if the target uses physical regs (as nearly all targets do). False
+ /// for stack machines such as WebAssembly and other virtual-register
+ /// machines. If true, all vregs must be allocated before PEI. If false, then
+ /// callee-save register spilling and scavenging are not needed or used. If
+ /// false, implicitly defined registers will still be assumed to be physical
+ /// registers, except that variadic defs will be allocated vregs.
+ virtual bool usesPhysRegsForValues() const { return true; }
/// True if the target wants to use interprocedural register allocation by
/// default. The -enable-ipra flag can be used to override this.
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetOptions.h b/contrib/llvm-project/llvm/include/llvm/Target/TargetOptions.h
index 84c6ee2a6387..d73686b2bdd8 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetOptions.h
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetOptions.h
@@ -14,11 +14,15 @@
#ifndef LLVM_TARGET_TARGETOPTIONS_H
#define LLVM_TARGET_TARGETOPTIONS_H
+#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/MC/MCTargetOptions.h"
+#include <memory>
+
namespace llvm {
+ struct fltSemantics;
class MachineFunction;
- class Module;
+ class MemoryBuffer;
namespace FloatABI {
enum ABIType {
@@ -54,14 +58,17 @@ namespace llvm {
};
}
- namespace FPDenormal {
- enum DenormalMode {
- IEEE, // IEEE 754 denormal numbers
- PreserveSign, // the sign of a flushed-to-zero number is preserved in
- // the sign of 0
- PositiveZero // denormals are flushed to positive zero
- };
- }
+ enum class BasicBlockSection {
+ All, // Use Basic Block Sections for all basic blocks. A section
+ // for every basic block can significantly bloat object file sizes.
+ List, // Get list of functions & BBs from a file. Selectively enables
+ // basic block sections for a subset of basic blocks which can be
+ // used to control object size bloats from creating sections.
+ Labels, // Do not use Basic Block Sections but label basic blocks. This
+ // is useful when associating profile counts from virtual addresses
+ // to basic blocks.
+ None // Do not use Basic Block Sections.
+ };
enum class EABI {
Unknown,
@@ -114,12 +121,15 @@ namespace llvm {
EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false),
DisableIntegratedAS(false), RelaxELFRelocations(false),
FunctionSections(false), DataSections(false),
- UniqueSectionNames(true), TrapUnreachable(false),
- NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false),
- ExplicitEmulatedTLS(false), EnableIPRA(false),
+ UniqueSectionNames(true), UniqueBasicBlockSectionNames(false),
+ TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
+ EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false),
EmitStackSizeSection(false), EnableMachineOutliner(false),
SupportsDefaultOutlining(false), EmitAddrsig(false),
- EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {}
+ EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
+ EnableDebugEntryValues(false), ForceDwarfFrameSection(false),
+ XRayOmitFunctionIndex(false),
+ FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
/// option is specified on the command line, and should enable debugging
@@ -224,6 +234,9 @@ namespace llvm {
unsigned UniqueSectionNames : 1;
+ /// Use unique names for basic block sections.
+ unsigned UniqueBasicBlockSectionNames : 1;
+
/// Emit target-specific trap instruction for 'unreachable' IR instructions.
unsigned TrapUnreachable : 1;
@@ -256,12 +269,34 @@ namespace llvm {
/// Emit address-significance table.
unsigned EmitAddrsig : 1;
- /// Emit debug info about parameter's entry values.
- unsigned EnableDebugEntryValues : 1;
+ /// Emit basic blocks into separate sections.
+ BasicBlockSection BBSections = BasicBlockSection::None;
+
+ /// Memory Buffer that contains information on sampled basic blocks and used
+ /// to selectively generate basic block sections.
+ std::shared_ptr<MemoryBuffer> BBSectionsFuncListBuf;
+
+ /// The flag enables call site info production. It is used only for debug
+ /// info, and it is restricted only to optimized code. This can be used for
+ /// something else, so that should be controlled in the frontend.
+ unsigned EmitCallSiteInfo : 1;
+ /// Set if the target supports the debug entry values by default.
+ unsigned SupportsDebugEntryValues : 1;
+ /// When set to true, the EnableDebugEntryValues option forces production
+ /// of debug entry values even if the target does not officially support
+ /// it. Useful for testing purposes only. This flag should never be checked
+ /// directly, always use \ref ShouldEmitDebugEntryValues instead.
+ unsigned EnableDebugEntryValues : 1;
+ /// NOTE: There are targets that still do not support the debug entry values
+ /// production.
+ bool ShouldEmitDebugEntryValues() const;
/// Emit DWARF debug frame section.
unsigned ForceDwarfFrameSection : 1;
+ /// Emit XRay Function Index section
+ unsigned XRayOmitFunctionIndex : 1;
+
/// FloatABIType - This setting is set by -float-abi=xxx option is specfied
/// on the command line. This setting may either be Default, Soft, or Hard.
/// Default selects the target's default behavior. Soft selects the ABI for
@@ -298,9 +333,32 @@ namespace llvm {
/// Which debugger to tune for.
DebuggerKind DebuggerTuning = DebuggerKind::Default;
- /// FPDenormalMode - This flags specificies which denormal numbers the code
- /// is permitted to require.
- FPDenormal::DenormalMode FPDenormalMode = FPDenormal::IEEE;
+ private:
+ /// Flushing mode to assume in default FP environment.
+ DenormalMode FPDenormalMode;
+
+ /// Flushing mode to assume in default FP environment, for float/vector of
+ /// float.
+ DenormalMode FP32DenormalMode;
+
+ public:
+ void setFPDenormalMode(DenormalMode Mode) {
+ FPDenormalMode = Mode;
+ }
+
+ void setFP32DenormalMode(DenormalMode Mode) {
+ FP32DenormalMode = Mode;
+ }
+
+ DenormalMode getRawFPDenormalMode() const {
+ return FPDenormalMode;
+ }
+
+ DenormalMode getRawFP32DenormalMode() const {
+ return FP32DenormalMode;
+ }
+
+ DenormalMode getDenormalMode(const fltSemantics &FPType) const;
/// What exception model to use
ExceptionHandling ExceptionModel = ExceptionHandling::None;
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetSchedule.td b/contrib/llvm-project/llvm/include/llvm/Target/TargetSchedule.td
index 24f37e94da91..9f2f27ddcb25 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetSchedule.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetSchedule.td
@@ -99,7 +99,7 @@ class SchedMachineModel {
bit CompleteModel = 1;
// Indicates that we should do full overlap checking for multiple InstrRWs
- // definining the same instructions within the same SchedMachineModel.
+ // defining the same instructions within the same SchedMachineModel.
// FIXME: Remove when all in tree targets are clean with the full check
// enabled.
bit FullInstRWOverlapCheck = 1;
@@ -163,7 +163,7 @@ class ProcResourceKind;
// differently. Here we refer to stage between decoding into micro-ops
// and moving them into a reservation station.) Normally NumMicroOps
// is sufficient to limit dispatch/issue groups. However, some
-// processors can form groups of with only certain combinitions of
+// processors can form groups of with only certain combinations of
// instruction types. e.g. POWER7.
//
// Use BufferSize = 1 for in-order execution units. This is used for
diff --git a/contrib/llvm-project/llvm/include/llvm/Target/TargetSelectionDAG.td b/contrib/llvm-project/llvm/include/llvm/Target/TargetSelectionDAG.td
index 46ad5a619770..de809bb10d49 100644
--- a/contrib/llvm-project/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/contrib/llvm-project/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -316,6 +316,7 @@ def vt : SDNode<"ISD::VALUETYPE" , SDTOther , [], "VTSDNode">;
def bb : SDNode<"ISD::BasicBlock", SDTOther , [], "BasicBlockSDNode">;
def cond : SDNode<"ISD::CONDCODE" , SDTOther , [], "CondCodeSDNode">;
def undef : SDNode<"ISD::UNDEF" , SDTUNDEF , []>;
+def vscale : SDNode<"ISD::VSCALE" , SDTIntUnaryOp, []>;
def globaladdr : SDNode<"ISD::GlobalAddress", SDTPtrLeaf, [],
"GlobalAddressSDNode">;
def tglobaladdr : SDNode<"ISD::TargetGlobalAddress", SDTPtrLeaf, [],
@@ -401,7 +402,9 @@ def smulfixsat : SDNode<"ISD::SMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>
def umulfix : SDNode<"ISD::UMULFIX" , SDTIntScaledBinOp, [SDNPCommutative]>;
def umulfixsat : SDNode<"ISD::UMULFIXSAT", SDTIntScaledBinOp, [SDNPCommutative]>;
def sdivfix : SDNode<"ISD::SDIVFIX" , SDTIntScaledBinOp>;
+def sdivfixsat : SDNode<"ISD::SDIVFIXSAT", SDTIntScaledBinOp>;
def udivfix : SDNode<"ISD::UDIVFIX" , SDTIntScaledBinOp>;
+def udivfixsat : SDNode<"ISD::UDIVFIXSAT", SDTIntScaledBinOp>;
def sext_inreg : SDNode<"ISD::SIGN_EXTEND_INREG", SDTExtInreg>;
def sext_invec : SDNode<"ISD::SIGN_EXTEND_VECTOR_INREG", SDTExtInvec>;
@@ -563,8 +566,6 @@ def br : SDNode<"ISD::BR" , SDTBr, [SDNPHasChain]>;
def catchret : SDNode<"ISD::CATCHRET" , SDTCatchret,
[SDNPHasChain, SDNPSideEffect]>;
def cleanupret : SDNode<"ISD::CLEANUPRET" , SDTNone, [SDNPHasChain]>;
-def catchpad : SDNode<"ISD::CATCHPAD" , SDTNone,
- [SDNPHasChain, SDNPSideEffect]>;
def trap : SDNode<"ISD::TRAP" , SDTNone,
[SDNPHasChain, SDNPSideEffect]>;
@@ -666,10 +667,11 @@ def intrinsic_w_chain : SDNode<"ISD::INTRINSIC_W_CHAIN",
def intrinsic_wo_chain : SDNode<"ISD::INTRINSIC_WO_CHAIN",
SDTypeProfile<1, -1, [SDTCisPtrTy<1>]>, []>;
-def SDT_assertext : SDTypeProfile<1, 1,
+def SDT_assert : SDTypeProfile<1, 1,
[SDTCisInt<0>, SDTCisInt<1>, SDTCisSameAs<1, 0>]>;
-def assertsext : SDNode<"ISD::AssertSext", SDT_assertext>;
-def assertzext : SDNode<"ISD::AssertZext", SDT_assertext>;
+def assertsext : SDNode<"ISD::AssertSext", SDT_assert>;
+def assertzext : SDNode<"ISD::AssertZext", SDT_assert>;
+def assertalign : SDNode<"ISD::AssertAlign", SDT_assert>;
//===----------------------------------------------------------------------===//
@@ -717,19 +719,6 @@ class SDNodeXForm<SDNode opc, code xformFunction> {
def NOOP_SDNodeXForm : SDNodeXForm<imm, [{}]>;
//===----------------------------------------------------------------------===//
-// PatPred Subclasses.
-//
-// These allow specifying different sorts of predicates that control whether a
-// node is matched.
-//
-class PatPred;
-
-class CodePatPred<code predicate> : PatPred {
- code PredicateCode = predicate;
-}
-
-
-//===----------------------------------------------------------------------===//
// Selection DAG Pattern Fragments.
//
// Pattern fragments are reusable chunks of dags that match specific things.
@@ -741,7 +730,7 @@ class CodePatPred<code predicate> : PatPred {
/// PatFrags - Represents a set of pattern fragments. Each single fragment
/// can match something on the DAG, from a single node to multiple nested other
/// fragments. The whole set of fragments matches if any of the single
-/// fragemnts match. This allows e.g. matching and "add with overflow" and
+/// fragments match. This allows e.g. matching and "add with overflow" and
/// a regular "add" with the same fragment set.
///
class PatFrags<dag ops, list<dag> frags, code pred = [{}],
@@ -1433,56 +1422,56 @@ def any_uint_to_fp : PatFrags<(ops node:$src),
(uint_to_fp node:$src)]>;
multiclass binary_atomic_op_ord<SDNode atomic_op> {
- def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
+ def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingMonotonic = 1;
}
- def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
+ def NAME#_acquire : PatFrag<(ops node:$ptr, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquire = 1;
}
- def #NAME#_release : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
+ def NAME#_release : PatFrag<(ops node:$ptr, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingRelease = 1;
}
- def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
+ def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquireRelease = 1;
}
- def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$val)> {
+ def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingSequentiallyConsistent = 1;
}
}
multiclass ternary_atomic_op_ord<SDNode atomic_op> {
- def #NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ def NAME#_monotonic : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingMonotonic = 1;
}
- def #NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ def NAME#_acquire : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquire = 1;
}
- def #NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ def NAME#_release : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingRelease = 1;
}
- def #NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ def NAME#_acq_rel : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingAcquireRelease = 1;
}
- def #NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
- (!cast<SDPatternOperator>(#NAME) node:$ptr, node:$cmp, node:$val)> {
+ def NAME#_seq_cst : PatFrag<(ops node:$ptr, node:$cmp, node:$val),
+ (!cast<SDPatternOperator>(NAME) node:$ptr, node:$cmp, node:$val)> {
let IsAtomic = 1;
let IsAtomicOrderingSequentiallyConsistent = 1;
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Testing/Support/Annotations.h b/contrib/llvm-project/llvm/include/llvm/Testing/Support/Annotations.h
index aad1a44f4ec9..cc99d1061520 100644
--- a/contrib/llvm-project/llvm/include/llvm/Testing/Support/Annotations.h
+++ b/contrib/llvm-project/llvm/include/llvm/Testing/Support/Annotations.h
@@ -68,12 +68,14 @@ public:
/// Crashes if there isn't exactly one.
size_t point(llvm::StringRef Name = "") const;
/// Returns the position of all points marked by ^ (or $name^) in the text.
+ /// Order matches the order within the text.
std::vector<size_t> points(llvm::StringRef Name = "") const;
/// Returns the location of the range marked by [[ ]] (or $name[[ ]]).
/// Crashes if there isn't exactly one.
Range range(llvm::StringRef Name = "") const;
/// Returns the location of all ranges marked by [[ ]] (or $name[[ ]]).
+ /// They are ordered by start position within the text.
std::vector<Range> ranges(llvm::StringRef Name = "") const;
private:
diff --git a/contrib/llvm-project/llvm/include/llvm/Testing/Support/Error.h b/contrib/llvm-project/llvm/include/llvm/Testing/Support/Error.h
index 85328f26440b..cd5b79cd6bfb 100644
--- a/contrib/llvm-project/llvm/include/llvm/Testing/Support/Error.h
+++ b/contrib/llvm-project/llvm/include/llvm/Testing/Support/Error.h
@@ -128,6 +128,36 @@ public:
private:
Optional<testing::Matcher<InfoT &>> Matcher;
};
+
+class ErrorMessageMatches
+ : public testing::MatcherInterface<const ErrorHolder &> {
+public:
+ explicit ErrorMessageMatches(
+ testing::Matcher<std::vector<std::string>> Matcher)
+ : Matcher(std::move(Matcher)) {}
+
+ bool MatchAndExplain(const ErrorHolder &Holder,
+ testing::MatchResultListener *listener) const override {
+ std::vector<std::string> Messages;
+ for (const std::shared_ptr<ErrorInfoBase> &Info: Holder.Infos)
+ Messages.push_back(Info->message());
+
+ return Matcher.MatchAndExplain(Messages, listener);
+ }
+
+ void DescribeTo(std::ostream *OS) const override {
+ *OS << "failed with Error whose message ";
+ Matcher.DescribeTo(OS);
+ }
+
+ void DescribeNegationTo(std::ostream *OS) const override {
+ *OS << "failed with an Error whose message ";
+ Matcher.DescribeNegationTo(OS);
+ }
+
+private:
+ testing::Matcher<std::vector<std::string>> Matcher;
+};
} // namespace detail
#define EXPECT_THAT_ERROR(Err, Matcher) \
@@ -154,6 +184,18 @@ testing::Matcher<const detail::ErrorHolder &> Failed(M Matcher) {
testing::SafeMatcherCast<InfoT &>(Matcher)));
}
+template <typename... M>
+testing::Matcher<const detail::ErrorHolder &> FailedWithMessage(M... Matcher) {
+ static_assert(sizeof...(M) > 0, "");
+ return MakeMatcher(
+ new detail::ErrorMessageMatches(testing::ElementsAre(Matcher...)));
+}
+
+template <typename M>
+testing::Matcher<const detail::ErrorHolder &> FailedWithMessageArray(M Matcher) {
+ return MakeMatcher(new detail::ErrorMessageMatches(Matcher));
+}
+
template <typename M>
detail::ValueMatchesPoly<M> HasValue(M Matcher) {
return detail::ValueMatchesPoly<M>(Matcher);
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/ELF/TBEHandler.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/ELF/TBEHandler.h
index 1748fd13f3dc..76484410987f 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/ELF/TBEHandler.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/ELF/TBEHandler.h
@@ -24,7 +24,6 @@ namespace llvm {
class raw_ostream;
class Error;
class StringRef;
-class VersionTuple;
namespace elfabi {
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.def b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.def
index 4c695fe18eec..2fcae3b28d44 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.def
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.def
@@ -13,26 +13,27 @@
///
/// X86 architectures sorted by cpu type and sub type id.
///
-ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL)
-ARCHINFO(x86_64, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_ALL)
-ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H)
+ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL, 32)
+ARCHINFO(x86_64, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_ALL, 64)
+ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H, 64)
///
/// ARM architectures sorted by cpu sub type id.
///
-ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T)
-ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6)
-ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ)
-ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7)
-ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S)
-ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K)
-ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M)
-ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M)
-ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM)
+ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T, 32)
+ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6, 32)
+ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ, 32)
+ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7, 32)
+ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S, 32)
+ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K, 32)
+ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M, 32)
+ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M, 32)
+ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM, 32)
///
/// ARM64 architectures sorted by cpu sub type id.
///
-ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL)
+ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL, 64)
+ARCHINFO(arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E, 64)
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.h
index 3898cbada68f..7a9f951d0316 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/Architecture.h
@@ -13,16 +13,19 @@
#ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
#define LLVM_TEXTAPI_MACHO_ARCHITECTURE_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <utility>
namespace llvm {
+class raw_ostream;
+class StringRef;
+class Triple;
+
namespace MachO {
/// Defines the architecture slices that are supported by Text-based Stub files.
enum Architecture : uint8_t {
-#define ARCHINFO(Arch, Type, SubType) AK_##Arch,
+#define ARCHINFO(Arch, Type, SubType, NumBits) AK_##Arch,
#include "llvm/TextAPI/MachO/Architecture.def"
#undef ARCHINFO
AK_unknown, // this has to go last.
@@ -43,6 +46,9 @@ std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch);
/// Convert a target to an architecture slice.
Architecture mapToArchitecture(const llvm::Triple &Target);
+/// Check if architecture is 64 bit.
+bool is64Bit(Architecture);
+
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
} // end namespace MachO.
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/ArchitectureSet.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/ArchitectureSet.h
index 6e4ede6275b4..c48a4a702363 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/ArchitectureSet.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/ArchitectureSet.h
@@ -13,14 +13,17 @@
#ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
#define LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
-#include "llvm/Support/raw_ostream.h"
#include "llvm/TextAPI/MachO/Architecture.h"
#include <cstddef>
#include <iterator>
#include <limits>
+#include <string>
+#include <tuple>
#include <vector>
namespace llvm {
+class raw_ostream;
+
namespace MachO {
class ArchitectureSet {
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/InterfaceFile.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/InterfaceFile.h
index bd434e04b693..09d2b8c3cdf0 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/InterfaceFile.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/InterfaceFile.h
@@ -158,7 +158,7 @@ public:
/// Set the path from which this file was generated (if applicable).
///
/// \param Path_ The path to the source file.
- void setPath(StringRef Path_) { Path = Path_; }
+ void setPath(StringRef Path_) { Path = std::string(Path_); }
/// Get the path from which this file was generated (if applicable).
///
@@ -217,7 +217,9 @@ public:
const_filtered_target_range targets(ArchitectureSet Archs) const;
/// Set the install name of the library.
- void setInstallName(StringRef InstallName_) { InstallName = InstallName_; }
+ void setInstallName(StringRef InstallName_) {
+ InstallName = std::string(InstallName_);
+ }
/// Get the install name of the library.
StringRef getInstallName() const { return InstallName; }
@@ -272,12 +274,12 @@ public:
/// \param Target_ The target applicable to Parent
/// \param Parent The name of Parent
void addParentUmbrella(const Target &Target_, StringRef Parent);
- const std::vector<std::pair<Target, std::string>> &umbrellas() const {
- return ParentUmbrellas;
- }
- /// Get the parent umbrella framework.
- const std::vector<std::pair<Target, std::string>> getParentUmbrellas() const {
+ /// Get the list of Parent Umbrella frameworks.
+ ///
+ /// \return Returns a list of target information and install name of parent
+ /// umbrellas.
+ const std::vector<std::pair<Target, std::string>> &umbrellas() const {
return ParentUmbrellas;
}
@@ -331,6 +333,20 @@ public:
return UUIDs;
}
+ /// Add a library for inlining to top level library.
+ ///
+ ///\param Document The library to inline with top level library.
+ void addDocument(std::shared_ptr<InterfaceFile> &&Document) {
+ Documents.emplace_back(std::move(Document));
+ }
+
+ /// Get the list of inlined libraries.
+ ///
+ /// \return Returns a list of the inlined frameworks.
+ const std::vector<std::shared_ptr<InterfaceFile>> &documents() const {
+ return Documents;
+ }
+
/// Add a symbol to the symbols list or extend an existing one.
void addSymbol(SymbolKind Kind, StringRef Name, const TargetList &Targets,
SymbolFlags Flags = SymbolFlags::None);
@@ -406,6 +422,7 @@ private:
std::vector<std::pair<Target, std::string>> ParentUmbrellas;
std::vector<InterfaceFileRef> AllowableClients;
std::vector<InterfaceFileRef> ReexportedLibraries;
+ std::vector<std::shared_ptr<InterfaceFile>> Documents;
std::vector<std::pair<Target, std::string>> UUIDs;
SymbolMapType Symbols;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/PackedVersion.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/PackedVersion.h
index 2d0138097dd9..0d9158ae5f0d 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/PackedVersion.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/PackedVersion.h
@@ -13,10 +13,13 @@
#ifndef LLVM_TEXTAPI_MACHO_PACKED_VERSION_H
#define LLVM_TEXTAPI_MACHO_PACKED_VERSION_H
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <utility>
namespace llvm {
+class raw_ostream;
+class StringRef;
+
namespace MachO {
class PackedVersion {
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIReader.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIReader.h
index c551f0454e8e..889b8aad0e9a 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIReader.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIReader.h
@@ -10,9 +10,11 @@
#define LLVM_TEXTAPI_MACHO_READER_H
#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
namespace llvm {
+
+class MemoryBufferRef;
+
namespace MachO {
class InterfaceFile;
diff --git a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIWriter.h b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIWriter.h
index 2a45bb86a332..109ac8e3c371 100644
--- a/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIWriter.h
+++ b/contrib/llvm-project/llvm/include/llvm/TextAPI/MachO/TextAPIWriter.h
@@ -9,9 +9,11 @@
#ifndef LLVM_TEXTAPI_MACHO_WRITER_H
#define LLVM_TEXTAPI_MACHO_WRITER_H
-#include "llvm/Support/MemoryBuffer.h"
-
namespace llvm {
+
+class Error;
+class raw_ostream;
+
namespace MachO {
class InterfaceFile;
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h
new file mode 100644
index 000000000000..c3caa55c25ce
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroCleanup.h
@@ -0,0 +1,28 @@
+//===-- CoroCleanup.h - Lower all coroutine related intrinsics --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// This file delcares a pass that lowers all remaining coroutine intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_COROUTINES_COROCLEANUP_H
+#define LLVM_TRANSFORMS_COROUTINES_COROCLEANUP_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct CoroCleanupPass : PassInfoMixin<CoroCleanupPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_COROUTINES_COROCLEANUP_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroEarly.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroEarly.h
new file mode 100644
index 000000000000..0f5d1e40eb17
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroEarly.h
@@ -0,0 +1,31 @@
+//===---- CoroEarly.h - Lower early coroutine intrinsics --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// This file provides the interface to the early coroutine intrinsic lowering
+// pass. This pass lowers coroutine intrinsics that hide the details of the
+// exact calling convention for coroutine resume and destroy functions and
+// details of the structure of the coroutine frame.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_COROUTINES_COROEARLY_H
+#define LLVM_TRANSFORMS_COROUTINES_COROEARLY_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct CoroEarlyPass : PassInfoMixin<CoroEarlyPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_COROUTINES_COROEARLY_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroElide.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroElide.h
new file mode 100644
index 000000000000..348e8e355ea0
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroElide.h
@@ -0,0 +1,30 @@
+//===---- CoroElide.h - Coroutine frame allocation elision ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// This file declares a pass that replaces dynamic allocation of coroutine
+// frames with alloca and replaces calls to llvm.coro.resume and
+// llvm.coro.destroy with direct calls to coroutine sub-functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_COROUTINES_COROELIDE_H
+#define LLVM_TRANSFORMS_COROUTINES_COROELIDE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+class Function;
+
+struct CoroElidePass : PassInfoMixin<CoroElidePass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_COROUTINES_COROELIDE_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroSplit.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroSplit.h
new file mode 100644
index 000000000000..40424e5a7e6a
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Coroutines/CoroSplit.h
@@ -0,0 +1,30 @@
+//===- CoroSplit.h - Converts a coroutine into a state machine -*- C++ -*--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// This file declares the pass that builds the coroutine frame and outlines
+// the resume and destroy parts of the coroutine into separate functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_COROUTINES_COROSPLIT_H
+#define LLVM_TRANSFORMS_COROUTINES_COROSPLIT_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+struct CoroSplitPass : PassInfoMixin<CoroSplitPass> {
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_COROUTINES_COROSPLIT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO.h
index de0c80f5b19a..28e454d3b0fc 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO.h
@@ -25,7 +25,6 @@ class StringRef;
class ModuleSummaryIndex;
class ModulePass;
class Pass;
-class Function;
class BasicBlock;
class GlobalValue;
class raw_ostream;
@@ -84,10 +83,12 @@ ModulePass *createEliminateAvailableExternallyPass();
//===----------------------------------------------------------------------===//
/// createGVExtractionPass - If deleteFn is true, this pass deletes
/// the specified global values. Otherwise, it deletes as much of the module as
-/// possible, except for the global values specified.
+/// possible, except for the global values specified. If keepConstInit is true,
+/// the initializers of global constants are not deleted even if they are
+/// unused.
///
ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
- deleteFn = false);
+ deleteFn = false, bool keepConstInit = false);
//===----------------------------------------------------------------------===//
/// This pass performs iterative function importing from other modules.
@@ -151,6 +152,10 @@ ModulePass *createDeadArgHackingPass();
Pass *createArgumentPromotionPass(unsigned maxElements = 3);
//===----------------------------------------------------------------------===//
+/// createOpenMPOptLegacyPass - OpenMP specific optimizations.
+Pass *createOpenMPOptLegacyPass();
+
+//===----------------------------------------------------------------------===//
/// createIPConstantPropagationPass - This pass propagates constants from call
/// sites into the bodies of functions.
///
@@ -236,12 +241,15 @@ enum class PassSummaryAction {
/// The behavior depends on the summary arguments:
/// - If ExportSummary is non-null, this pass will export type identifiers to
/// the given summary.
-/// - Otherwise, if ImportSummary is non-null, this pass will import type
-/// identifiers from the given summary.
-/// - Otherwise it does neither.
-/// It is invalid for both ExportSummary and ImportSummary to be non-null.
+/// - If ImportSummary is non-null, this pass will import type identifiers from
+/// the given summary.
+/// - Otherwise, if both are null and DropTypeTests is true, all type test
+/// assume sequences will be removed from the IR.
+/// It is invalid for both ExportSummary and ImportSummary to be non-null
+/// unless DropTypeTests is true.
ModulePass *createLowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
- const ModuleSummaryIndex *ImportSummary);
+ const ModuleSummaryIndex *ImportSummary,
+ bool DropTypeTests = false);
/// This pass export CFI checks for use by external modules.
ModulePass *createCrossDSOCFIPass();
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h
index c8afb7bdcd65..6d6cb58abdbb 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/ArgumentPromotion.h
@@ -14,6 +14,7 @@
#include "llvm/IR/PassManager.h"
namespace llvm {
+class TargetTransformInfo;
/// Argument promotion pass.
///
@@ -26,6 +27,17 @@ class ArgumentPromotionPass : public PassInfoMixin<ArgumentPromotionPass> {
public:
ArgumentPromotionPass(unsigned MaxElements = 3u) : MaxElements(MaxElements) {}
+ /// Check if callers and the callee \p F agree how promoted arguments would be
+ /// passed. The ones that they do not agree on are eliminated from the sets but
+ /// the return value has to be observed as well.
+ static bool areFunctionArgsABICompatible(
+ const Function &F, const TargetTransformInfo &TTI,
+ SmallPtrSetImpl<Argument *> &ArgsToPromote,
+ SmallPtrSetImpl<Argument *> &ByValArgsToTransform);
+
+ /// Checks if a type could have padding bytes.
+ static bool isDenselyPacked(Type *type, const DataLayout &DL);
+
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Attributor.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Attributor.h
index f7430a83e8d7..bed180e6717a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Attributor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Attributor.h
@@ -29,7 +29,7 @@
// automatically capture a potential dependence from Q to P. This dependence
// will cause P to be reevaluated whenever Q changes in the future.
//
-// The Attributor will only reevaluated abstract attributes that might have
+// The Attributor will only reevaluate abstract attributes that might have
// changed since the last iteration. That means that the Attribute will not
// revisit all instructions/blocks/functions in the module but only query
// an update from a subset of the abstract attributes.
@@ -101,15 +101,26 @@
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/AssumeBundleQueries.h"
+#include "llvm/Analysis/CFG.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/InlineCost.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/MustExecute.h"
+#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/CallSite.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/IR/AbstractCallSite.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Transforms/Utils/CallGraphUpdater.h"
namespace llvm {
+struct Attributor;
struct AbstractAttribute;
struct InformationCache;
struct AAIsDead;
@@ -143,29 +154,24 @@ enum class DepClassTy {
/// are floating values that do not have a corresponding attribute list
/// position.
struct IRPosition {
- virtual ~IRPosition() {}
/// The positions we distinguish in the IR.
- ///
- /// The values are chosen such that the KindOrArgNo member has a value >= 1
- /// if it is an argument or call site argument while a value < 1 indicates the
- /// respective kind of that value.
- enum Kind : int {
- IRP_INVALID = -6, ///< An invalid position.
- IRP_FLOAT = -5, ///< A position that is not associated with a spot suitable
- ///< for attributes. This could be any value or instruction.
- IRP_RETURNED = -4, ///< An attribute for the function return value.
- IRP_CALL_SITE_RETURNED = -3, ///< An attribute for a call site return value.
- IRP_FUNCTION = -2, ///< An attribute for a function (scope).
- IRP_CALL_SITE = -1, ///< An attribute for a call site (function scope).
- IRP_ARGUMENT = 0, ///< An attribute for a function argument.
- IRP_CALL_SITE_ARGUMENT = 1, ///< An attribute for a call site argument.
+ enum Kind : char {
+ IRP_INVALID, ///< An invalid position.
+ IRP_FLOAT, ///< A position that is not associated with a spot suitable
+ ///< for attributes. This could be any value or instruction.
+ IRP_RETURNED, ///< An attribute for the function return value.
+ IRP_CALL_SITE_RETURNED, ///< An attribute for a call site return value.
+ IRP_FUNCTION, ///< An attribute for a function (scope).
+ IRP_CALL_SITE, ///< An attribute for a call site (function scope).
+ IRP_ARGUMENT, ///< An attribute for a function argument.
+ IRP_CALL_SITE_ARGUMENT, ///< An attribute for a call site argument.
};
/// Default constructor available to create invalid positions implicitly. All
/// other positions need to be created explicitly through the appropriate
/// static member function.
- IRPosition() : AnchorVal(nullptr), KindOrArgNo(IRP_INVALID) { verify(); }
+ IRPosition() : Enc(nullptr, ENC_VALUE) { verify(); }
/// Create a position describing the value of \p V.
static const IRPosition value(const Value &V) {
@@ -188,7 +194,7 @@ struct IRPosition {
/// Create a position describing the argument \p Arg.
static const IRPosition argument(const Argument &Arg) {
- return IRPosition(const_cast<Argument &>(Arg), Kind(Arg.getArgNo()));
+ return IRPosition(const_cast<Argument &>(Arg), IRP_ARGUMENT);
}
/// Create a position describing the function scope of \p CB.
@@ -204,29 +210,15 @@ struct IRPosition {
/// Create a position describing the argument of \p CB at position \p ArgNo.
static const IRPosition callsite_argument(const CallBase &CB,
unsigned ArgNo) {
- return IRPosition(const_cast<CallBase &>(CB), Kind(ArgNo));
- }
-
- /// Create a position describing the function scope of \p ICS.
- static const IRPosition callsite_function(ImmutableCallSite ICS) {
- return IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction()));
- }
-
- /// Create a position describing the returned value of \p ICS.
- static const IRPosition callsite_returned(ImmutableCallSite ICS) {
- return IRPosition::callsite_returned(cast<CallBase>(*ICS.getInstruction()));
- }
-
- /// Create a position describing the argument of \p ICS at position \p ArgNo.
- static const IRPosition callsite_argument(ImmutableCallSite ICS,
- unsigned ArgNo) {
- return IRPosition::callsite_argument(cast<CallBase>(*ICS.getInstruction()),
- ArgNo);
+ return IRPosition(const_cast<Use &>(CB.getArgOperandUse(ArgNo)),
+ IRP_CALL_SITE_ARGUMENT);
}
/// Create a position describing the argument of \p ACS at position \p ArgNo.
static const IRPosition callsite_argument(AbstractCallSite ACS,
unsigned ArgNo) {
+ if (ACS.getNumArgOperands() <= ArgNo)
+ return IRPosition();
int CSArgNo = ACS.getCallArgOperandNo(ArgNo);
if (CSArgNo >= 0)
return IRPosition::callsite_argument(
@@ -247,9 +239,7 @@ struct IRPosition {
return IRPosition::function(*IRP.getAssociatedFunction());
}
- bool operator==(const IRPosition &RHS) const {
- return (AnchorVal == RHS.AnchorVal) && (KindOrArgNo == RHS.KindOrArgNo);
- }
+ bool operator==(const IRPosition &RHS) const { return Enc == RHS.Enc; }
bool operator!=(const IRPosition &RHS) const { return !(*this == RHS); }
/// Return the value this abstract attribute is anchored with.
@@ -259,25 +249,23 @@ struct IRPosition {
/// far, only the case for call site arguments as the value is not sufficient
/// to pinpoint them. Instead, we can use the call site as an anchor.
Value &getAnchorValue() const {
- assert(KindOrArgNo != IRP_INVALID &&
- "Invalid position does not have an anchor value!");
- return *AnchorVal;
+ switch (getEncodingBits()) {
+ case ENC_VALUE:
+ case ENC_RETURNED_VALUE:
+ case ENC_FLOATING_FUNCTION:
+ return *getAsValuePtr();
+ case ENC_CALL_SITE_ARGUMENT_USE:
+ return *(getAsUsePtr()->getUser());
+ default:
+ llvm_unreachable("Unkown encoding!");
+ };
}
/// Return the associated function, if any.
Function *getAssociatedFunction() const {
- if (auto *CB = dyn_cast<CallBase>(AnchorVal))
+ if (auto *CB = dyn_cast<CallBase>(&getAnchorValue()))
return CB->getCalledFunction();
- assert(KindOrArgNo != IRP_INVALID &&
- "Invalid position does not have an anchor scope!");
- Value &V = getAnchorValue();
- if (isa<Function>(V))
- return &cast<Function>(V);
- if (isa<Argument>(V))
- return cast<Argument>(V).getParent();
- if (isa<Instruction>(V))
- return cast<Instruction>(V).getFunction();
- return nullptr;
+ return getAnchorScope();
}
/// Return the associated argument, if any.
@@ -324,17 +312,33 @@ struct IRPosition {
/// Return the value this abstract attribute is associated with.
Value &getAssociatedValue() const {
- assert(KindOrArgNo != IRP_INVALID &&
- "Invalid position does not have an associated value!");
- if (getArgNo() < 0 || isa<Argument>(AnchorVal))
- return *AnchorVal;
- assert(isa<CallBase>(AnchorVal) && "Expected a call base!");
- return *cast<CallBase>(AnchorVal)->getArgOperand(getArgNo());
+ if (getArgNo() < 0 || isa<Argument>(&getAnchorValue()))
+ return getAnchorValue();
+ assert(isa<CallBase>(&getAnchorValue()) && "Expected a call base!");
+ return *cast<CallBase>(&getAnchorValue())->getArgOperand(getArgNo());
+ }
+
+ /// Return the type this abstract attribute is associated with.
+ Type *getAssociatedType() const {
+ if (getPositionKind() == IRPosition::IRP_RETURNED)
+ return getAssociatedFunction()->getReturnType();
+ return getAssociatedValue().getType();
}
/// Return the argument number of the associated value if it is an argument or
/// call site argument, otherwise a negative value.
- int getArgNo() const { return KindOrArgNo; }
+ int getArgNo() const {
+ switch (getPositionKind()) {
+ case IRPosition::IRP_ARGUMENT:
+ return cast<Argument>(getAsValuePtr())->getArgNo();
+ case IRPosition::IRP_CALL_SITE_ARGUMENT: {
+ Use &U = *getAsUsePtr();
+ return cast<CallBase>(U.getUser())->getArgOperandNo(&U);
+ }
+ default:
+ return -1;
+ }
+ }
/// Return the index in the attribute list for this position.
unsigned getAttrIdx() const {
@@ -350,7 +354,7 @@ struct IRPosition {
return AttributeList::ReturnIndex;
case IRPosition::IRP_ARGUMENT:
case IRPosition::IRP_CALL_SITE_ARGUMENT:
- return KindOrArgNo + AttributeList::FirstArgIndex;
+ return getArgNo() + AttributeList::FirstArgIndex;
}
llvm_unreachable(
"There is no attribute index for a floating or invalid position!");
@@ -358,19 +362,23 @@ struct IRPosition {
/// Return the associated position kind.
Kind getPositionKind() const {
- if (getArgNo() >= 0) {
- assert(((isa<Argument>(getAnchorValue()) &&
- isa<Argument>(getAssociatedValue())) ||
- isa<CallBase>(getAnchorValue())) &&
- "Expected argument or call base due to argument number!");
- if (isa<CallBase>(getAnchorValue()))
- return IRP_CALL_SITE_ARGUMENT;
+ char EncodingBits = getEncodingBits();
+ if (EncodingBits == ENC_CALL_SITE_ARGUMENT_USE)
+ return IRP_CALL_SITE_ARGUMENT;
+ if (EncodingBits == ENC_FLOATING_FUNCTION)
+ return IRP_FLOAT;
+
+ Value *V = getAsValuePtr();
+ if (!V)
+ return IRP_INVALID;
+ if (isa<Argument>(V))
return IRP_ARGUMENT;
- }
-
- assert(KindOrArgNo < 0 &&
- "Expected (call site) arguments to never reach this point!");
- return Kind(KindOrArgNo);
+ if (isa<Function>(V))
+ return isReturnPosition(EncodingBits) ? IRP_RETURNED : IRP_FUNCTION;
+ if (isa<CallBase>(V))
+ return isReturnPosition(EncodingBits) ? IRP_CALL_SITE_RETURNED
+ : IRP_CALL_SITE;
+ return IRP_FLOAT;
}
/// TODO: Figure out if the attribute related helper functions should live
@@ -382,7 +390,8 @@ struct IRPosition {
/// e.g., the function position if this is an
/// argument position, should be ignored.
bool hasAttr(ArrayRef<Attribute::AttrKind> AKs,
- bool IgnoreSubsumingPositions = false) const;
+ bool IgnoreSubsumingPositions = false,
+ Attributor *A = nullptr) const;
/// Return the attributes of any kind in \p AKs existing in the IR at a
/// position that will affect this one. While each position can only have a
@@ -394,23 +403,8 @@ struct IRPosition {
/// argument position, should be ignored.
void getAttrs(ArrayRef<Attribute::AttrKind> AKs,
SmallVectorImpl<Attribute> &Attrs,
- bool IgnoreSubsumingPositions = false) const;
-
- /// Return the attribute of kind \p AK existing in the IR at this position.
- Attribute getAttr(Attribute::AttrKind AK) const {
- if (getPositionKind() == IRP_INVALID || getPositionKind() == IRP_FLOAT)
- return Attribute();
-
- AttributeList AttrList;
- if (ImmutableCallSite ICS = ImmutableCallSite(&getAnchorValue()))
- AttrList = ICS.getAttributes();
- else
- AttrList = getAssociatedFunction()->getAttributes();
-
- if (AttrList.hasAttribute(getAttrIdx(), AK))
- return AttrList.getAttribute(getAttrIdx(), AK);
- return Attribute();
- }
+ bool IgnoreSubsumingPositions = false,
+ Attributor *A = nullptr) const;
/// Remove the attribute of kind \p AKs existing in the IR at this position.
void removeAttrs(ArrayRef<Attribute::AttrKind> AKs) const {
@@ -418,9 +412,9 @@ struct IRPosition {
return;
AttributeList AttrList;
- CallSite CS = CallSite(&getAnchorValue());
- if (CS)
- AttrList = CS.getAttributes();
+ auto *CB = dyn_cast<CallBase>(&getAnchorValue());
+ if (CB)
+ AttrList = CB->getAttributes();
else
AttrList = getAssociatedFunction()->getAttributes();
@@ -428,8 +422,8 @@ struct IRPosition {
for (Attribute::AttrKind AK : AKs)
AttrList = AttrList.removeAttribute(Ctx, getAttrIdx(), AK);
- if (CS)
- CS.setAttributes(AttrList);
+ if (CB)
+ CB->setAttributes(AttrList);
else
getAssociatedFunction()->setAttributes(AttrList);
}
@@ -452,41 +446,127 @@ struct IRPosition {
static const IRPosition TombstoneKey;
///}
+ /// Conversion into a void * to allow reuse of pointer hashing.
+ operator void *() const { return Enc.getOpaqueValue(); }
+
private:
/// Private constructor for special values only!
- explicit IRPosition(int KindOrArgNo)
- : AnchorVal(0), KindOrArgNo(KindOrArgNo) {}
+ explicit IRPosition(void *Ptr) { Enc.setFromOpaqueValue(Ptr); }
/// IRPosition anchored at \p AnchorVal with kind/argument numbet \p PK.
- explicit IRPosition(Value &AnchorVal, Kind PK)
- : AnchorVal(&AnchorVal), KindOrArgNo(PK) {
+ explicit IRPosition(Value &AnchorVal, Kind PK) {
+ switch (PK) {
+ case IRPosition::IRP_INVALID:
+ llvm_unreachable("Cannot create invalid IRP with an anchor value!");
+ break;
+ case IRPosition::IRP_FLOAT:
+ // Special case for floating functions.
+ if (isa<Function>(AnchorVal))
+ Enc = {&AnchorVal, ENC_FLOATING_FUNCTION};
+ else
+ Enc = {&AnchorVal, ENC_VALUE};
+ break;
+ case IRPosition::IRP_FUNCTION:
+ case IRPosition::IRP_CALL_SITE:
+ Enc = {&AnchorVal, ENC_VALUE};
+ break;
+ case IRPosition::IRP_RETURNED:
+ case IRPosition::IRP_CALL_SITE_RETURNED:
+ Enc = {&AnchorVal, ENC_RETURNED_VALUE};
+ break;
+ case IRPosition::IRP_ARGUMENT:
+ Enc = {&AnchorVal, ENC_VALUE};
+ break;
+ case IRPosition::IRP_CALL_SITE_ARGUMENT:
+ llvm_unreachable(
+ "Cannot create call site argument IRP with an anchor value!");
+ break;
+ }
+ verify();
+ }
+
+ /// IRPosition for the use \p U. The position kind \p PK needs to be
+ /// IRP_CALL_SITE_ARGUMENT, the anchor value is the user, the associated value
+ /// the used value.
+ explicit IRPosition(Use &U, Kind PK) {
+ assert(PK == IRP_CALL_SITE_ARGUMENT &&
+ "Use constructor is for call site arguments only!");
+ Enc = {&U, ENC_CALL_SITE_ARGUMENT_USE};
verify();
}
/// Verify internal invariants.
void verify();
-protected:
- /// The value this position is anchored at.
- Value *AnchorVal;
+ /// Return the attributes of kind \p AK existing in the IR as attribute.
+ bool getAttrsFromIRAttr(Attribute::AttrKind AK,
+ SmallVectorImpl<Attribute> &Attrs) const;
- /// The argument number, if non-negative, or the position "kind".
- int KindOrArgNo;
+ /// Return the attributes of kind \p AK existing in the IR as operand bundles
+ /// of an llvm.assume.
+ bool getAttrsFromAssumes(Attribute::AttrKind AK,
+ SmallVectorImpl<Attribute> &Attrs,
+ Attributor &A) const;
+
+ /// Return the underlying pointer as Value *, valid for all positions but
+ /// IRP_CALL_SITE_ARGUMENT.
+ Value *getAsValuePtr() const {
+ assert(getEncodingBits() != ENC_CALL_SITE_ARGUMENT_USE &&
+ "Not a value pointer!");
+ return reinterpret_cast<Value *>(Enc.getPointer());
+ }
+
+ /// Return the underlying pointer as Use *, valid only for
+ /// IRP_CALL_SITE_ARGUMENT positions.
+ Use *getAsUsePtr() const {
+ assert(getEncodingBits() == ENC_CALL_SITE_ARGUMENT_USE &&
+ "Not a value pointer!");
+ return reinterpret_cast<Use *>(Enc.getPointer());
+ }
+
+ /// Return true if \p EncodingBits describe a returned or call site returned
+ /// position.
+ static bool isReturnPosition(char EncodingBits) {
+ return EncodingBits == ENC_RETURNED_VALUE;
+ }
+
+ /// Return true if the encoding bits describe a returned or call site returned
+ /// position.
+ bool isReturnPosition() const { return isReturnPosition(getEncodingBits()); }
+
+ /// The encoding of the IRPosition is a combination of a pointer and two
+ /// encoding bits. The values of the encoding bits are defined in the enum
+ /// below. The pointer is either a Value* (for the first three encoding bit
+ /// combinations) or Use* (for ENC_CALL_SITE_ARGUMENT_USE).
+ ///
+ ///{
+ enum {
+ ENC_VALUE = 0b00,
+ ENC_RETURNED_VALUE = 0b01,
+ ENC_FLOATING_FUNCTION = 0b10,
+ ENC_CALL_SITE_ARGUMENT_USE = 0b11,
+ };
+
+ // Reserve the maximal amount of bits so there is no need to mask out the
+ // remaining ones. We will not encode anything else in the pointer anyway.
+ static constexpr int NumEncodingBits =
+ PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
+ static_assert(NumEncodingBits >= 2, "At least two bits are required!");
+
+ /// The pointer with the encoding bits.
+ PointerIntPair<void *, NumEncodingBits, char> Enc;
+ ///}
+
+ /// Return the encoding bits.
+ char getEncodingBits() const { return Enc.getInt(); }
};
/// Helper that allows IRPosition as a key in a DenseMap.
-template <> struct DenseMapInfo<IRPosition> {
+template <> struct DenseMapInfo<IRPosition> : DenseMapInfo<void *> {
static inline IRPosition getEmptyKey() { return IRPosition::EmptyKey; }
static inline IRPosition getTombstoneKey() {
return IRPosition::TombstoneKey;
}
- static unsigned getHashValue(const IRPosition &IRP) {
- return (DenseMapInfo<Value *>::getHashValue(&IRP.getAnchorValue()) << 4) ^
- (unsigned(IRP.getArgNo()));
- }
- static bool isEqual(const IRPosition &LHS, const IRPosition &RHS) {
- return LHS == RHS;
- }
};
/// A visitor class for IR positions.
@@ -527,25 +607,16 @@ public:
struct AnalysisGetter {
template <typename Analysis>
typename Analysis::Result *getAnalysis(const Function &F) {
- if (!MAM || !F.getParent())
+ if (!FAM || !F.getParent())
return nullptr;
- auto &FAM = MAM->getResult<FunctionAnalysisManagerModuleProxy>(
- const_cast<Module &>(*F.getParent()))
- .getManager();
- return &FAM.getResult<Analysis>(const_cast<Function &>(F));
+ return &FAM->getResult<Analysis>(const_cast<Function &>(F));
}
- template <typename Analysis>
- typename Analysis::Result *getAnalysis(const Module &M) {
- if (!MAM)
- return nullptr;
- return &MAM->getResult<Analysis>(const_cast<Module &>(M));
- }
- AnalysisGetter(ModuleAnalysisManager &MAM) : MAM(&MAM) {}
+ AnalysisGetter(FunctionAnalysisManager &FAM) : FAM(&FAM) {}
AnalysisGetter() {}
private:
- ModuleAnalysisManager *MAM = nullptr;
+ FunctionAnalysisManager *FAM = nullptr;
};
/// Data structure to hold cached (LLVM-IR) information.
@@ -561,36 +632,46 @@ private:
/// reusable, it is advised to inherit from the InformationCache and cast the
/// instance down in the abstract attributes.
struct InformationCache {
- InformationCache(const Module &M, AnalysisGetter &AG)
- : DL(M.getDataLayout()), Explorer(/* ExploreInterBlock */ true), AG(AG) {
-
- CallGraph *CG = AG.getAnalysis<CallGraphAnalysis>(M);
- if (!CG)
- return;
-
- DenseMap<const Function *, unsigned> SccSize;
- for (scc_iterator<CallGraph *> I = scc_begin(CG); !I.isAtEnd(); ++I) {
- for (CallGraphNode *Node : *I)
- SccSize[Node->getFunction()] = I->size();
- }
- SccSizeOpt = std::move(SccSize);
+ InformationCache(const Module &M, AnalysisGetter &AG,
+ BumpPtrAllocator &Allocator, SetVector<Function *> *CGSCC)
+ : DL(M.getDataLayout()), Allocator(Allocator),
+ Explorer(
+ /* ExploreInterBlock */ true, /* ExploreCFGForward */ true,
+ /* ExploreCFGBackward */ true,
+ /* LIGetter */
+ [&](const Function &F) { return AG.getAnalysis<LoopAnalysis>(F); },
+ /* DTGetter */
+ [&](const Function &F) {
+ return AG.getAnalysis<DominatorTreeAnalysis>(F);
+ },
+ /* PDTGetter */
+ [&](const Function &F) {
+ return AG.getAnalysis<PostDominatorTreeAnalysis>(F);
+ }),
+ AG(AG), CGSCC(CGSCC) {}
+
+ ~InformationCache() {
+ // The FunctionInfo objects are allocated via a BumpPtrAllocator, we call
+ // the destructor manually.
+ for (auto &It : FuncInfoMap)
+ It.getSecond()->~FunctionInfo();
}
+ /// A vector type to hold instructions.
+ using InstructionVectorTy = SmallVector<Instruction *, 8>;
+
/// A map type from opcodes to instructions with this opcode.
- using OpcodeInstMapTy = DenseMap<unsigned, SmallVector<Instruction *, 32>>;
+ using OpcodeInstMapTy = DenseMap<unsigned, InstructionVectorTy *>;
/// Return the map that relates "interesting" opcodes with all instructions
/// with that opcode in \p F.
OpcodeInstMapTy &getOpcodeInstMapForFunction(const Function &F) {
- return FuncInstOpcodeMap[&F];
+ return getFunctionInfo(F).OpcodeInstMap;
}
- /// A vector type to hold instructions.
- using InstructionVectorTy = std::vector<Instruction *>;
-
/// Return the instructions in \p F that may read or write memory.
InstructionVectorTy &getReadOrWriteInstsForFunction(const Function &F) {
- return FuncRWInstsMap[&F];
+ return getFunctionInfo(F).RWInsts;
}
/// Return MustBeExecutedContextExplorer
@@ -608,47 +689,90 @@ struct InformationCache {
return AG.getAnalysis<AAManager>(F);
}
+ /// Return true if \p Arg is involved in a must-tail call, thus the argument
+ /// of the caller or callee.
+ bool isInvolvedInMustTailCall(const Argument &Arg) {
+ FunctionInfo &FI = getFunctionInfo(*Arg.getParent());
+ return FI.CalledViaMustTail || FI.ContainsMustTailCall;
+ }
+
/// Return the analysis result from a pass \p AP for function \p F.
template <typename AP>
typename AP::Result *getAnalysisResultForFunction(const Function &F) {
return AG.getAnalysis<AP>(F);
}
- /// Return SCC size on call graph for function \p F.
+ /// Return SCC size on call graph for function \p F or 0 if unknown.
unsigned getSccSize(const Function &F) {
- if (!SccSizeOpt.hasValue())
- return 0;
- return (SccSizeOpt.getValue())[&F];
+ if (CGSCC && CGSCC->count(const_cast<Function *>(&F)))
+ return CGSCC->size();
+ return 0;
}
/// Return datalayout used in the module.
const DataLayout &getDL() { return DL; }
+ /// Return the map conaining all the knowledge we have from `llvm.assume`s.
+ const RetainedKnowledgeMap &getKnowledgeMap() const { return KnowledgeMap; }
+
private:
- /// A map type from functions to opcode to instruction maps.
- using FuncInstOpcodeMapTy = DenseMap<const Function *, OpcodeInstMapTy>;
+ struct FunctionInfo {
+ ~FunctionInfo();
+
+ /// A nested map that remembers all instructions in a function with a
+ /// certain instruction opcode (Instruction::getOpcode()).
+ OpcodeInstMapTy OpcodeInstMap;
+
+ /// A map from functions to their instructions that may read or write
+ /// memory.
+ InstructionVectorTy RWInsts;
+
+ /// Function is called by a `musttail` call.
+ bool CalledViaMustTail;
+
+ /// Function contains a `musttail` call.
+ bool ContainsMustTailCall;
+ };
- /// A map type from functions to their read or write instructions.
- using FuncRWInstsMapTy = DenseMap<const Function *, InstructionVectorTy>;
+ /// A map type from functions to informatio about it.
+ DenseMap<const Function *, FunctionInfo *> FuncInfoMap;
- /// A nested map that remembers all instructions in a function with a certain
- /// instruction opcode (Instruction::getOpcode()).
- FuncInstOpcodeMapTy FuncInstOpcodeMap;
+ /// Return information about the function \p F, potentially by creating it.
+ FunctionInfo &getFunctionInfo(const Function &F) {
+ FunctionInfo *&FI = FuncInfoMap[&F];
+ if (!FI) {
+ FI = new (Allocator) FunctionInfo();
+ initializeInformationCache(F, *FI);
+ }
+ return *FI;
+ }
- /// A map from functions to their instructions that may read or write memory.
- FuncRWInstsMapTy FuncRWInstsMap;
+ /// Initialize the function information cache \p FI for the function \p F.
+ ///
+ /// This method needs to be called for all function that might be looked at
+ /// through the information cache interface *prior* to looking at them.
+ void initializeInformationCache(const Function &F, FunctionInfo &FI);
/// The datalayout used in the module.
const DataLayout &DL;
+ /// The allocator used to allocate memory, e.g. for `FunctionInfo`s.
+ BumpPtrAllocator &Allocator;
+
/// MustBeExecutedContextExplorer
MustBeExecutedContextExplorer Explorer;
+ /// A map with knowledge retained in `llvm.assume` instructions.
+ RetainedKnowledgeMap KnowledgeMap;
+
/// Getters for analysis.
AnalysisGetter &AG;
- /// Cache result for scc size in the call graph
- Optional<DenseMap<const Function *, unsigned>> SccSizeOpt;
+ /// The underlying CGSCC, or null if not available.
+ SetVector<Function *> *CGSCC;
+
+ /// Set of inlineable functions
+ SmallPtrSet<const Function *, 8> InlineableFunctions;
/// Give the Attributor access to the members so
/// Attributor::identifyDefaultAbstractAttributes(...) can initialize them.
@@ -685,21 +809,18 @@ private:
struct Attributor {
/// Constructor
///
+ /// \param Functions The set of functions we are deriving attributes for.
/// \param InfoCache Cache to hold various information accessible for
/// the abstract attributes.
- /// \param DepRecomputeInterval Number of iterations until the dependences
- /// between abstract attributes are recomputed.
- /// \param Whitelist If not null, a set limiting the attribute opportunities.
- Attributor(InformationCache &InfoCache, unsigned DepRecomputeInterval,
- DenseSet<const char *> *Whitelist = nullptr)
- : InfoCache(InfoCache), DepRecomputeInterval(DepRecomputeInterval),
- Whitelist(Whitelist) {}
+ /// \param CGUpdater Helper to update an underlying call graph.
+ /// \param Allowed If not null, a set limiting the attribute opportunities.
+ Attributor(SetVector<Function *> &Functions, InformationCache &InfoCache,
+ CallGraphUpdater &CGUpdater,
+ DenseSet<const char *> *Allowed = nullptr)
+ : Allocator(InfoCache.Allocator), Functions(Functions),
+ InfoCache(InfoCache), CGUpdater(CGUpdater), Allowed(Allowed) {}
- ~Attributor() {
- DeleteContainerPointers(AllAbstractAttributes);
- for (auto &It : ArgumentReplacementMap)
- DeleteContainerPointers(It.second);
- }
+ ~Attributor();
/// Run the analyses until a fixpoint is reached or enforced (timeout).
///
@@ -707,7 +828,7 @@ struct Attributor {
/// as the Attributor is not destroyed (it owns the attributes now).
///
/// \Returns CHANGED if the IR was changed, otherwise UNCHANGED.
- ChangeStatus run(Module &M);
+ ChangeStatus run();
/// Lookup an abstract attribute of type \p AAType at position \p IRP. While
/// no abstract attribute is found equivalent positions are checked, see
@@ -733,8 +854,118 @@ struct Attributor {
const AAType &getAAFor(const AbstractAttribute &QueryingAA,
const IRPosition &IRP, bool TrackDependence = true,
DepClassTy DepClass = DepClassTy::REQUIRED) {
- return getOrCreateAAFor<AAType>(IRP, &QueryingAA, TrackDependence,
- DepClass);
+ return getOrCreateAAFor<AAType>(IRP, &QueryingAA, TrackDependence, DepClass,
+ /* ForceUpdate */ false);
+ }
+
+ /// Similar to getAAFor but the return abstract attribute will be updated (via
+ /// `AbstractAttribute::update`) even if it is found in the cache. This is
+ /// especially useful for AAIsDead as changes in liveness can make updates
+ /// possible/useful that were not happening before as the abstract attribute
+ /// was assumed dead.
+ template <typename AAType>
+ const AAType &getAndUpdateAAFor(const AbstractAttribute &QueryingAA,
+ const IRPosition &IRP,
+ bool TrackDependence = true,
+ DepClassTy DepClass = DepClassTy::REQUIRED) {
+ return getOrCreateAAFor<AAType>(IRP, &QueryingAA, TrackDependence, DepClass,
+ /* ForceUpdate */ true);
+ }
+
+ /// The version of getAAFor that allows to omit a querying abstract
+ /// attribute. Using this after Attributor started running is restricted to
+ /// only the Attributor itself. Initial seeding of AAs can be done via this
+ /// function.
+ template <typename AAType>
+ const AAType &getOrCreateAAFor(const IRPosition &IRP,
+ const AbstractAttribute *QueryingAA = nullptr,
+ bool TrackDependence = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL,
+ bool ForceUpdate = false) {
+ if (AAType *AAPtr = lookupAAFor<AAType>(IRP, QueryingAA, TrackDependence)) {
+ if (ForceUpdate)
+ updateAA(*AAPtr);
+ return *AAPtr;
+ }
+
+ // No matching attribute found, create one.
+ // Use the static create method.
+ auto &AA = AAType::createForPosition(IRP, *this);
+
+ // If we are currenty seeding attributes, enforce seeding rules.
+ if (SeedingPeriod && !shouldSeedAttribute(AA)) {
+ AA.getState().indicatePessimisticFixpoint();
+ return AA;
+ }
+
+ registerAA(AA);
+
+ // For now we ignore naked and optnone functions.
+ bool Invalidate = Allowed && !Allowed->count(&AAType::ID);
+ const Function *FnScope = IRP.getAnchorScope();
+ if (FnScope)
+ Invalidate |= FnScope->hasFnAttribute(Attribute::Naked) ||
+ FnScope->hasFnAttribute(Attribute::OptimizeNone);
+
+ // Bootstrap the new attribute with an initial update to propagate
+ // information, e.g., function -> call site. If it is not on a given
+ // Allowed we will not perform updates at all.
+ if (Invalidate) {
+ AA.getState().indicatePessimisticFixpoint();
+ return AA;
+ }
+
+ AA.initialize(*this);
+
+ // We can initialize (=look at) code outside the current function set but
+ // not call update because that would again spawn new abstract attributes in
+ // potentially unconnected code regions (=SCCs).
+ if (FnScope && !Functions.count(const_cast<Function *>(FnScope))) {
+ AA.getState().indicatePessimisticFixpoint();
+ return AA;
+ }
+
+ // Allow seeded attributes to declare dependencies.
+ // Remember the seeding state.
+ bool OldSeedingPeriod = SeedingPeriod;
+ SeedingPeriod = false;
+
+ updateAA(AA);
+
+ SeedingPeriod = OldSeedingPeriod;
+
+ if (TrackDependence && AA.getState().isValidState())
+ recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
+ DepClass);
+ return AA;
+ }
+
+ /// Return the attribute of \p AAType for \p IRP if existing. This also allows
+ /// non-AA users lookup.
+ template <typename AAType>
+ AAType *lookupAAFor(const IRPosition &IRP,
+ const AbstractAttribute *QueryingAA = nullptr,
+ bool TrackDependence = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL) {
+ static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
+ "Cannot query an attribute with a type not derived from "
+ "'AbstractAttribute'!");
+ assert((QueryingAA || !TrackDependence) &&
+ "Cannot track dependences without a QueryingAA!");
+
+ // Lookup the abstract attribute of type AAType. If found, return it after
+ // registering a dependence of QueryingAA on the one returned attribute.
+ AbstractAttribute *AAPtr = AAMap.lookup({&AAType::ID, IRP});
+ if (!AAPtr)
+ return nullptr;
+
+ AAType *AA = static_cast<AAType *>(AAPtr);
+
+ // Do not register a dependence on an attribute with an invalid state.
+ if (TrackDependence && AA->getState().isValidState())
+ recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
+ DepClass);
+ return AA;
}
/// Explicitly record a dependence from \p FromAA to \p ToAA, that is if
@@ -765,10 +996,11 @@ struct Attributor {
// Put the attribute in the lookup map structure and the container we use to
// keep track of all attributes.
const IRPosition &IRP = AA.getIRPosition();
- auto &KindToAbstractAttributeMap = AAMap[IRP];
- assert(!KindToAbstractAttributeMap.count(&AAType::ID) &&
- "Attribute already in map!");
- KindToAbstractAttributeMap[&AAType::ID] = &AA;
+ AbstractAttribute *&AAPtr = AAMap[{&AAType::ID, IRP}];
+
+ assert(!AAPtr && "Attribute already in map!");
+ AAPtr = &AA;
+
AllAbstractAttributes.push_back(&AA);
return AA;
}
@@ -776,6 +1008,17 @@ struct Attributor {
/// Return the internal information cache.
InformationCache &getInfoCache() { return InfoCache; }
+ /// Return true if this is a module pass, false otherwise.
+ bool isModulePass() const {
+ return !Functions.empty() &&
+ Functions.size() == Functions.front()->getParent()->size();
+ }
+
+ /// Return true if we derive attributes for \p Fn
+ bool isRunOn(Function &Fn) const {
+ return Functions.empty() || Functions.count(&Fn);
+ }
+
/// Determine opportunities to derive 'default' attributes in \p F and create
/// abstract attribute objects for them.
///
@@ -788,11 +1031,13 @@ struct Attributor {
/// various places.
void identifyDefaultAbstractAttributes(Function &F);
- /// Initialize the information cache for queries regarding function \p F.
+ /// Determine whether the function \p F is IPO amendable
///
- /// This method needs to be called for all function that might be looked at
- /// through the information cache interface *prior* to looking at them.
- void initializeInformationCache(Function &F);
+ /// If a function is exactly defined or it has alwaysinline attribute
+ /// and is viable to be inlined, we say it is IPO amendable
+ bool isFunctionIPOAmendable(const Function &F) {
+ return F.hasExactDefinition() || InfoCache.InlineableFunctions.count(&F);
+ }
/// Mark the internal function \p F as live.
///
@@ -805,6 +1050,14 @@ struct Attributor {
identifyDefaultAbstractAttributes(const_cast<Function &>(F));
}
+ /// Helper function to remove callsite.
+ void removeCallSite(CallInst *CI) {
+ if (!CI)
+ return;
+
+ CGUpdater.removeCallSite(*CI);
+ }
+
/// Record that \p U is to be replaces with \p NV after information was
/// manifested. This also triggers deletion of trivially dead istructions.
bool changeUseAfterManifest(Use &U, Value &NV) {
@@ -819,47 +1072,18 @@ struct Attributor {
}
/// Helper function to replace all uses of \p V with \p NV. Return true if
- /// there is any change.
- bool changeValueAfterManifest(Value &V, Value &NV) {
+ /// there is any change. The flag \p ChangeDroppable indicates if dropppable
+ /// uses should be changed too.
+ bool changeValueAfterManifest(Value &V, Value &NV,
+ bool ChangeDroppable = true) {
bool Changed = false;
for (auto &U : V.uses())
- Changed |= changeUseAfterManifest(U, NV);
+ if (ChangeDroppable || !U.getUser()->isDroppable())
+ Changed |= changeUseAfterManifest(U, NV);
return Changed;
}
- /// Get pointer operand of memory accessing instruction. If \p I is
- /// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
- /// is set to false and the instruction is volatile, return nullptr.
- static const Value *getPointerOperand(const Instruction *I,
- bool AllowVolatile) {
- if (auto *LI = dyn_cast<LoadInst>(I)) {
- if (!AllowVolatile && LI->isVolatile())
- return nullptr;
- return LI->getPointerOperand();
- }
-
- if (auto *SI = dyn_cast<StoreInst>(I)) {
- if (!AllowVolatile && SI->isVolatile())
- return nullptr;
- return SI->getPointerOperand();
- }
-
- if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
- if (!AllowVolatile && CXI->isVolatile())
- return nullptr;
- return CXI->getPointerOperand();
- }
-
- if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
- if (!AllowVolatile && RMWI->isVolatile())
- return nullptr;
- return RMWI->getPointerOperand();
- }
-
- return nullptr;
- }
-
/// Record that \p I is to be replaced with `unreachable` after information
/// was manifested.
void changeToUnreachableAfterManifest(Instruction *I) {
@@ -884,17 +1108,50 @@ struct Attributor {
/// Record that \p F is deleted after information was manifested.
void deleteAfterManifest(Function &F) { ToBeDeletedFunctions.insert(&F); }
+ /// If \p V is assumed to be a constant, return it, if it is unclear yet,
+ /// return None, otherwise return `nullptr`.
+ Optional<Constant *> getAssumedConstant(const Value &V,
+ const AbstractAttribute &AA,
+ bool &UsedAssumedInformation);
+
/// Return true if \p AA (or its context instruction) is assumed dead.
///
/// If \p LivenessAA is not provided it is queried.
- bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA);
+ bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA,
+ bool CheckBBLivenessOnly = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL);
+
+ /// Return true if \p I is assumed dead.
+ ///
+ /// If \p LivenessAA is not provided it is queried.
+ bool isAssumedDead(const Instruction &I, const AbstractAttribute *QueryingAA,
+ const AAIsDead *LivenessAA,
+ bool CheckBBLivenessOnly = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL);
+
+ /// Return true if \p U is assumed dead.
+ ///
+ /// If \p FnLivenessAA is not provided it is queried.
+ bool isAssumedDead(const Use &U, const AbstractAttribute *QueryingAA,
+ const AAIsDead *FnLivenessAA,
+ bool CheckBBLivenessOnly = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL);
+
+ /// Return true if \p IRP is assumed dead.
+ ///
+ /// If \p FnLivenessAA is not provided it is queried.
+ bool isAssumedDead(const IRPosition &IRP, const AbstractAttribute *QueryingAA,
+ const AAIsDead *FnLivenessAA,
+ bool CheckBBLivenessOnly = false,
+ DepClassTy DepClass = DepClassTy::OPTIONAL);
/// Check \p Pred on all (transitive) uses of \p V.
///
/// This method will evaluate \p Pred on all (transitive) uses of the
/// associated value and return true if \p Pred holds every time.
- bool checkForAllUses(const function_ref<bool(const Use &, bool &)> &Pred,
- const AbstractAttribute &QueryingAA, const Value &V);
+ bool checkForAllUses(function_ref<bool(const Use &, bool &)> Pred,
+ const AbstractAttribute &QueryingAA, const Value &V,
+ DepClassTy LivenessDepClass = DepClassTy::OPTIONAL);
/// Helper struct used in the communication between an abstract attribute (AA)
/// that wants to change the signature of a function and the Attributor which
@@ -974,6 +1231,16 @@ struct Attributor {
friend struct Attributor;
};
+ /// Check if we can rewrite a function signature.
+ ///
+ /// The argument \p Arg is replaced with new ones defined by the number,
+ /// order, and types in \p ReplacementTypes.
+ ///
+ /// \returns True, if the replacement can be registered, via
+ /// registerFunctionSignatureRewrite, false otherwise.
+ bool isValidFunctionSignatureRewrite(Argument &Arg,
+ ArrayRef<Type *> ReplacementTypes);
+
/// Register a rewrite for a function signature.
///
/// The argument \p Arg is replaced with new ones defined by the number,
@@ -992,9 +1259,11 @@ struct Attributor {
/// This method will evaluate \p Pred on call sites and return
/// true if \p Pred holds in every call sites. However, this is only possible
/// all call sites are known, hence the function has internal linkage.
- bool checkForAllCallSites(const function_ref<bool(AbstractCallSite)> &Pred,
+ /// If true is returned, \p AllCallSitesKnown is set if all possible call
+ /// sites of the function have been visited.
+ bool checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,
const AbstractAttribute &QueryingAA,
- bool RequireAllCallSites);
+ bool RequireAllCallSites, bool &AllCallSitesKnown);
/// Check \p Pred on all values potentially returned by \p F.
///
@@ -1003,31 +1272,30 @@ struct Attributor {
/// matched with their respective return instructions. Returns true if \p Pred
/// holds on all of them.
bool checkForAllReturnedValuesAndReturnInsts(
- const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
- &Pred,
+ function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)> Pred,
const AbstractAttribute &QueryingAA);
/// Check \p Pred on all values potentially returned by the function
/// associated with \p QueryingAA.
///
/// This is the context insensitive version of the method above.
- bool checkForAllReturnedValues(const function_ref<bool(Value &)> &Pred,
+ bool checkForAllReturnedValues(function_ref<bool(Value &)> Pred,
const AbstractAttribute &QueryingAA);
/// Check \p Pred on all instructions with an opcode present in \p Opcodes.
///
/// This method will evaluate \p Pred on all instructions with an opcode
/// present in \p Opcode and return true if \p Pred holds on all of them.
- bool checkForAllInstructions(const function_ref<bool(Instruction &)> &Pred,
+ bool checkForAllInstructions(function_ref<bool(Instruction &)> Pred,
const AbstractAttribute &QueryingAA,
- const ArrayRef<unsigned> &Opcodes);
+ const ArrayRef<unsigned> &Opcodes,
+ bool CheckBBLivenessOnly = false);
/// Check \p Pred on all call-like instructions (=CallBased derived).
///
/// See checkForAllCallLikeInstructions(...) for more information.
- bool
- checkForAllCallLikeInstructions(const function_ref<bool(Instruction &)> &Pred,
- const AbstractAttribute &QueryingAA) {
+ bool checkForAllCallLikeInstructions(function_ref<bool(Instruction &)> Pred,
+ const AbstractAttribute &QueryingAA) {
return checkForAllInstructions(Pred, QueryingAA,
{(unsigned)Instruction::Invoke,
(unsigned)Instruction::CallBr,
@@ -1039,92 +1307,61 @@ struct Attributor {
/// This method will evaluate \p Pred on all instructions that read or write
/// to memory present in the information cache and return true if \p Pred
/// holds on all of them.
- bool checkForAllReadWriteInstructions(
- const llvm::function_ref<bool(Instruction &)> &Pred,
- AbstractAttribute &QueryingAA);
+ bool checkForAllReadWriteInstructions(function_ref<bool(Instruction &)> Pred,
+ AbstractAttribute &QueryingAA);
/// Return the data layout associated with the anchor scope.
const DataLayout &getDataLayout() const { return InfoCache.DL; }
+ /// The allocator used to allocate memory, e.g. for `AbstractAttribute`s.
+ BumpPtrAllocator &Allocator;
+
private:
- /// Check \p Pred on all call sites of \p Fn.
+ /// This method will do fixpoint iteration until fixpoint or the
+ /// maximum iteration count is reached.
///
- /// This method will evaluate \p Pred on call sites and return
- /// true if \p Pred holds in every call sites. However, this is only possible
- /// all call sites are known, hence the function has internal linkage.
- bool checkForAllCallSites(const function_ref<bool(AbstractCallSite)> &Pred,
- const Function &Fn, bool RequireAllCallSites,
- const AbstractAttribute *QueryingAA);
-
- /// The private version of getAAFor that allows to omit a querying abstract
- /// attribute. See also the public getAAFor method.
- template <typename AAType>
- const AAType &getOrCreateAAFor(const IRPosition &IRP,
- const AbstractAttribute *QueryingAA = nullptr,
- bool TrackDependence = false,
- DepClassTy DepClass = DepClassTy::OPTIONAL) {
- if (const AAType *AAPtr =
- lookupAAFor<AAType>(IRP, QueryingAA, TrackDependence))
- return *AAPtr;
-
- // No matching attribute found, create one.
- // Use the static create method.
- auto &AA = AAType::createForPosition(IRP, *this);
- registerAA(AA);
+ /// If the maximum iteration count is reached, This method will
+ /// indicate pessimistic fixpoint on attributes that transitively depend
+ /// on attributes that were scheduled for an update.
+ void runTillFixpoint();
- // For now we ignore naked and optnone functions.
- bool Invalidate = Whitelist && !Whitelist->count(&AAType::ID);
- if (const Function *Fn = IRP.getAnchorScope())
- Invalidate |= Fn->hasFnAttribute(Attribute::Naked) ||
- Fn->hasFnAttribute(Attribute::OptimizeNone);
+ /// Gets called after scheduling, manifests attributes to the LLVM IR.
+ ChangeStatus manifestAttributes();
- // Bootstrap the new attribute with an initial update to propagate
- // information, e.g., function -> call site. If it is not on a given
- // whitelist we will not perform updates at all.
- if (Invalidate) {
- AA.getState().indicatePessimisticFixpoint();
- return AA;
- }
+ /// Gets called after attributes have been manifested, cleans up the IR.
+ /// Deletes dead functions, blocks and instructions.
+ /// Rewrites function signitures and updates the call graph.
+ ChangeStatus cleanupIR();
- AA.initialize(*this);
- AA.update(*this);
+ /// Run `::update` on \p AA and track the dependences queried while doing so.
+ /// Also adjust the state if we know further updates are not necessary.
+ ChangeStatus updateAA(AbstractAttribute &AA);
- if (TrackDependence && AA.getState().isValidState())
- recordDependence(AA, const_cast<AbstractAttribute &>(*QueryingAA),
- DepClass);
- return AA;
- }
+ /// Remember the dependences on the top of the dependence stack such that they
+ /// may trigger further updates. (\see DependenceStack)
+ void rememberDependences();
- /// Return the attribute of \p AAType for \p IRP if existing.
- template <typename AAType>
- const AAType *lookupAAFor(const IRPosition &IRP,
- const AbstractAttribute *QueryingAA = nullptr,
- bool TrackDependence = false,
- DepClassTy DepClass = DepClassTy::OPTIONAL) {
- static_assert(std::is_base_of<AbstractAttribute, AAType>::value,
- "Cannot query an attribute with a type not derived from "
- "'AbstractAttribute'!");
- assert((QueryingAA || !TrackDependence) &&
- "Cannot track dependences without a QueryingAA!");
-
- // Lookup the abstract attribute of type AAType. If found, return it after
- // registering a dependence of QueryingAA on the one returned attribute.
- const auto &KindToAbstractAttributeMap = AAMap.lookup(IRP);
- if (AAType *AA = static_cast<AAType *>(
- KindToAbstractAttributeMap.lookup(&AAType::ID))) {
- // Do not register a dependence on an attribute with an invalid state.
- if (TrackDependence && AA->getState().isValidState())
- recordDependence(*AA, const_cast<AbstractAttribute &>(*QueryingAA),
- DepClass);
- return AA;
- }
- return nullptr;
- }
+ /// Check \p Pred on all call sites of \p Fn.
+ ///
+ /// This method will evaluate \p Pred on call sites and return
+ /// true if \p Pred holds in every call sites. However, this is only possible
+ /// all call sites are known, hence the function has internal linkage.
+ /// If true is returned, \p AllCallSitesKnown is set if all possible call
+ /// sites of the function have been visited.
+ bool checkForAllCallSites(function_ref<bool(AbstractCallSite)> Pred,
+ const Function &Fn, bool RequireAllCallSites,
+ const AbstractAttribute *QueryingAA,
+ bool &AllCallSitesKnown);
/// Apply all requested function signature rewrites
/// (\see registerFunctionSignatureRewrite) and return Changed if the module
/// was altered.
- ChangeStatus rewriteFunctionSignatures();
+ ChangeStatus
+ rewriteFunctionSignatures(SmallPtrSetImpl<Function *> &ModifiedFns);
+
+ /// Check if the Attribute \p AA should be seeded.
+ /// See getOrCreateAAFor.
+ bool shouldSeedAttribute(AbstractAttribute &AA);
/// The set of all abstract attributes.
///{
@@ -1136,43 +1373,47 @@ private:
/// on the outer level, and the addresses of the static member (AAType::ID) on
/// the inner level.
///{
- using KindToAbstractAttributeMap =
- DenseMap<const char *, AbstractAttribute *>;
- DenseMap<IRPosition, KindToAbstractAttributeMap> AAMap;
- ///}
-
- /// A map from abstract attributes to the ones that queried them through calls
- /// to the getAAFor<...>(...) method.
- ///{
- struct QueryMapValueTy {
- /// Set of abstract attributes which were used but not necessarily required
- /// for a potential optimistic state.
- SetVector<AbstractAttribute *> OptionalAAs;
-
- /// Set of abstract attributes which were used and which were necessarily
- /// required for any potential optimistic state.
- SetVector<AbstractAttribute *> RequiredAAs;
- };
- using QueryMapTy = MapVector<const AbstractAttribute *, QueryMapValueTy>;
- QueryMapTy QueryMap;
+ using AAMapKeyTy = std::pair<const char *, IRPosition>;
+ DenseMap<AAMapKeyTy, AbstractAttribute *> AAMap;
///}
/// Map to remember all requested signature changes (= argument replacements).
- DenseMap<Function *, SmallVector<ArgumentReplacementInfo *, 8>>
+ DenseMap<Function *, SmallVector<std::unique_ptr<ArgumentReplacementInfo>, 8>>
ArgumentReplacementMap;
+ /// The set of functions we are deriving attributes for.
+ SetVector<Function *> &Functions;
+
/// The information cache that holds pre-processed (LLVM-IR) information.
InformationCache &InfoCache;
- /// Set if the attribute currently updated did query a non-fix attribute.
- bool QueriedNonFixAA;
+ /// Helper to update an underlying call graph.
+ CallGraphUpdater &CGUpdater;
- /// Number of iterations until the dependences between abstract attributes are
- /// recomputed.
- const unsigned DepRecomputeInterval;
+ /// Set of functions for which we modified the content such that it might
+ /// impact the call graph.
+ SmallPtrSet<Function *, 8> CGModifiedFunctions;
+
+ /// Information about a dependence. If FromAA is changed ToAA needs to be
+ /// updated as well.
+ struct DepInfo {
+ const AbstractAttribute *FromAA;
+ const AbstractAttribute *ToAA;
+ DepClassTy DepClass;
+ };
+
+ /// The dependence stack is used to track dependences during an
+ /// `AbstractAttribute::update` call. As `AbstractAttribute::update` can be
+ /// recursive we might have multiple vectors of dependences in here. The stack
+ /// size, should be adjusted according to the expected recursion depth and the
+ /// inner dependence vector size to the expected number of dependences per
+ /// abstract attribute. Since the inner vectors are actually allocated on the
+ /// stack we can be generous with their size.
+ using DependenceVector = SmallVector<DepInfo, 8>;
+ SmallVector<DependenceVector *, 16> DependenceStack;
/// If not null, a set limiting the attribute opportunities.
- const DenseSet<const char *> *Whitelist;
+ const DenseSet<const char *> *Allowed;
/// A set to remember the functions we already assume to be live and visited.
DenseSet<const Function *> VisitedFunctions;
@@ -1187,12 +1428,16 @@ private:
/// Invoke instructions with at least a single dead successor block.
SmallVector<WeakVH, 16> InvokeWithDeadSuccessor;
+ /// Wheather attributes are being `seeded`, always false after ::run function
+ /// gets called \see getOrCreateAAFor.
+ bool SeedingPeriod = true;
+
/// Functions, blocks, and instructions we delete after manifest is done.
///
///{
SmallPtrSet<Function *, 8> ToBeDeletedFunctions;
SmallPtrSet<BasicBlock *, 8> ToBeDeletedBlocks;
- SmallPtrSet<Instruction *, 8> ToBeDeletedInsts;
+ SmallDenseSet<WeakVH, 8> ToBeDeletedInsts;
///}
};
@@ -1255,11 +1500,20 @@ template <typename base_ty, base_ty BestState, base_ty WorstState>
struct IntegerStateBase : public AbstractState {
using base_t = base_ty;
+ IntegerStateBase() {}
+ IntegerStateBase(base_t Assumed) : Assumed(Assumed) {}
+
/// Return the best possible representable state.
static constexpr base_t getBestState() { return BestState; }
+ static constexpr base_t getBestState(const IntegerStateBase &) {
+ return getBestState();
+ }
/// Return the worst possible representable state.
static constexpr base_t getWorstState() { return WorstState; }
+ static constexpr base_t getWorstState(const IntegerStateBase &) {
+ return getWorstState();
+ }
/// See AbstractState::isValidState()
/// NOTE: For now we simply pretend that the worst possible state is invalid.
@@ -1306,6 +1560,13 @@ struct IntegerStateBase : public AbstractState {
handleNewAssumedValue(R.getAssumed());
}
+ /// "Clamp" this state with \p R. The result is subtype dependent but it is
+ /// intended that information known in either state will be known in
+ /// this one afterwards.
+ void operator+=(const IntegerStateBase<base_t, BestState, WorstState> &R) {
+ handleNewKnownValue(R.getKnown());
+ }
+
void operator|=(const IntegerStateBase<base_t, BestState, WorstState> &R) {
joinOR(R.getAssumed(), R.getKnown());
}
@@ -1398,8 +1659,19 @@ template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
base_ty WorstState = 0>
struct IncIntegerState
: public IntegerStateBase<base_ty, BestState, WorstState> {
+ using super = IntegerStateBase<base_ty, BestState, WorstState>;
using base_t = base_ty;
+ IncIntegerState() : super() {}
+ IncIntegerState(base_t Assumed) : super(Assumed) {}
+
+ /// Return the best possible representable state.
+ static constexpr base_t getBestState() { return BestState; }
+ static constexpr base_t
+ getBestState(const IncIntegerState<base_ty, BestState, WorstState> &) {
+ return getBestState();
+ }
+
/// Take minimum of assumed and \p Value.
IncIntegerState &takeAssumedMinimum(base_t Value) {
// Make sure we never loose "known value".
@@ -1468,8 +1740,12 @@ private:
/// Simple wrapper for a single bit (boolean) state.
struct BooleanState : public IntegerStateBase<bool, 1, 0> {
+ using super = IntegerStateBase<bool, 1, 0>;
using base_t = IntegerStateBase::base_t;
+ BooleanState() : super() {}
+ BooleanState(base_t Assumed) : super(Assumed) {}
+
/// Set the assumed value to \p Value but never below the known one.
void setAssumed(bool Value) { Assumed &= (Known | Value); }
@@ -1520,6 +1796,10 @@ struct IntegerRangeState : public AbstractState {
: BitWidth(BitWidth), Assumed(ConstantRange::getEmpty(BitWidth)),
Known(ConstantRange::getFull(BitWidth)) {}
+ IntegerRangeState(const ConstantRange &CR)
+ : BitWidth(CR.getBitWidth()), Assumed(CR),
+ Known(getWorstState(CR.getBitWidth())) {}
+
/// Return the worst possible representable state.
static ConstantRange getWorstState(uint32_t BitWidth) {
return ConstantRange::getFull(BitWidth);
@@ -1529,6 +1809,9 @@ struct IntegerRangeState : public AbstractState {
static ConstantRange getBestState(uint32_t BitWidth) {
return ConstantRange::getEmpty(BitWidth);
}
+ static ConstantRange getBestState(const IntegerRangeState &IRS) {
+ return getBestState(IRS.getBitWidth());
+ }
/// Return associated values' bit width.
uint32_t getBitWidth() const { return BitWidth; }
@@ -1622,11 +1905,14 @@ struct IRAttributeManifest {
};
/// Helper to tie a abstract state implementation to an abstract attribute.
-template <typename StateTy, typename Base>
-struct StateWrapper : public StateTy, public Base {
+template <typename StateTy, typename BaseType, class... Ts>
+struct StateWrapper : public BaseType, public StateTy {
/// Provide static access to the type of the state.
using StateType = StateTy;
+ StateWrapper(const IRPosition &IRP, Ts... Args)
+ : BaseType(IRP), StateTy(Args...) {}
+
/// See AbstractAttribute::getState(...).
StateType &getState() override { return *this; }
@@ -1635,15 +1921,16 @@ struct StateWrapper : public StateTy, public Base {
};
/// Helper class that provides common functionality to manifest IR attributes.
-template <Attribute::AttrKind AK, typename Base>
-struct IRAttribute : public IRPosition, public Base {
- IRAttribute(const IRPosition &IRP) : IRPosition(IRP) {}
- ~IRAttribute() {}
+template <Attribute::AttrKind AK, typename BaseType>
+struct IRAttribute : public BaseType {
+ IRAttribute(const IRPosition &IRP) : BaseType(IRP) {}
/// See AbstractAttribute::initialize(...).
virtual void initialize(Attributor &A) override {
const IRPosition &IRP = this->getIRPosition();
- if (isa<UndefValue>(IRP.getAssociatedValue()) || hasAttr(getAttrKind())) {
+ if (isa<UndefValue>(IRP.getAssociatedValue()) ||
+ this->hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ false,
+ &A)) {
this->getState().indicateOptimisticFixpoint();
return;
}
@@ -1657,17 +1944,18 @@ struct IRAttribute : public IRPosition, public Base {
// TODO: We could always determine abstract attributes and if sufficient
// information was found we could duplicate the functions that do not
// have an exact definition.
- if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
+ if (IsFnInterface && (!FnScope || !A.isFunctionIPOAmendable(*FnScope)))
this->getState().indicatePessimisticFixpoint();
}
/// See AbstractAttribute::manifest(...).
ChangeStatus manifest(Attributor &A) override {
- if (isa<UndefValue>(getIRPosition().getAssociatedValue()))
+ if (isa<UndefValue>(this->getIRPosition().getAssociatedValue()))
return ChangeStatus::UNCHANGED;
SmallVector<Attribute, 4> DeducedAttrs;
- getDeducedAttributes(getAnchorValue().getContext(), DeducedAttrs);
- return IRAttributeManifest::manifestAttrs(A, getIRPosition(), DeducedAttrs);
+ getDeducedAttributes(this->getAnchorValue().getContext(), DeducedAttrs);
+ return IRAttributeManifest::manifestAttrs(A, this->getIRPosition(),
+ DeducedAttrs);
}
/// Return the kind that identifies the abstract attribute implementation.
@@ -1678,9 +1966,6 @@ struct IRAttribute : public IRPosition, public Base {
SmallVectorImpl<Attribute> &Attrs) const {
Attrs.emplace_back(Attribute::get(Ctx, getAttrKind()));
}
-
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const override { return *this; }
};
/// Base struct for all "concrete attribute" deductions.
@@ -1726,9 +2011,11 @@ struct IRAttribute : public IRPosition, public Base {
/// both directions will be added in the future.
/// NOTE: The mechanics of adding a new "concrete" abstract attribute are
/// described in the file comment.
-struct AbstractAttribute {
+struct AbstractAttribute : public IRPosition {
using StateType = AbstractState;
+ AbstractAttribute(const IRPosition &IRP) : IRPosition(IRP) {}
+
/// Virtual destructor.
virtual ~AbstractAttribute() {}
@@ -1747,7 +2034,8 @@ struct AbstractAttribute {
virtual const StateType &getState() const = 0;
/// Return an IR position, see struct IRPosition.
- virtual const IRPosition &getIRPosition() const = 0;
+ const IRPosition &getIRPosition() const { return *this; };
+ IRPosition &getIRPosition() { return *this; };
/// Helper functions, for debug purposes only.
///{
@@ -1756,6 +2044,12 @@ struct AbstractAttribute {
/// This function should return the "summarized" assumed state as string.
virtual const std::string getAsStr() const = 0;
+
+ /// This function should return the name of the AbstractAttribute
+ virtual const std::string getName() const = 0;
+
+ /// This function should return the address of the ID of the AbstractAttribute
+ virtual const char *getIdAddr() const = 0;
///}
/// Allow the Attributor access to the protected methods.
@@ -1793,6 +2087,12 @@ protected:
///
/// \Return CHANGED if the internal state changed, otherwise UNCHANGED.
virtual ChangeStatus updateImpl(Attributor &A) = 0;
+
+private:
+ /// Set of abstract attributes which were queried by this one. The bit encodes
+ /// if there is an optional of required dependence.
+ using DepTy = PointerIntPair<AbstractAttribute *, 1>;
+ TinyPtrVector<DepTy> Deps;
};
/// Forward declarations of output streams for debug purposes.
@@ -1806,15 +2106,23 @@ raw_ostream &operator<<(raw_ostream &OS, const AbstractState &State);
template <typename base_ty, base_ty BestState, base_ty WorstState>
raw_ostream &
operator<<(raw_ostream &OS,
- const IntegerStateBase<base_ty, BestState, WorstState> &State);
+ const IntegerStateBase<base_ty, BestState, WorstState> &S) {
+ return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
+ << static_cast<const AbstractState &>(S);
+}
raw_ostream &operator<<(raw_ostream &OS, const IntegerRangeState &State);
///}
struct AttributorPass : public PassInfoMixin<AttributorPass> {
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
+struct AttributorCGSCCPass : public PassInfoMixin<AttributorCGSCCPass> {
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
Pass *createAttributorLegacyPass();
+Pass *createAttributorCGSCCLegacyPass();
/// ----------------------------------------------------------------------------
/// Abstract Attribute Classes
@@ -1823,7 +2131,7 @@ Pass *createAttributorLegacyPass();
/// An abstract attribute for the returned values of a function.
struct AAReturnedValues
: public IRAttribute<Attribute::Returned, AbstractAttribute> {
- AAReturnedValues(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AAReturnedValues(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return an assumed unique return value if a single candidate is found. If
/// there cannot be one, return a nullptr. If it is not clear yet, return the
@@ -1839,8 +2147,8 @@ struct AAReturnedValues
/// Note: Unlike the Attributor::checkForAllReturnedValuesAndReturnInsts
/// method, this one will not filter dead return instructions.
virtual bool checkForAllReturnedValuesAndReturnInsts(
- const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
- &Pred) const = 0;
+ function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)> Pred)
+ const = 0;
using iterator =
MapVector<Value *, SmallSetVector<ReturnInst *, 4>>::iterator;
@@ -1856,6 +2164,18 @@ struct AAReturnedValues
static AAReturnedValues &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAReturnedValues"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAReturnedValues
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -1863,7 +2183,7 @@ struct AAReturnedValues
struct AANoUnwind
: public IRAttribute<Attribute::NoUnwind,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoUnwind(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoUnwind(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Returns true if nounwind is assumed.
bool isAssumedNoUnwind() const { return getAssumed(); }
@@ -1874,6 +2194,17 @@ struct AANoUnwind
/// Create an abstract attribute view for the position \p IRP.
static AANoUnwind &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoUnwind"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoUnwind
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -1881,7 +2212,7 @@ struct AANoUnwind
struct AANoSync
: public IRAttribute<Attribute::NoSync,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoSync(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoSync(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Returns true if "nosync" is assumed.
bool isAssumedNoSync() const { return getAssumed(); }
@@ -1892,6 +2223,17 @@ struct AANoSync
/// Create an abstract attribute view for the position \p IRP.
static AANoSync &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoSync"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoSync
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -1900,7 +2242,7 @@ struct AANoSync
struct AANonNull
: public IRAttribute<Attribute::NonNull,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANonNull(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANonNull(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if we assume that the underlying value is nonnull.
bool isAssumedNonNull() const { return getAssumed(); }
@@ -1911,6 +2253,17 @@ struct AANonNull
/// Create an abstract attribute view for the position \p IRP.
static AANonNull &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANonNull"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANonNull
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -1919,7 +2272,7 @@ struct AANonNull
struct AANoRecurse
: public IRAttribute<Attribute::NoRecurse,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoRecurse(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoRecurse(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if "norecurse" is assumed.
bool isAssumedNoRecurse() const { return getAssumed(); }
@@ -1930,6 +2283,17 @@ struct AANoRecurse
/// Create an abstract attribute view for the position \p IRP.
static AANoRecurse &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoRecurse"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoRecurse
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -1938,7 +2302,7 @@ struct AANoRecurse
struct AAWillReturn
: public IRAttribute<Attribute::WillReturn,
StateWrapper<BooleanState, AbstractAttribute>> {
- AAWillReturn(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AAWillReturn(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if "willreturn" is assumed.
bool isAssumedWillReturn() const { return getAssumed(); }
@@ -1949,15 +2313,26 @@ struct AAWillReturn
/// Create an abstract attribute view for the position \p IRP.
static AAWillReturn &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAWillReturn"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AAWillReturn
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract attribute for undefined behavior.
struct AAUndefinedBehavior
- : public StateWrapper<BooleanState, AbstractAttribute>,
- public IRPosition {
- AAUndefinedBehavior(const IRPosition &IRP) : IRPosition(IRP) {}
+ : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAUndefinedBehavior(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Return true if "undefined behavior" is assumed.
bool isAssumedToCauseUB() const { return getAssumed(); }
@@ -1971,44 +2346,62 @@ struct AAUndefinedBehavior
/// Return true if "undefined behavior" is known for a specific instruction.
virtual bool isKnownToCauseUB(Instruction *I) const = 0;
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const override { return *this; }
-
/// Create an abstract attribute view for the position \p IRP.
static AAUndefinedBehavior &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAUndefinedBehavior"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAUndefineBehavior
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface to determine reachability of point A to B.
-struct AAReachability : public StateWrapper<BooleanState, AbstractAttribute>,
- public IRPosition {
- AAReachability(const IRPosition &IRP) : IRPosition(IRP) {}
+struct AAReachability : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAReachability(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Returns true if 'From' instruction is assumed to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
bool isAssumedReachable(const Instruction *From,
const Instruction *To) const {
- return true;
+ return isPotentiallyReachable(From, To);
}
/// Returns true if 'From' instruction is known to reach, 'To' instruction.
/// Users should provide two positions they are interested in, and the class
/// determines (and caches) reachability.
bool isKnownReachable(const Instruction *From, const Instruction *To) const {
- return true;
+ return isPotentiallyReachable(From, To);
}
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const override { return *this; }
-
/// Create an abstract attribute view for the position \p IRP.
static AAReachability &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAReachability"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAReachability
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -2017,7 +2410,7 @@ struct AAReachability : public StateWrapper<BooleanState, AbstractAttribute>,
struct AANoAlias
: public IRAttribute<Attribute::NoAlias,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoAlias(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoAlias(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if we assume that the underlying value is alias.
bool isAssumedNoAlias() const { return getAssumed(); }
@@ -2028,6 +2421,17 @@ struct AANoAlias
/// Create an abstract attribute view for the position \p IRP.
static AANoAlias &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoAlias"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoAlias
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -2036,7 +2440,7 @@ struct AANoAlias
struct AANoFree
: public IRAttribute<Attribute::NoFree,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoFree(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoFree(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if "nofree" is assumed.
bool isAssumedNoFree() const { return getAssumed(); }
@@ -2047,6 +2451,17 @@ struct AANoFree
/// Create an abstract attribute view for the position \p IRP.
static AANoFree &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoFree"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoFree
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
@@ -2055,7 +2470,7 @@ struct AANoFree
struct AANoReturn
: public IRAttribute<Attribute::NoReturn,
StateWrapper<BooleanState, AbstractAttribute>> {
- AANoReturn(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoReturn(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if the underlying object is assumed to never return.
bool isAssumedNoReturn() const { return getAssumed(); }
@@ -2066,18 +2481,36 @@ struct AANoReturn
/// Create an abstract attribute view for the position \p IRP.
static AANoReturn &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoReturn"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoReturn
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface for liveness abstract attribute.
-struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute>,
- public IRPosition {
- AAIsDead(const IRPosition &IRP) : IRPosition(IRP) {}
+struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAIsDead(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+
+protected:
+ /// The query functions are protected such that other attributes need to go
+ /// through the Attributor interfaces: `Attributor::isAssumedDead(...)`
/// Returns true if the underlying value is assumed dead.
virtual bool isAssumedDead() const = 0;
+ /// Returns true if the underlying value is known dead.
+ virtual bool isKnownDead() const = 0;
+
/// Returns true if \p BB is assumed dead.
virtual bool isAssumedDead(const BasicBlock *BB) const = 0;
@@ -2104,19 +2537,48 @@ struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute>,
return false;
}
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const override { return *this; }
-
+public:
/// Create an abstract attribute view for the position \p IRP.
static AAIsDead &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// Determine if \p F might catch asynchronous exceptions.
+ static bool mayCatchAsynchronousExceptions(const Function &F) {
+ return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
+ }
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAIsDead"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AAIsDead
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
+
+ friend struct Attributor;
};
/// State for dereferenceable attribute
struct DerefState : AbstractState {
+ static DerefState getBestState() { return DerefState(); }
+ static DerefState getBestState(const DerefState &) { return getBestState(); }
+
+ /// Return the worst possible representable state.
+ static DerefState getWorstState() {
+ DerefState DS;
+ DS.indicatePessimisticFixpoint();
+ return DS;
+ }
+ static DerefState getWorstState(const DerefState &) {
+ return getWorstState();
+ }
+
/// State representing for dereferenceable bytes.
IncIntegerState<> DerefBytesState;
@@ -2199,20 +2661,21 @@ struct DerefState : AbstractState {
/// Add accessed bytes to the map.
void addAccessedBytes(int64_t Offset, uint64_t Size) {
- AccessedBytesMap[Offset] = std::max(AccessedBytesMap[Offset], Size);
+ uint64_t &AccessedBytes = AccessedBytesMap[Offset];
+ AccessedBytes = std::max(AccessedBytes, Size);
// Known bytes might increase.
computeKnownDerefBytesFromAccessedMap();
}
/// Equality for DerefState.
- bool operator==(const DerefState &R) {
+ bool operator==(const DerefState &R) const {
return this->DerefBytesState == R.DerefBytesState &&
this->GlobalState == R.GlobalState;
}
/// Inequality for DerefState.
- bool operator!=(const DerefState &R) { return !(*this == R); }
+ bool operator!=(const DerefState &R) const { return !(*this == R); }
/// See IntegerStateBase::operator^=
DerefState operator^=(const DerefState &R) {
@@ -2221,6 +2684,13 @@ struct DerefState : AbstractState {
return *this;
}
+ /// See IntegerStateBase::operator+=
+ DerefState operator+=(const DerefState &R) {
+ DerefBytesState += R.DerefBytesState;
+ GlobalState += R.GlobalState;
+ return *this;
+ }
+
/// See IntegerStateBase::operator&=
DerefState operator&=(const DerefState &R) {
DerefBytesState &= R.DerefBytesState;
@@ -2243,7 +2713,7 @@ protected:
struct AADereferenceable
: public IRAttribute<Attribute::Dereferenceable,
StateWrapper<DerefState, AbstractAttribute>> {
- AADereferenceable(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AADereferenceable(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return true if we assume that the underlying value is nonnull.
bool isAssumedNonNull() const {
@@ -2277,17 +2747,29 @@ struct AADereferenceable
static AADereferenceable &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AADereferenceable"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AADereferenceable
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
using AAAlignmentStateType =
- IncIntegerState<uint32_t, /* maximal alignment */ 1U << 29, 0>;
+ IncIntegerState<uint32_t, Value::MaximumAlignment, 0>;
/// An abstract interface for all align attributes.
struct AAAlign : public IRAttribute<
Attribute::Alignment,
StateWrapper<AAAlignmentStateType, AbstractAttribute>> {
- AAAlign(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AAAlign(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// Return assumed alignment.
unsigned getAssumedAlign() const { return getAssumed(); }
@@ -2295,6 +2777,17 @@ struct AAAlign : public IRAttribute<
/// Return known alignment.
unsigned getKnownAlign() const { return getKnown(); }
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAAlign"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AAAlign
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Create an abstract attribute view for the position \p IRP.
static AAAlign &createForPosition(const IRPosition &IRP, Attributor &A);
@@ -2307,7 +2800,7 @@ struct AANoCapture
: public IRAttribute<
Attribute::NoCapture,
StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>> {
- AANoCapture(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AANoCapture(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// State encoding bits. A set bit in the state means the property holds.
/// NO_CAPTURE is the best possible state, 0 the worst possible state.
@@ -2349,17 +2842,25 @@ struct AANoCapture
/// Create an abstract attribute view for the position \p IRP.
static AANoCapture &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AANoCapture"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AANoCapture
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
/// An abstract interface for value simplify abstract attribute.
-struct AAValueSimplify : public StateWrapper<BooleanState, AbstractAttribute>,
- public IRPosition {
- AAValueSimplify(const IRPosition &IRP) : IRPosition(IRP) {}
-
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const { return *this; }
+struct AAValueSimplify : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAValueSimplify(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Return an assumed simplified value if a single candidate is found. If
/// there cannot be one, return original value. If it is not clear yet, return
@@ -2370,13 +2871,25 @@ struct AAValueSimplify : public StateWrapper<BooleanState, AbstractAttribute>,
static AAValueSimplify &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAValueSimplify"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAValueSimplify
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
-struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute>,
- public IRPosition {
- AAHeapToStack(const IRPosition &IRP) : IRPosition(IRP) {}
+struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAHeapToStack(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
/// Returns true if HeapToStack conversion is assumed to be possible.
bool isAssumedHeapToStack() const { return getAssumed(); }
@@ -2384,22 +2897,76 @@ struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute>,
/// Returns true if HeapToStack conversion is known to be possible.
bool isKnownHeapToStack() const { return getKnown(); }
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const { return *this; }
-
/// Create an abstract attribute view for the position \p IRP.
static AAHeapToStack &createForPosition(const IRPosition &IRP, Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAHeapToStack"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is AAHeapToStack
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+/// An abstract interface for privatizability.
+///
+/// A pointer is privatizable if it can be replaced by a new, private one.
+/// Privatizing pointer reduces the use count, interaction between unrelated
+/// code parts.
+///
+/// In order for a pointer to be privatizable its value cannot be observed
+/// (=nocapture), it is (for now) not written (=readonly & noalias), we know
+/// what values are necessary to make the private copy look like the original
+/// one, and the values we need can be loaded (=dereferenceable).
+struct AAPrivatizablePtr
+ : public StateWrapper<BooleanState, AbstractAttribute> {
+ using Base = StateWrapper<BooleanState, AbstractAttribute>;
+ AAPrivatizablePtr(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
+
+ /// Returns true if pointer privatization is assumed to be possible.
+ bool isAssumedPrivatizablePtr() const { return getAssumed(); }
+
+ /// Returns true if pointer privatization is known to be possible.
+ bool isKnownPrivatizablePtr() const { return getKnown(); }
+
+ /// Return the type we can choose for a private copy of the underlying
+ /// value. None means it is not clear yet, nullptr means there is none.
+ virtual Optional<Type *> getPrivatizableType() const = 0;
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AAPrivatizablePtr &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAPrivatizablePtr"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAPricatizablePtr
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
-/// An abstract interface for all memory related attributes.
+/// An abstract interface for memory access kind related attributes
+/// (readnone/readonly/writeonly).
struct AAMemoryBehavior
: public IRAttribute<
Attribute::ReadNone,
StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>> {
- AAMemoryBehavior(const IRPosition &IRP) : IRAttribute(IRP) {}
+ AAMemoryBehavior(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
/// State encoding bits. A set bit in the state means the property holds.
/// BEST_STATE is the best possible state, 0 the worst possible state.
@@ -2410,6 +2977,7 @@ struct AAMemoryBehavior
BEST_STATE = NO_ACCESSES,
};
+ static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
/// Return true if we know that the underlying value is not read or accessed
/// in its respective scope.
@@ -2439,21 +3007,198 @@ struct AAMemoryBehavior
static AAMemoryBehavior &createForPosition(const IRPosition &IRP,
Attributor &A);
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAMemoryBehavior"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAMemoryBehavior
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
-/// An abstract interface for range value analysis.
-struct AAValueConstantRange : public IntegerRangeState,
- public AbstractAttribute,
- public IRPosition {
- AAValueConstantRange(const IRPosition &IRP)
- : IntegerRangeState(
- IRP.getAssociatedValue().getType()->getIntegerBitWidth()),
- IRPosition(IRP) {}
+/// An abstract interface for all memory location attributes
+/// (readnone/argmemonly/inaccessiblememonly/inaccessibleorargmemonly).
+struct AAMemoryLocation
+ : public IRAttribute<
+ Attribute::ReadNone,
+ StateWrapper<BitIntegerState<uint32_t, 511>, AbstractAttribute>> {
+ using MemoryLocationsKind = StateType::base_t;
- /// Return an IR position, see struct IRPosition.
- const IRPosition &getIRPosition() const override { return *this; }
+ AAMemoryLocation(const IRPosition &IRP, Attributor &A) : IRAttribute(IRP) {}
+
+ /// Encoding of different locations that could be accessed by a memory
+ /// access.
+ enum {
+ ALL_LOCATIONS = 0,
+ NO_LOCAL_MEM = 1 << 0,
+ NO_CONST_MEM = 1 << 1,
+ NO_GLOBAL_INTERNAL_MEM = 1 << 2,
+ NO_GLOBAL_EXTERNAL_MEM = 1 << 3,
+ NO_GLOBAL_MEM = NO_GLOBAL_INTERNAL_MEM | NO_GLOBAL_EXTERNAL_MEM,
+ NO_ARGUMENT_MEM = 1 << 4,
+ NO_INACCESSIBLE_MEM = 1 << 5,
+ NO_MALLOCED_MEM = 1 << 6,
+ NO_UNKOWN_MEM = 1 << 7,
+ NO_LOCATIONS = NO_LOCAL_MEM | NO_CONST_MEM | NO_GLOBAL_INTERNAL_MEM |
+ NO_GLOBAL_EXTERNAL_MEM | NO_ARGUMENT_MEM |
+ NO_INACCESSIBLE_MEM | NO_MALLOCED_MEM | NO_UNKOWN_MEM,
+
+ // Helper bit to track if we gave up or not.
+ VALID_STATE = NO_LOCATIONS + 1,
+
+ BEST_STATE = NO_LOCATIONS | VALID_STATE,
+ };
+ static_assert(BEST_STATE == getBestState(), "Unexpected BEST_STATE value");
+
+ /// Return true if we know that the associated functions has no observable
+ /// accesses.
+ bool isKnownReadNone() const { return isKnown(NO_LOCATIONS); }
+
+ /// Return true if we assume that the associated functions has no observable
+ /// accesses.
+ bool isAssumedReadNone() const {
+ return isAssumed(NO_LOCATIONS) | isAssumedStackOnly();
+ }
+
+ /// Return true if we know that the associated functions has at most
+ /// local/stack accesses.
+ bool isKnowStackOnly() const {
+ return isKnown(inverseLocation(NO_LOCAL_MEM, true, true));
+ }
+
+ /// Return true if we assume that the associated functions has at most
+ /// local/stack accesses.
+ bool isAssumedStackOnly() const {
+ return isAssumed(inverseLocation(NO_LOCAL_MEM, true, true));
+ }
+
+ /// Return true if we know that the underlying value will only access
+ /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
+ bool isKnownInaccessibleMemOnly() const {
+ return isKnown(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
+ }
+
+ /// Return true if we assume that the underlying value will only access
+ /// inaccesible memory only (see Attribute::InaccessibleMemOnly).
+ bool isAssumedInaccessibleMemOnly() const {
+ return isAssumed(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
+ }
+
+ /// Return true if we know that the underlying value will only access
+ /// argument pointees (see Attribute::ArgMemOnly).
+ bool isKnownArgMemOnly() const {
+ return isKnown(inverseLocation(NO_ARGUMENT_MEM, true, true));
+ }
+
+ /// Return true if we assume that the underlying value will only access
+ /// argument pointees (see Attribute::ArgMemOnly).
+ bool isAssumedArgMemOnly() const {
+ return isAssumed(inverseLocation(NO_ARGUMENT_MEM, true, true));
+ }
+
+ /// Return true if we know that the underlying value will only access
+ /// inaccesible memory or argument pointees (see
+ /// Attribute::InaccessibleOrArgMemOnly).
+ bool isKnownInaccessibleOrArgMemOnly() const {
+ return isKnown(
+ inverseLocation(NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
+ }
+
+ /// Return true if we assume that the underlying value will only access
+ /// inaccesible memory or argument pointees (see
+ /// Attribute::InaccessibleOrArgMemOnly).
+ bool isAssumedInaccessibleOrArgMemOnly() const {
+ return isAssumed(
+ inverseLocation(NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
+ }
+
+ /// Return true if the underlying value may access memory through arguement
+ /// pointers of the associated function, if any.
+ bool mayAccessArgMem() const { return !isAssumed(NO_ARGUMENT_MEM); }
+
+ /// Return true if only the memory locations specififed by \p MLK are assumed
+ /// to be accessed by the associated function.
+ bool isAssumedSpecifiedMemOnly(MemoryLocationsKind MLK) const {
+ return isAssumed(MLK);
+ }
+
+ /// Return the locations that are assumed to be not accessed by the associated
+ /// function, if any.
+ MemoryLocationsKind getAssumedNotAccessedLocation() const {
+ return getAssumed();
+ }
+
+ /// Return the inverse of location \p Loc, thus for NO_XXX the return
+ /// describes ONLY_XXX. The flags \p AndLocalMem and \p AndConstMem determine
+ /// if local (=stack) and constant memory are allowed as well. Most of the
+ /// time we do want them to be included, e.g., argmemonly allows accesses via
+ /// argument pointers or local or constant memory accesses.
+ static MemoryLocationsKind
+ inverseLocation(MemoryLocationsKind Loc, bool AndLocalMem, bool AndConstMem) {
+ return NO_LOCATIONS & ~(Loc | (AndLocalMem ? NO_LOCAL_MEM : 0) |
+ (AndConstMem ? NO_CONST_MEM : 0));
+ };
+
+ /// Return the locations encoded by \p MLK as a readable string.
+ static std::string getMemoryLocationsAsStr(MemoryLocationsKind MLK);
+
+ /// Simple enum to distinguish read/write/read-write accesses.
+ enum AccessKind {
+ NONE = 0,
+ READ = 1 << 0,
+ WRITE = 1 << 1,
+ READ_WRITE = READ | WRITE,
+ };
+
+ /// Check \p Pred on all accesses to the memory kinds specified by \p MLK.
+ ///
+ /// This method will evaluate \p Pred on all accesses (access instruction +
+ /// underlying accessed memory pointer) and it will return true if \p Pred
+ /// holds every time.
+ virtual bool checkForAllAccessesToMemoryKind(
+ function_ref<bool(const Instruction *, const Value *, AccessKind,
+ MemoryLocationsKind)>
+ Pred,
+ MemoryLocationsKind MLK) const = 0;
+
+ /// Create an abstract attribute view for the position \p IRP.
+ static AAMemoryLocation &createForPosition(const IRPosition &IRP,
+ Attributor &A);
+
+ /// See AbstractState::getAsStr().
+ const std::string getAsStr() const override {
+ return getMemoryLocationsAsStr(getAssumedNotAccessedLocation());
+ }
+
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAMemoryLocation"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAMemoryLocation
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
+ /// Unique ID (due to the unique address)
+ static const char ID;
+};
+
+/// An abstract interface for range value analysis.
+struct AAValueConstantRange
+ : public StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t> {
+ using Base = StateWrapper<IntegerRangeState, AbstractAttribute, uint32_t>;
+ AAValueConstantRange(const IRPosition &IRP, Attributor &A)
+ : Base(IRP, IRP.getAssociatedType()->getIntegerBitWidth()) {}
/// See AbstractAttribute::getState(...).
IntegerRangeState &getState() override { return *this; }
@@ -2478,7 +3223,8 @@ struct AAValueConstantRange : public IntegerRangeState,
/// Return an assumed constant for the assocaited value a program point \p
/// CtxI.
Optional<ConstantInt *>
- getAssumedConstantInt(Attributor &A, const Instruction *CtxI = nullptr) const {
+ getAssumedConstantInt(Attributor &A,
+ const Instruction *CtxI = nullptr) const {
ConstantRange RangeV = getAssumedConstantRange(A, CtxI);
if (auto *C = RangeV.getSingleElement())
return cast<ConstantInt>(
@@ -2488,10 +3234,30 @@ struct AAValueConstantRange : public IntegerRangeState,
return nullptr;
}
+ /// See AbstractAttribute::getName()
+ const std::string getName() const override { return "AAValueConstantRange"; }
+
+ /// See AbstractAttribute::getIdAddr()
+ const char *getIdAddr() const override { return &ID; }
+
+ /// This function should return true if the type of the \p AA is
+ /// AAValueConstantRange
+ static bool classof(const AbstractAttribute *AA) {
+ return (AA->getIdAddr() == &ID);
+ }
+
/// Unique ID (due to the unique address)
static const char ID;
};
+/// Run options, used by the pass manager.
+enum AttributorRunOption {
+ NONE = 0,
+ MODULE = 1 << 0,
+ CGSCC = 1 << 1,
+ ALL = MODULE | CGSCC
+};
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_FUNCTIONATTRS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/FunctionImport.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/FunctionImport.h
index b4dde7b199ff..6eaf82a6bfec 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/FunctionImport.h
@@ -105,8 +105,10 @@ public:
std::function<Expected<std::unique_ptr<Module>>(StringRef Identifier)>;
/// Create a Function Importer.
- FunctionImporter(const ModuleSummaryIndex &Index, ModuleLoaderTy ModuleLoader)
- : Index(Index), ModuleLoader(std::move(ModuleLoader)) {}
+ FunctionImporter(const ModuleSummaryIndex &Index, ModuleLoaderTy ModuleLoader,
+ bool ClearDSOLocalOnDeclarations)
+ : Index(Index), ModuleLoader(std::move(ModuleLoader)),
+ ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {}
/// Import functions in Module \p M based on the supplied import list.
Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
@@ -117,6 +119,10 @@ private:
/// Factory function to load a Module for a given identifier
ModuleLoaderTy ModuleLoader;
+
+ /// See the comment of ClearDSOLocalOnDeclarations in
+ /// Utils/FunctionImportUtils.h.
+ bool ClearDSOLocalOnDeclarations;
};
/// The function importing pass
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Inliner.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Inliner.h
index 8202b94d5a93..3454b0af0d9f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Inliner.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/Inliner.h
@@ -11,9 +11,9 @@
#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/LazyCallGraph.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/ImportedFunctionsInliningStatistics.h"
#include <utility>
@@ -36,6 +36,8 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
/// call the implementation here.
void getAnalysisUsage(AnalysisUsage &Info) const override;
+ using llvm::Pass::doInitialization;
+
bool doInitialization(CallGraph &CG) override;
/// Main run interface method, this implements the interface required by the
@@ -51,7 +53,7 @@ struct LegacyInlinerBase : public CallGraphSCCPass {
/// This method must be implemented by the subclass to determine the cost of
/// inlining the specified call site. If the cost returned is greater than
/// the current inline threshold, the call site is not inlined.
- virtual InlineCost getInlineCost(CallSite CS) = 0;
+ virtual InlineCost getInlineCost(CallBase &CB) = 0;
/// Remove dead functions.
///
@@ -74,6 +76,7 @@ private:
protected:
AssumptionCacheTracker *ACT;
ProfileSummaryInfo *PSI;
+ std::function<const TargetLibraryInfo &(Function &)> GetTLI;
ImportedFunctionsInliningStatistics ImportedFunctionsStats;
};
@@ -93,21 +96,53 @@ protected:
/// passes be composed to achieve the same end result.
class InlinerPass : public PassInfoMixin<InlinerPass> {
public:
- InlinerPass(InlineParams Params = getInlineParams())
- : Params(std::move(Params)) {}
+ InlinerPass() = default;
~InlinerPass();
InlinerPass(InlinerPass &&Arg)
- : Params(std::move(Arg.Params)),
- ImportedFunctionsStats(std::move(Arg.ImportedFunctionsStats)) {}
+ : ImportedFunctionsStats(std::move(Arg.ImportedFunctionsStats)) {}
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
LazyCallGraph &CG, CGSCCUpdateResult &UR);
private:
- InlineParams Params;
+ InlineAdvisor &getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
+ FunctionAnalysisManager &FAM, Module &M);
std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
+ Optional<DefaultInlineAdvisor> OwnedDefaultAdvisor;
};
+/// Module pass, wrapping the inliner pass. This works in conjunction with the
+/// InlineAdvisorAnalysis to facilitate inlining decisions taking into account
+/// module-wide state, that need to keep track of inter-inliner pass runs, for
+/// a given module. An InlineAdvisor is configured and kept alive for the
+/// duration of the ModuleInlinerWrapperPass::run.
+class ModuleInlinerWrapperPass
+ : public PassInfoMixin<ModuleInlinerWrapperPass> {
+public:
+ ModuleInlinerWrapperPass(
+ InlineParams Params = getInlineParams(), bool Debugging = false,
+ InliningAdvisorMode Mode = InliningAdvisorMode::Default,
+ unsigned MaxDevirtIterations = 0);
+ ModuleInlinerWrapperPass(ModuleInlinerWrapperPass &&Arg) = default;
+
+ PreservedAnalyses run(Module &, ModuleAnalysisManager &);
+
+ /// Allow adding more CGSCC passes, besides inlining. This should be called
+ /// before run is called, as part of pass pipeline building.
+ CGSCCPassManager &getPM() { return PM; }
+
+ /// Allow adding module-level analyses benefiting the contained CGSCC passes.
+ template <class T> void addRequiredModuleAnalysis() {
+ MPM.addPass(RequireAnalysisPass<T, Module>());
+ }
+
+private:
+ const InlineParams Params;
+ const InliningAdvisorMode Mode;
+ const unsigned MaxDevirtIterations;
+ CGSCCPassManager PM;
+ ModulePassManager MPM;
+};
} // end namespace llvm
#endif // LLVM_TRANSFORMS_IPO_INLINER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
index 3c2bb65b9552..5e91ae599363 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/LowerTypeTests.h
@@ -201,9 +201,12 @@ class LowerTypeTestsPass : public PassInfoMixin<LowerTypeTestsPass> {
public:
ModuleSummaryIndex *ExportSummary;
const ModuleSummaryIndex *ImportSummary;
+ bool DropTypeTests;
LowerTypeTestsPass(ModuleSummaryIndex *ExportSummary,
- const ModuleSummaryIndex *ImportSummary)
- : ExportSummary(ExportSummary), ImportSummary(ImportSummary) {}
+ const ModuleSummaryIndex *ImportSummary,
+ bool DropTypeTests = false)
+ : ExportSummary(ExportSummary), ImportSummary(ImportSummary),
+ DropTypeTests(DropTypeTests) {}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
new file mode 100644
index 000000000000..d96187b73f9b
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/OpenMPOpt.h
@@ -0,0 +1,66 @@
+//===- IPO/OpenMPOpt.h - Collection of OpenMP optimizations -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_OPENMP_OPT_H
+#define LLVM_TRANSFORMS_IPO_OPENMP_OPT_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+namespace omp {
+
+/// Summary of a kernel (=entry point for target offloading).
+using Kernel = Function *;
+
+/// Helper to remember if the module contains OpenMP (runtime calls), to be used
+/// foremost with containsOpenMP.
+struct OpenMPInModule {
+ OpenMPInModule &operator=(bool Found) {
+ if (Found)
+ Value = OpenMPInModule::OpenMP::FOUND;
+ else
+ Value = OpenMPInModule::OpenMP::NOT_FOUND;
+ return *this;
+ }
+ bool isKnown() { return Value != OpenMP::UNKNOWN; }
+ operator bool() { return Value != OpenMP::NOT_FOUND; }
+
+ /// Return the known kernels (=GPU entry points) in the module.
+ SmallPtrSetImpl<Kernel> &getKernels() { return Kernels; }
+
+ /// Identify kernels in the module and populate the Kernels set.
+ void identifyKernels(Module &M);
+
+private:
+ enum class OpenMP { FOUND, NOT_FOUND, UNKNOWN } Value = OpenMP::UNKNOWN;
+
+ /// Collection of known kernels (=GPU entry points) in the module.
+ SmallPtrSet<Kernel, 8> Kernels;
+};
+
+/// Helper to determine if \p M contains OpenMP (runtime calls).
+bool containsOpenMP(Module &M, OpenMPInModule &OMPInModule);
+
+} // namespace omp
+
+/// OpenMP optimizations pass.
+class OpenMPOptPass : public PassInfoMixin<OpenMPOptPass> {
+ /// Helper to remember if the module contains OpenMP (runtime calls).
+ omp::OpenMPInModule OMPInModule;
+
+public:
+ PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
+ LazyCallGraph &CG, CGSCCUpdateResult &UR);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_OPENMP_OPT_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
index ababa1d61f66..a9928c3f5a40 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -14,6 +14,7 @@
#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+#include "llvm-c/Transforms/PassManagerBuilder.h"
#include <functional>
#include <memory>
#include <string>
@@ -155,6 +156,7 @@ public:
bool DisableTailCalls;
bool DisableUnrollLoops;
+ bool CallGraphProfile;
bool SLPVectorize;
bool LoopVectorize;
bool LoopsInterleaved;
@@ -216,7 +218,6 @@ private:
void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
void addPGOInstrPasses(legacy::PassManagerBase &MPM, bool IsCS);
void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
- void addInstructionCombiningPass(legacy::PassManagerBase &MPM) const;
public:
/// populateFunctionPassManager - This fills in the function pass manager,
@@ -251,5 +252,13 @@ public:
}
};
+inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
+ return reinterpret_cast<PassManagerBuilder*>(P);
+}
+
+inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
+ return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
+}
+
} // end namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h
index 0b3ba86bc9e4..0637d629bd29 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/SyntheticCountsPropagation.h
@@ -1,13 +1,17 @@
+//=- SyntheticCountsPropagation.h - Propagate function counts -----*- C++ -*-=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
#ifndef LLVM_TRANSFORMS_IPO_SYNTHETIC_COUNTS_PROPAGATION_H
#define LLVM_TRANSFORMS_IPO_SYNTHETIC_COUNTS_PROPAGATION_H
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Support/ScaledNumber.h"
namespace llvm {
-class Function;
class Module;
class SyntheticCountsPropagation
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
index 8af2af7f352f..86e28cfead80 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/IPO/WholeProgramDevirt.h
@@ -236,6 +236,11 @@ struct VTableSlotSummary {
uint64_t ByteOffset;
};
+void updateVCallVisibilityInModule(Module &M,
+ bool WholeProgramVisibilityEnabledInLTO);
+void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index,
+ bool WholeProgramVisibilityEnabledInLTO);
+
/// Perform index-based whole program devirtualization on the \p Summary
/// index. Any devirtualized targets used by a type test in another module
/// are added to the \p ExportedGUIDs set. For any local devirtualized targets
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombine.h b/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
index d7a6662510d3..0ad4f54fd465 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombine.h
@@ -24,14 +24,13 @@ namespace llvm {
class InstCombinePass : public PassInfoMixin<InstCombinePass> {
InstCombineWorklist Worklist;
- const bool ExpensiveCombines;
const unsigned MaxIterations;
public:
static StringRef name() { return "InstCombinePass"; }
- explicit InstCombinePass(bool ExpensiveCombines = true);
- explicit InstCombinePass(bool ExpensiveCombines, unsigned MaxIterations);
+ explicit InstCombinePass();
+ explicit InstCombinePass(unsigned MaxIterations);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
@@ -42,15 +41,13 @@ public:
/// will try to combine all instructions in the function.
class InstructionCombiningPass : public FunctionPass {
InstCombineWorklist Worklist;
- const bool ExpensiveCombines;
const unsigned MaxIterations;
public:
static char ID; // Pass identification, replacement for typeid
- explicit InstructionCombiningPass(bool ExpensiveCombines = true);
- explicit InstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations);
+ explicit InstructionCombiningPass();
+ explicit InstructionCombiningPass(unsigned MaxIterations);
void getAnalysisUsage(AnalysisUsage &AU) const override;
bool runOnFunction(Function &F) override;
@@ -68,9 +65,8 @@ public:
// into:
// %Z = add int 2, %X
//
-FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines = true);
-FunctionPass *createInstructionCombiningPass(bool ExpensiveCombines,
- unsigned MaxIterations);
+FunctionPass *createInstructionCombiningPass();
+FunctionPass *createInstructionCombiningPass(unsigned MaxIterations);
}
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombineWorklist.h b/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombineWorklist.h
index 3ed0a820db10..25aabe199d0f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombineWorklist.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/InstCombine/InstCombineWorklist.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/Compiler.h"
@@ -26,6 +27,10 @@ namespace llvm {
class InstCombineWorklist {
SmallVector<Instruction *, 256> Worklist;
DenseMap<Instruction *, unsigned> WorklistMap;
+ /// These instructions will be added in reverse order after the current
+ /// combine has finished. This means that these instructions will be visited
+ /// in the order they have been added.
+ SmallSetVector<Instruction *, 16> Deferred;
public:
InstCombineWorklist() = default;
@@ -33,11 +38,26 @@ public:
InstCombineWorklist(InstCombineWorklist &&) = default;
InstCombineWorklist &operator=(InstCombineWorklist &&) = default;
- bool isEmpty() const { return Worklist.empty(); }
+ bool isEmpty() const { return Worklist.empty() && Deferred.empty(); }
- /// Add - Add the specified instruction to the worklist if it isn't already
- /// in it.
- void Add(Instruction *I) {
+ /// Add instruction to the worklist.
+ /// Instructions will be visited in the order they are added.
+ /// You likely want to use this method.
+ void add(Instruction *I) {
+ if (Deferred.insert(I))
+ LLVM_DEBUG(dbgs() << "IC: ADD DEFERRED: " << *I << '\n');
+ }
+
+ /// Add value to the worklist if it is an instruction.
+ /// Instructions will be visited in the order they are added.
+ void addValue(Value *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ add(I);
+ }
+
+ /// Push the instruction onto the worklist stack.
+ /// Instructions that have been added first will be visited last.
+ void push(Instruction *I) {
assert(I);
assert(I->getParent() && "Instruction not inserted yet?");
@@ -47,58 +67,54 @@ public:
}
}
- void AddValue(Value *V) {
+ void pushValue(Value *V) {
if (Instruction *I = dyn_cast<Instruction>(V))
- Add(I);
+ push(I);
}
- /// AddInitialGroup - Add the specified batch of stuff in reverse order.
- /// which should only be done when the worklist is empty and when the group
- /// has no duplicates.
- void AddInitialGroup(ArrayRef<Instruction *> List) {
- assert(Worklist.empty() && "Worklist must be empty to add initial group");
- Worklist.reserve(List.size()+16);
- WorklistMap.reserve(List.size());
- LLVM_DEBUG(dbgs() << "IC: ADDING: " << List.size()
- << " instrs to worklist\n");
- unsigned Idx = 0;
- for (Instruction *I : reverse(List)) {
- WorklistMap.insert(std::make_pair(I, Idx++));
- Worklist.push_back(I);
- }
+ Instruction *popDeferred() {
+ if (Deferred.empty())
+ return nullptr;
+ return Deferred.pop_back_val();
}
- // Remove - remove I from the worklist if it exists.
- void Remove(Instruction *I) {
- DenseMap<Instruction*, unsigned>::iterator It = WorklistMap.find(I);
- if (It == WorklistMap.end()) return; // Not in worklist.
+ void reserve(size_t Size) {
+ Worklist.reserve(Size + 16);
+ WorklistMap.reserve(Size);
+ }
- // Don't bother moving everything down, just null out the slot.
- Worklist[It->second] = nullptr;
+ /// Remove I from the worklist if it exists.
+ void remove(Instruction *I) {
+ DenseMap<Instruction*, unsigned>::iterator It = WorklistMap.find(I);
+ if (It != WorklistMap.end()) {
+ // Don't bother moving everything down, just null out the slot.
+ Worklist[It->second] = nullptr;
+ WorklistMap.erase(It);
+ }
- WorklistMap.erase(It);
+ Deferred.remove(I);
}
- Instruction *RemoveOne() {
+ Instruction *removeOne() {
+ if (Worklist.empty())
+ return nullptr;
Instruction *I = Worklist.pop_back_val();
WorklistMap.erase(I);
return I;
}
- /// AddUsersToWorkList - When an instruction is simplified, add all users of
- /// the instruction to the work lists because they might get more simplified
- /// now.
- ///
- void AddUsersToWorkList(Instruction &I) {
+ /// When an instruction is simplified, add all users of the instruction
+ /// to the work lists because they might get more simplified now.
+ void pushUsersToWorkList(Instruction &I) {
for (User *U : I.users())
- Add(cast<Instruction>(U));
+ push(cast<Instruction>(U));
}
- /// Zap - check that the worklist is empty and nuke the backing store for
- /// the map if it is large.
- void Zap() {
+ /// Check that the worklist is empty and nuke the backing store for the map.
+ void zap() {
assert(WorklistMap.empty() && "Worklist empty, but map not?");
+ assert(Deferred.empty() && "Deferred instructions left over");
// Do an explicit clear, this shrinks the map if needed.
WorklistMap.clear();
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation.h
index fcad1e11895f..d4373d7b39ea 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation.h
@@ -28,6 +28,7 @@ class FunctionPass;
class ModulePass;
class OptimizationRemarkEmitter;
class Comdat;
+class CallBase;
/// Instrumentation passes often insert conditional checks into entry blocks.
/// Call this function before splitting the entry block to move instructions
@@ -62,21 +63,9 @@ struct GCOVOptions {
// gcc's gcov-io.h
char Version[4];
- // Emit a "cfg checksum" that follows the "line number checksum" of a
- // function. This affects both .gcno and .gcda files.
- bool UseCfgChecksum;
-
// Add the 'noredzone' attribute to added runtime library calls.
bool NoRedZone;
- // Emit the name of the function in the .gcda files. This is redundant, as
- // the function identifier can be used to find the name from the .gcno file.
- bool FunctionNamesInData;
-
- // Emit the exit block immediately after the start block, rather than after
- // all of the function body's blocks.
- bool ExitBlockBeforeBody;
-
// Regexes separated by a semi-colon to filter the files to instrument.
std::string Filter;
@@ -99,6 +88,8 @@ ModulePass *createPGOIndirectCallPromotionLegacyPass(bool InLTO = false,
bool SamplePGO = false);
FunctionPass *createPGOMemOPSizeOptLegacyPass();
+ModulePass *createCGProfileLegacyPass();
+
// The pgo-specific indirect call promotion function declared below is used by
// the pgo-driven indirect call promotion and sample profile passes. It's a
// wrapper around llvm::promoteCall, et al. that additionally computes !prof
@@ -106,7 +97,7 @@ FunctionPass *createPGOMemOPSizeOptLegacyPass();
// generic utilities.
namespace pgo {
-// Helper function that transforms Inst (either an indirect-call instruction, or
+// Helper function that transforms CB (either an indirect-call instruction, or
// an invoke instruction , to a conditional call to F. This is like:
// if (Inst.CalledValue == F)
// F(...);
@@ -119,10 +110,9 @@ namespace pgo {
// If \p AttachProfToDirectCall is true, a prof metadata is attached to the
// new direct call to contain \p Count.
// Returns the promoted direct call instruction.
-Instruction *promoteIndirectCall(Instruction *Inst, Function *F, uint64_t Count,
- uint64_t TotalCount,
- bool AttachProfToDirectCall,
- OptimizationRemarkEmitter *ORE);
+CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count,
+ uint64_t TotalCount, bool AttachProfToDirectCall,
+ OptimizationRemarkEmitter *ORE);
} // namespace pgo
/// Options for the frontend instrumentation based profiling pass.
@@ -174,6 +164,7 @@ struct SanitizerCoverageOptions {
bool TracePC = false;
bool TracePCGuard = false;
bool Inline8bitCounters = false;
+ bool InlineBoolFlag = false;
bool PCTable = false;
bool NoPrune = false;
bool StackDepth = false;
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
index 40007a9b8c53..fea6064042ae 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -39,7 +39,7 @@ public:
LocationMetadata SourceLoc;
StringRef Name;
bool IsDynInit = false;
- bool IsBlacklisted = false;
+ bool IsExcluded = false;
Entry() = default;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
new file mode 100644
index 000000000000..7da0bf8c441f
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizerCommon.h
@@ -0,0 +1,49 @@
+//===--------- Definition of the AddressSanitizer class ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares common infrastructure for AddressSanitizer and
+// HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H
+
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Module.h"
+
+namespace llvm {
+
+class InterestingMemoryOperand {
+public:
+ Use *PtrUse;
+ bool IsWrite;
+ Type *OpType;
+ uint64_t TypeSize;
+ MaybeAlign Alignment;
+ // The mask Value, if we're looking at a masked load/store.
+ Value *MaybeMask;
+
+ InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
+ class Type *OpType, MaybeAlign Alignment,
+ Value *MaybeMask = nullptr)
+ : IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
+ MaybeMask(MaybeMask) {
+ const DataLayout &DL = I->getModule()->getDataLayout();
+ TypeSize = DL.getTypeStoreSizeInBits(OpType);
+ PtrUse = &I->getOperandUse(OperandNo);
+ }
+
+ Instruction *getInsn() { return cast<Instruction>(PtrUse->getUser()); }
+
+ Value *getPtr() { return PtrUse->get(); }
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/CGProfile.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/CGProfile.h
index 28fd3804dec9..4cb45fd42f80 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/CGProfile.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/CGProfile.h
@@ -19,11 +19,6 @@ namespace llvm {
class CGProfilePass : public PassInfoMixin<CGProfilePass> {
public:
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-
-private:
- void addModuleFlags(
- Module &M,
- MapVector<std::pair<Function *, Function *>, uint64_t> &Counts) const;
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
index 2e0fae527b15..263d3b629589 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/InstrProfiling.h
@@ -82,6 +82,9 @@ private:
/// Register-promote counter loads and stores in loops.
void promoteCounterLoadStores(Function *F);
+ /// Returns true if relocating counters at runtime is enabled.
+ bool isRuntimeCounterRelocationEnabled() const;
+
/// Returns true if profile counter update register promotion is enabled.
bool isCounterPromotionEnabled() const;
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
index 85a43ff86f2e..999086a29f87 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Instrumentation/SanitizerCoverage.h
@@ -18,6 +18,8 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Transforms/Instrumentation.h"
namespace llvm {
@@ -30,17 +32,34 @@ class ModuleSanitizerCoveragePass
: public PassInfoMixin<ModuleSanitizerCoveragePass> {
public:
explicit ModuleSanitizerCoveragePass(
- SanitizerCoverageOptions Options = SanitizerCoverageOptions())
- : Options(Options) {}
+ SanitizerCoverageOptions Options = SanitizerCoverageOptions(),
+ const std::vector<std::string> &AllowlistFiles =
+ std::vector<std::string>(),
+ const std::vector<std::string> &BlocklistFiles =
+ std::vector<std::string>())
+ : Options(Options) {
+ if (AllowlistFiles.size() > 0)
+ Allowlist = SpecialCaseList::createOrDie(AllowlistFiles,
+ *vfs::getRealFileSystem());
+ if (BlocklistFiles.size() > 0)
+ Blocklist = SpecialCaseList::createOrDie(BlocklistFiles,
+ *vfs::getRealFileSystem());
+ }
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
private:
SanitizerCoverageOptions Options;
+
+ std::unique_ptr<SpecialCaseList> Allowlist;
+ std::unique_ptr<SpecialCaseList> Blocklist;
};
// Insert SanitizerCoverage instrumentation.
ModulePass *createModuleSanitizerCoverageLegacyPassPass(
- const SanitizerCoverageOptions &Options = SanitizerCoverageOptions());
+ const SanitizerCoverageOptions &Options = SanitizerCoverageOptions(),
+ const std::vector<std::string> &AllowlistFiles = std::vector<std::string>(),
+ const std::vector<std::string> &BlocklistFiles =
+ std::vector<std::string>());
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar.h
index 1f2842836303..a1aacec76979 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar.h
@@ -22,10 +22,6 @@ class Function;
class FunctionPass;
class ModulePass;
class Pass;
-class GetElementPtrInst;
-class PassInfo;
-class TargetLowering;
-class TargetMachine;
//===----------------------------------------------------------------------===//
//
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
index fb1687e1ac5d..10b6e1c6a21b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/AlignmentFromAssumptions.h
@@ -17,13 +17,15 @@
#ifndef LLVM_TRANSFORMS_SCALAR_ALIGNMENTFROMASSUMPTIONS_H
#define LLVM_TRANSFORMS_SCALAR_ALIGNMENTFROMASSUMPTIONS_H
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class AssumptionCache;
+class DominatorTree;
+class ScalarEvolution;
+class SCEV;
+
struct AlignmentFromAssumptionsPass
: public PassInfoMixin<AlignmentFromAssumptionsPass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -35,9 +37,9 @@ struct AlignmentFromAssumptionsPass
ScalarEvolution *SE = nullptr;
DominatorTree *DT = nullptr;
- bool extractAlignmentInfo(CallInst *I, Value *&AAPtr, const SCEV *&AlignSCEV,
- const SCEV *&OffSCEV);
- bool processAssumption(CallInst *I);
+ bool extractAlignmentInfo(CallInst *I, unsigned Idx, Value *&AAPtr,
+ const SCEV *&AlignSCEV, const SCEV *&OffSCEV);
+ bool processAssumption(CallInst *I, unsigned Idx);
};
}
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Float2Int.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Float2Int.h
index f04b98a19d82..5fb47af6f795 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Float2Int.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Float2Int.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/EquivalenceClasses.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
@@ -30,20 +31,19 @@ public:
bool runImpl(Function &F, const DominatorTree &DT);
private:
- void findRoots(Function &F, const DominatorTree &DT,
- SmallPtrSet<Instruction *, 8> &Roots);
+ void findRoots(Function &F, const DominatorTree &DT);
void seen(Instruction *I, ConstantRange R);
ConstantRange badRange();
ConstantRange unknownRange();
ConstantRange validateRange(ConstantRange R);
- void walkBackwards(const SmallPtrSetImpl<Instruction *> &Roots);
+ void walkBackwards();
void walkForwards();
bool validateAndTransform();
Value *convert(Instruction *I, Type *ToTy);
void cleanup();
MapVector<Instruction *, ConstantRange> SeenInsts;
- SmallPtrSet<Instruction *, 8> Roots;
+ SmallSetVector<Instruction *, 8> Roots;
EquivalenceClasses<Instruction *> ECs;
MapVector<Instruction *, Value *> ConvertedInsts;
LLVMContext *Ctx;
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h
index 5a3d30de16a3..f2818c6b792e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVN.h
@@ -20,7 +20,6 @@
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/InstructionPrecedenceTracking.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/IR/Dominators.h"
@@ -35,6 +34,7 @@
namespace llvm {
+class AAResults;
class AssumptionCache;
class BasicBlock;
class BranchInst;
@@ -61,14 +61,57 @@ class GVNLegacyPass;
} // end namespace gvn
+/// A set of parameters to control various transforms performed by GVN pass.
+// Each of the optional boolean parameters can be set to:
+/// true - enabling the transformation.
+/// false - disabling the transformation.
+/// None - relying on a global default.
+/// Intended use is to create a default object, modify parameters with
+/// additional setters and then pass it to GVN.
+struct GVNOptions {
+ Optional<bool> AllowPRE = None;
+ Optional<bool> AllowLoadPRE = None;
+ Optional<bool> AllowLoadInLoopPRE = None;
+ Optional<bool> AllowMemDep = None;
+
+ GVNOptions() = default;
+
+ /// Enables or disables PRE in GVN.
+ GVNOptions &setPRE(bool PRE) {
+ AllowPRE = PRE;
+ return *this;
+ }
+
+ /// Enables or disables PRE of loads in GVN.
+ GVNOptions &setLoadPRE(bool LoadPRE) {
+ AllowLoadPRE = LoadPRE;
+ return *this;
+ }
+
+ GVNOptions &setLoadInLoopPRE(bool LoadInLoopPRE) {
+ AllowLoadInLoopPRE = LoadInLoopPRE;
+ return *this;
+ }
+
+ /// Enables or disables use of MemDepAnalysis.
+ GVNOptions &setMemDep(bool MemDep) {
+ AllowMemDep = MemDep;
+ return *this;
+ }
+};
+
/// The core GVN pass object.
///
/// FIXME: We should have a good summary of the GVN algorithm implemented by
/// this particular pass here.
class GVN : public PassInfoMixin<GVN> {
+ GVNOptions Options;
+
public:
struct Expression;
+ GVN(GVNOptions Options = {}) : Options(Options) {}
+
/// Run the pass over the function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
@@ -80,9 +123,14 @@ public:
}
DominatorTree &getDominatorTree() const { return *DT; }
- AliasAnalysis *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
+ AAResults *getAliasAnalysis() const { return VN.getAliasAnalysis(); }
MemoryDependenceResults &getMemDep() const { return *MD; }
+ bool isPREEnabled() const;
+ bool isLoadPREEnabled() const;
+ bool isLoadInLoopPREEnabled() const;
+ bool isMemDepEnabled() const;
+
/// This class holds the mapping between values and value numbers. It is used
/// as an efficient mechanism to determine the expression-wise equivalence of
/// two values.
@@ -107,7 +155,7 @@ public:
DenseMap<std::pair<uint32_t, const BasicBlock *>, uint32_t>;
PhiTranslateMap PhiTranslateTable;
- AliasAnalysis *AA = nullptr;
+ AAResults *AA = nullptr;
MemoryDependenceResults *MD = nullptr;
DominatorTree *DT = nullptr;
@@ -143,8 +191,8 @@ public:
void add(Value *V, uint32_t num);
void clear();
void erase(Value *v);
- void setAliasAnalysis(AliasAnalysis *A) { AA = A; }
- AliasAnalysis *getAliasAnalysis() const { return AA; }
+ void setAliasAnalysis(AAResults *A) { AA = A; }
+ AAResults *getAliasAnalysis() const { return AA; }
void setMemDep(MemoryDependenceResults *M) { MD = M; }
void setDomTree(DominatorTree *D) { DT = D; }
uint32_t getNextUnusedValueNumber() { return nextValueNumber; }
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVNExpression.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
index 1600d1af3242..c4a04877a1ff 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/GVNExpression.h
@@ -323,7 +323,6 @@ public:
class LoadExpression final : public MemoryExpression {
private:
LoadInst *Load;
- MaybeAlign Alignment;
public:
LoadExpression(unsigned NumOperands, LoadInst *L,
@@ -332,10 +331,7 @@ public:
LoadExpression(enum ExpressionType EType, unsigned NumOperands, LoadInst *L,
const MemoryAccess *MemoryLeader)
- : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {
- if (L)
- Alignment = MaybeAlign(L->getAlignment());
- }
+ : MemoryExpression(NumOperands, EType, MemoryLeader), Load(L) {}
LoadExpression() = delete;
LoadExpression(const LoadExpression &) = delete;
@@ -349,9 +345,6 @@ public:
LoadInst *getLoadInst() const { return Load; }
void setLoadInst(LoadInst *L) { Load = L; }
- MaybeAlign getAlignment() const { return Alignment; }
- void setAlignment(MaybeAlign Align) { Alignment = Align; }
-
bool equals(const Expression &Other) const override;
bool exactlyEquals(const Expression &Other) const override {
return Expression::exactlyEquals(Other) &&
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h
index b1e700714e51..11fb80e49486 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/InductiveRangeCheckElimination.h
@@ -15,14 +15,12 @@
#define LLVM_TRANSFORMS_SCALAR_INDUCTIVERANGECHECKELIMINATION_H
#include "llvm/IR/PassManager.h"
-#include "llvm/Transforms/Scalar/LoopPassManager.h"
namespace llvm {
class IRCEPass : public PassInfoMixin<IRCEPass> {
public:
- PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
- LoopStandardAnalysisResults &AR, LPMUpdater &U);
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
};
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/JumpThreading.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
index a8beb8ca6e05..327bf6d00c47 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/JumpThreading.h
@@ -90,6 +90,7 @@ class JumpThreadingPass : public PassInfoMixin<JumpThreadingPass> {
#endif
unsigned BBDupThreshold;
+ unsigned DefaultBBDupThreshold;
public:
JumpThreadingPass(int T = -1);
@@ -127,18 +128,22 @@ public:
bool ComputeValueKnownInPredecessorsImpl(
Value *V, BasicBlock *BB, jumpthreading::PredValueInfo &Result,
jumpthreading::ConstantPreference Preference,
- DenseSet<std::pair<Value *, BasicBlock *>> &RecursionSet,
- Instruction *CxtI = nullptr);
+ DenseSet<Value *> &RecursionSet, Instruction *CxtI = nullptr);
bool
ComputeValueKnownInPredecessors(Value *V, BasicBlock *BB,
jumpthreading::PredValueInfo &Result,
jumpthreading::ConstantPreference Preference,
Instruction *CxtI = nullptr) {
- DenseSet<std::pair<Value *, BasicBlock *>> RecursionSet;
+ DenseSet<Value *> RecursionSet;
return ComputeValueKnownInPredecessorsImpl(V, BB, Result, Preference,
RecursionSet, CxtI);
}
+ Constant *EvaluateOnPredecessorEdge(BasicBlock *BB, BasicBlock *PredPredBB,
+ Value *cond);
+ bool MaybeThreadThroughTwoBasicBlocks(BasicBlock *BB, Value *Cond);
+ void ThreadThroughTwoBasicBlocks(BasicBlock *PredPredBB, BasicBlock *PredBB,
+ BasicBlock *BB, BasicBlock *SuccBB);
bool ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
jumpthreading::ConstantPreference Preference,
Instruction *CxtI = nullptr);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
index aed764855b2e..9b2f0fcab95b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h
@@ -44,6 +44,7 @@
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/LoopAnalysisManager.h"
#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/MemorySSA.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
@@ -52,6 +53,7 @@
#include "llvm/IR/PassManager.h"
#include "llvm/Transforms/Utils/LCSSA.h"
#include "llvm/Transforms/Utils/LoopSimplify.h"
+#include "llvm/Transforms/Utils/LoopUtils.h"
namespace llvm {
@@ -101,40 +103,6 @@ using RequireAnalysisLoopPass =
RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
LoopStandardAnalysisResults &, LPMUpdater &>;
-namespace internal {
-/// Helper to implement appending of loops onto a worklist.
-///
-/// We want to process loops in postorder, but the worklist is a LIFO data
-/// structure, so we append to it in *reverse* postorder.
-///
-/// For trees, a preorder traversal is a viable reverse postorder, so we
-/// actually append using a preorder walk algorithm.
-template <typename RangeT>
-inline void appendLoopsToWorklist(RangeT &&Loops,
- SmallPriorityWorklist<Loop *, 4> &Worklist) {
- // We use an internal worklist to build up the preorder traversal without
- // recursion.
- SmallVector<Loop *, 4> PreOrderLoops, PreOrderWorklist;
-
- // We walk the initial sequence of loops in reverse because we generally want
- // to visit defs before uses and the worklist is LIFO.
- for (Loop *RootL : reverse(Loops)) {
- assert(PreOrderLoops.empty() && "Must start with an empty preorder walk.");
- assert(PreOrderWorklist.empty() &&
- "Must start with an empty preorder walk worklist.");
- PreOrderWorklist.push_back(RootL);
- do {
- Loop *L = PreOrderWorklist.pop_back_val();
- PreOrderWorklist.append(L->begin(), L->end());
- PreOrderLoops.push_back(L);
- } while (!PreOrderWorklist.empty());
-
- Worklist.insert(std::move(PreOrderLoops));
- PreOrderLoops.clear();
- }
-}
-}
-
template <typename LoopPassT> class FunctionToLoopPassAdaptor;
/// This class provides an interface for updating the loop pass manager based
@@ -190,7 +158,7 @@ public:
"the current loop!");
#endif
- internal::appendLoopsToWorklist(NewChildLoops, Worklist);
+ appendLoopsToWorklist(NewChildLoops, Worklist);
// Also skip further processing of the current loop--it will be revisited
// after all of its newly added children are accounted for.
@@ -210,7 +178,7 @@ public:
"All of the new loops must be siblings of the current loop!");
#endif
- internal::appendLoopsToWorklist(NewSibLoops, Worklist);
+ appendLoopsToWorklist(NewSibLoops, Worklist);
// No need to skip the current loop or revisit it, as sibling loops
// shouldn't impact anything.
@@ -324,13 +292,9 @@ public:
// update them when they mutate the loop nest structure.
LPMUpdater Updater(Worklist, LAM);
- // Add the loop nests in the reverse order of LoopInfo. For some reason,
- // they are stored in RPO w.r.t. the control flow graph in LoopInfo. For
- // the purpose of unrolling, loop deletion, and LICM, we largely want to
- // work forward across the CFG so that we visit defs before uses and can
- // propagate simplifications from one loop nest into the next.
- // FIXME: Consider changing the order in LoopInfo.
- internal::appendLoopsToWorklist(reverse(LI), Worklist);
+ // Add the loop nests in the reverse order of LoopInfo. See method
+ // declaration.
+ appendLoopsToWorklist(LI, Worklist);
do {
Loop *L = Worklist.pop_back_val();
@@ -353,7 +317,12 @@ public:
// false).
if (!PI.runBeforePass<Loop>(Pass, *L))
continue;
- PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
+
+ PreservedAnalyses PassPA;
+ {
+ TimeTraceScope TimeScope(Pass.name());
+ PassPA = Pass.run(*L, LAM, LAR, Updater);
+ }
// Do not pass deleted Loop into the instrumentation.
if (Updater.skipCurrentLoop())
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h
index 233963528595..bd83a6a0cca4 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/LoopUnrollAndJamPass.h
@@ -9,12 +9,9 @@
#ifndef LLVM_TRANSFORMS_SCALAR_LOOPUNROLLANDJAMPASS_H
#define LLVM_TRANSFORMS_SCALAR_LOOPUNROLLANDJAMPASS_H
-#include "llvm/Analysis/LoopAnalysisManager.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
-
class Function;
/// A simple loop rotation transformation.
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
index 5386f58b2b82..8fc6c23e6944 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/MemCpyOptimizer.h
@@ -16,7 +16,6 @@
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/PassManager.h"
#include <cstdint>
#include <functional>
@@ -59,14 +58,14 @@ private:
// Helper functions
bool processStore(StoreInst *SI, BasicBlock::iterator &BBI);
bool processMemSet(MemSetInst *SI, BasicBlock::iterator &BBI);
- bool processMemCpy(MemCpyInst *M);
+ bool processMemCpy(MemCpyInst *M, BasicBlock::iterator &BBI);
bool processMemMove(MemMoveInst *M);
bool performCallSlotOptzn(Instruction *cpy, Value *cpyDst, Value *cpySrc,
- uint64_t cpyLen, unsigned cpyAlign, CallInst *C);
+ uint64_t cpyLen, Align cpyAlign, CallInst *C);
bool processMemCpyMemCpyDependence(MemCpyInst *M, MemCpyInst *MDep);
- bool processMemSetMemCpyDependence(MemCpyInst *M, MemSetInst *MDep);
- bool performMemCpyToMemSetOptzn(MemCpyInst *M, MemSetInst *MDep);
- bool processByValArgument(CallSite CS, unsigned ArgNo);
+ bool processMemSetMemCpyDependence(MemCpyInst *MemCpy, MemSetInst *MemSet);
+ bool performMemCpyToMemSetOptzn(MemCpyInst *MemCpy, MemSetInst *MemSet);
+ bool processByValArgument(CallBase &CB, unsigned ArgNo);
Instruction *tryMergingIntoMemset(Instruction *I, Value *StartPtr,
Value *ByteVal);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Reassociate.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Reassociate.h
index d5b175eff0e6..28794d27325a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Reassociate.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Scalar/Reassociate.h
@@ -25,7 +25,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/SetVector.h"
-#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ValueHandle.h"
#include <deque>
@@ -37,6 +36,7 @@ class BasicBlock;
class BinaryOperator;
class Function;
class Instruction;
+class IRBuilderBase;
class Value;
/// A private "module" namespace for types and utilities used by Reassociate.
@@ -114,7 +114,7 @@ private:
bool CombineXorOpnd(Instruction *I, reassociate::XorOpnd *Opnd1,
reassociate::XorOpnd *Opnd2, APInt &ConstOpnd,
Value *&Res);
- Value *buildMinimalMultiplyDAG(IRBuilder<> &Builder,
+ Value *buildMinimalMultiplyDAG(IRBuilderBase &Builder,
SmallVectorImpl<reassociate::Factor> &Factors);
Value *OptimizeMul(BinaryOperator *I,
SmallVectorImpl<reassociate::ValueEntry> &Ops);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils.h
index bb31646ce462..75edefac1cbd 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils.h
@@ -26,6 +26,12 @@ class Pass;
ModulePass *createMetaRenamerPass();
//===----------------------------------------------------------------------===//
+// createUniqueInternalLinkageNamesPass - Make internal linkage symbol names
+// unique.
+//
+ModulePass *createUniqueInternalLinkageNamesPass();
+
+//===----------------------------------------------------------------------===//
//
// LowerInvoke - This pass removes invoke instructions, converting them to call
// instructions.
@@ -126,6 +132,35 @@ FunctionPass *createControlHeightReductionLegacyPass();
// scalar-to-vector mappings from the TargetLibraryInfo.
//
FunctionPass *createInjectTLIMappingsLegacyPass();
-}
+
+//===----------------------------------------------------------------------===//
+//
+// UnifyLoopExits - For each loop, creates a new block N such that all exiting
+// blocks branch to N, and then N distributes control flow to all the original
+// exit blocks.
+//
+FunctionPass *createUnifyLoopExitsPass();
+
+//===----------------------------------------------------------------------===//
+//
+// FixIrreducible - Convert each SCC with irreducible control-flow
+// into a natural loop.
+//
+FunctionPass *createFixIrreduciblePass();
+
+//===----------------------------------------------------------------------===//
+//
+// AssumeSimplify - remove redundant assumes and merge assumes in the same
+// BasicBlock when possible.
+//
+FunctionPass *createAssumeSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CanonicalizeFreezeInLoops - Canonicalize freeze instructions in loops so they
+// don't block SCEV.
+//
+Pass *createCanonicalizeFreezeInLoopsPass();
+} // namespace llvm
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AMDGPUEmitPrintf.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AMDGPUEmitPrintf.h
new file mode 100644
index 000000000000..65dbf47e9bbc
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AMDGPUEmitPrintf.h
@@ -0,0 +1,25 @@
+//===- AMDGPUEmitPrintf.h ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utility function to lower a printf call into a series of device
+// library calls on the AMDGPU target.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_AMDGPUEMITPRINTF_H
+#define LLVM_TRANSFORMS_UTILS_AMDGPUEMITPRINTF_H
+
+#include "llvm/IR/IRBuilder.h"
+
+namespace llvm {
+
+Value *emitAMDGPUPrintfCall(IRBuilder<> &Builder, ArrayRef<Value *> Args);
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_AMDGPUEMITPRINTF_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
new file mode 100644
index 000000000000..8e0098296f38
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/AssumeBundleBuilder.h
@@ -0,0 +1,60 @@
+//===- AssumeBundleBuilder.h - utils to build assume bundles ----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contain tools to preserve informations. They should be used before
+// performing a transformation that may move and delete instructions as those
+// transformation may destroy or worsen information that can be derived from the
+// IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEBUILDER_H
+#define LLVM_TRANSFORMS_UTILS_ASSUMEBUNDLEBUILDER_H
+
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class IntrinsicInst;
+class AssumptionCache;
+class DominatorTree;
+
+/// Build a call to llvm.assume to preserve informations that can be derived
+/// from the given instruction.
+/// If no information derived from \p I, this call returns null.
+/// The returned instruction is not inserted anywhere.
+IntrinsicInst *buildAssumeFromInst(Instruction *I);
+
+/// Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert
+/// if before I. This is usually what need to be done to salvage the knowledge
+/// contained in the instruction I.
+/// The AssumptionCache must be provided if it is available or the cache may
+/// become silently be invalid.
+/// The DominatorTree can optionally be provided to enable cross-block
+/// reasoning.
+void salvageKnowledge(Instruction *I, AssumptionCache *AC = nullptr,
+ DominatorTree *DT = nullptr);
+
+/// This pass attempts to minimize the number of assume without loosing any
+/// information.
+struct AssumeSimplifyPass : public PassInfoMixin<AssumeSimplifyPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+FunctionPass *createAssumeSimplifyPass();
+
+/// This pass will try to build an llvm.assume for every instruction in the
+/// function. Its main purpose is testing.
+struct AssumeBuilderPass : public PassInfoMixin<AssumeBuilderPass> {
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
index dec8447c9f52..0a63654feb98 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -17,7 +17,9 @@
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/Analysis/DomTreeUpdater.h"
+#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/InstrTypes.h"
@@ -79,7 +81,8 @@ void FoldSingleEntryPHINodes(BasicBlock *BB,
/// recursively delete any operands that become dead as a result. This includes
/// tracing the def-use list from the PHI to see if it is ultimately unused or
/// if it reaches an unused cycle. Return true if any PHIs were deleted.
-bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr);
+bool DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr);
/// Attempts to merge a block into its predecessor, if possible. The return
/// value indicates success or failure.
@@ -94,6 +97,17 @@ bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU = nullptr,
MemoryDependenceResults *MemDep = nullptr,
bool PredecessorWithTwoSuccessors = false);
+/// Merge block(s) sucessors, if possible. Return true if at least two
+/// of the blocks were merged together.
+/// In order to merge, each block must be terminated by an unconditional
+/// branch. If L is provided, then the blocks merged into their predecessors
+/// must be in L. In addition, This utility calls on another utility:
+/// MergeBlockIntoPredecessor. Blocks are successfully merged when the call to
+/// MergeBlockIntoPredecessor returns true.
+bool MergeBlockSuccessorsIntoGivenBlocks(
+ SmallPtrSetImpl<BasicBlock *> &MergeBlocks, Loop *L = nullptr,
+ DomTreeUpdater *DTU = nullptr, LoopInfo *LI = nullptr);
+
/// Try to remove redundant dbg.value instructions from given basic block.
/// Returns true if at least one instruction was removed.
bool RemoveRedundantDbgInstrs(BasicBlock *BB);
@@ -127,6 +141,10 @@ struct CriticalEdgeSplittingOptions {
bool KeepOneInputPHIs = false;
bool PreserveLCSSA = false;
bool IgnoreUnreachableDests = false;
+ /// SplitCriticalEdge is guaranteed to preserve loop-simplify form if LI is
+ /// provided. If it cannot be preserved, no splitting will take place. If it
+ /// is not set, preserve loop-simplify form if possible.
+ bool PreserveLoopSimplify = true;
CriticalEdgeSplittingOptions(DominatorTree *DT = nullptr,
LoopInfo *LI = nullptr,
@@ -153,6 +171,11 @@ struct CriticalEdgeSplittingOptions {
IgnoreUnreachableDests = true;
return *this;
}
+
+ CriticalEdgeSplittingOptions &unsetPreserveLoopSimplify() {
+ PreserveLoopSimplify = false;
+ return *this;
+ }
};
/// If this edge is a critical edge, insert a new node to split the critical
@@ -362,6 +385,81 @@ bool SplitIndirectBrCriticalEdges(Function &F,
BranchProbabilityInfo *BPI = nullptr,
BlockFrequencyInfo *BFI = nullptr);
+/// Given a set of incoming and outgoing blocks, create a "hub" such that every
+/// edge from an incoming block InBB to an outgoing block OutBB is now split
+/// into two edges, one from InBB to the hub and another from the hub to
+/// OutBB. The hub consists of a series of guard blocks, one for each outgoing
+/// block. Each guard block conditionally branches to the corresponding outgoing
+/// block, or the next guard block in the chain. These guard blocks are returned
+/// in the argument vector.
+///
+/// Since the control flow edges from InBB to OutBB have now been replaced, the
+/// function also updates any PHINodes in OutBB. For each such PHINode, the
+/// operands corresponding to incoming blocks are moved to a new PHINode in the
+/// hub, and the hub is made an operand of the original PHINode.
+///
+/// Input CFG:
+/// ----------
+///
+/// Def
+/// |
+/// v
+/// In1 In2
+/// | |
+/// | |
+/// v v
+/// Foo ---> Out1 Out2
+/// |
+/// v
+/// Use
+///
+///
+/// Create hub: Incoming = {In1, In2}, Outgoing = {Out1, Out2}
+/// ----------------------------------------------------------
+///
+/// Def
+/// |
+/// v
+/// In1 In2 Foo
+/// | Hub | |
+/// | + - - | - - + |
+/// | ' v ' V
+/// +------> Guard1 -----> Out1
+/// ' | '
+/// ' v '
+/// ' Guard2 -----> Out2
+/// ' ' |
+/// + - - - - - + |
+/// v
+/// Use
+///
+/// Limitations:
+/// -----------
+/// 1. This assumes that all terminators in the CFG are direct branches (the
+/// "br" instruction). The presence of any other control flow such as
+/// indirectbr, switch or callbr will cause an assert.
+///
+/// 2. The updates to the PHINodes are not sufficient to restore SSA
+/// form. Consider a definition Def, its use Use, incoming block In2 and
+/// outgoing block Out2, such that:
+/// a. In2 is reachable from D or contains D.
+/// b. U is reachable from Out2 or is contained in Out2.
+/// c. U is not a PHINode if U is contained in Out2.
+///
+/// Clearly, Def dominates Out2 since the program is valid SSA. But when the
+/// hub is introduced, there is a new path through the hub along which Use is
+/// reachable from entry without passing through Def, and SSA is no longer
+/// valid. To fix this, we need to look at all the blocks post-dominated by
+/// the hub on the one hand, and dominated by Out2 on the other. This is left
+/// for the caller to accomplish, since each specific use of this function
+/// may have additional information which simplifies this fixup. For example,
+/// see restoreSSA() in the UnifyLoopExits pass.
+BasicBlock *CreateControlFlowHub(DomTreeUpdater *DTU,
+ SmallVectorImpl<BasicBlock *> &GuardBlocks,
+ const SetVector<BasicBlock *> &Predecessors,
+ const SetVector<BasicBlock *> &Successors,
+ const StringRef Prefix);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
index 3d15b2a7bf2a..90517e806e02 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -15,12 +15,11 @@
#define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/IRBuilder.h"
namespace llvm {
class Value;
class DataLayout;
- class TargetLibraryInfo;
+ class IRBuilderBase;
/// Analyze the name and prototype of the given function and set any
/// applicable attributes.
@@ -42,123 +41,123 @@ namespace llvm {
LibFunc LongDoubleFn);
/// Return V if it is an i8*, otherwise cast it to i8*.
- Value *castToCStr(Value *V, IRBuilder<> &B);
+ Value *castToCStr(Value *V, IRBuilderBase &B);
/// Emit a call to the strlen function to the builder, for the specified
/// pointer. Ptr is required to be some pointer type, and the return value has
/// 'intptr_t' type.
- Value *emitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
+ Value *emitStrLen(Value *Ptr, IRBuilderBase &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// Emit a call to the strdup function to the builder, for the specified
/// pointer. Ptr is required to be some pointer type, and the return value has
/// 'i8*' type.
- Value *emitStrDup(Value *Ptr, IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ Value *emitStrDup(Value *Ptr, IRBuilderBase &B, const TargetLibraryInfo *TLI);
/// Emit a call to the strnlen function to the builder, for the specified
/// pointer. Ptr is required to be some pointer type, MaxLen must be of size_t
/// type, and the return value has 'intptr_t' type.
- Value *emitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
+ Value *emitStrNLen(Value *Ptr, Value *MaxLen, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the strchr function to the builder, for the specified
/// pointer and character. Ptr is required to be some pointer type, and the
/// return value has 'i8*' type.
- Value *emitStrChr(Value *Ptr, char C, IRBuilder<> &B,
+ Value *emitStrChr(Value *Ptr, char C, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the strncmp function to the builder.
- Value *emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ Value *emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the strcpy function to the builder, for the specified
/// pointer arguments.
- Value *emitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+ Value *emitStrCpy(Value *Dst, Value *Src, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the stpcpy function to the builder, for the specified
/// pointer arguments.
- Value *emitStpCpy(Value *Dst, Value *Src, IRBuilder<> &B,
+ Value *emitStpCpy(Value *Dst, Value *Src, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the strncpy function to the builder, for the specified
/// pointer arguments and length.
- Value *emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
+ Value *emitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the stpncpy function to the builder, for the specified
/// pointer arguments and length.
- Value *emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
+ Value *emitStpNCpy(Value *Dst, Value *Src, Value *Len, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the __memcpy_chk function to the builder. This expects that
/// the Len and ObjSize have type 'intptr_t' and Dst/Src are pointers.
Value *emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const DataLayout &DL,
+ IRBuilderBase &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// Emit a call to the memchr function. This assumes that Ptr is a pointer,
/// Val is an i32 value, and Len is an 'intptr_t' value.
- Value *emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
+ Value *emitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the memcmp function.
- Value *emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ Value *emitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the bcmp function.
- Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
+ Value *emitBCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the memccpy function.
Value *emitMemCCpy(Value *Ptr1, Value *Ptr2, Value *Val, Value *Len,
- IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ IRBuilderBase &B, const TargetLibraryInfo *TLI);
/// Emit a call to the snprintf function.
Value *emitSNPrintf(Value *Dest, Value *Size, Value *Fmt,
- ArrayRef<Value *> Args, IRBuilder<> &B,
+ ArrayRef<Value *> Args, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the sprintf function.
Value *emitSPrintf(Value *Dest, Value *Fmt, ArrayRef<Value *> VariadicArgs,
- IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ IRBuilderBase &B, const TargetLibraryInfo *TLI);
/// Emit a call to the strcat function.
- Value *emitStrCat(Value *Dest, Value *Src, IRBuilder<> &B,
+ Value *emitStrCat(Value *Dest, Value *Src, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the strlcpy function.
- Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
+ Value *emitStrLCpy(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the strlcat function.
- Value *emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
+ Value *emitStrLCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the strncat function.
- Value *emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilder<> &B,
+ Value *emitStrNCat(Value *Dest, Value *Src, Value *Size, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the vsnprintf function.
Value *emitVSNPrintf(Value *Dest, Value *Size, Value *Fmt, Value *VAList,
- IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ IRBuilderBase &B, const TargetLibraryInfo *TLI);
/// Emit a call to the vsprintf function.
- Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilder<> &B,
+ Value *emitVSPrintf(Value *Dest, Value *Fmt, Value *VAList, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
/// Emit a call to the unary function named 'Name' (e.g. 'floor'). This
/// function is known to take a single of type matching 'Op' and returns one
/// value with the same type. If 'Op' is a long double, 'l' is added as the
/// suffix of name, if 'Op' is a float, we add a 'f' suffix.
- Value *emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B,
+ Value *emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilderBase &B,
const AttributeList &Attrs);
/// Emit a call to the unary function DoubleFn, FloatFn or LongDoubleFn,
/// depending of the type of Op.
Value *emitUnaryFloatFnCall(Value *Op, const TargetLibraryInfo *TLI,
LibFunc DoubleFn, LibFunc FloatFn,
- LibFunc LongDoubleFn, IRBuilder<> &B,
+ LibFunc LongDoubleFn, IRBuilderBase &B,
const AttributeList &Attrs);
/// Emit a call to the binary function named 'Name' (e.g. 'fmin'). This
@@ -166,74 +165,44 @@ namespace llvm {
/// value with the same type. If 'Op1/Op2' are long double, 'l' is added as
/// the suffix of name, if 'Op1/Op2' are float, we add a 'f' suffix.
Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2, StringRef Name,
- IRBuilder<> &B, const AttributeList &Attrs);
+ IRBuilderBase &B, const AttributeList &Attrs);
/// Emit a call to the binary function DoubleFn, FloatFn or LongDoubleFn,
/// depending of the type of Op1.
Value *emitBinaryFloatFnCall(Value *Op1, Value *Op2,
const TargetLibraryInfo *TLI, LibFunc DoubleFn,
LibFunc FloatFn, LibFunc LongDoubleFn,
- IRBuilder<> &B, const AttributeList &Attrs);
+ IRBuilderBase &B, const AttributeList &Attrs);
/// Emit a call to the putchar function. This assumes that Char is an integer.
- Value *emitPutChar(Value *Char, IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ Value *emitPutChar(Value *Char, IRBuilderBase &B,
+ const TargetLibraryInfo *TLI);
/// Emit a call to the puts function. This assumes that Str is some pointer.
- Value *emitPutS(Value *Str, IRBuilder<> &B, const TargetLibraryInfo *TLI);
+ Value *emitPutS(Value *Str, IRBuilderBase &B, const TargetLibraryInfo *TLI);
/// Emit a call to the fputc function. This assumes that Char is an i32, and
/// File is a pointer to FILE.
- Value *emitFPutC(Value *Char, Value *File, IRBuilder<> &B,
+ Value *emitFPutC(Value *Char, Value *File, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
- /// Emit a call to the fputc_unlocked function. This assumes that Char is an
- /// i32, and File is a pointer to FILE.
- Value *emitFPutCUnlocked(Value *Char, Value *File, IRBuilder<> &B,
- const TargetLibraryInfo *TLI);
-
/// Emit a call to the fputs function. Str is required to be a pointer and
/// File is a pointer to FILE.
- Value *emitFPutS(Value *Str, Value *File, IRBuilder<> &B,
+ Value *emitFPutS(Value *Str, Value *File, IRBuilderBase &B,
const TargetLibraryInfo *TLI);
- /// Emit a call to the fputs_unlocked function. Str is required to be a
- /// pointer and File is a pointer to FILE.
- Value *emitFPutSUnlocked(Value *Str, Value *File, IRBuilder<> &B,
- const TargetLibraryInfo *TLI);
-
/// Emit a call to the fwrite function. This assumes that Ptr is a pointer,
/// Size is an 'intptr_t', and File is a pointer to FILE.
- Value *emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
+ Value *emitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilderBase &B,
const DataLayout &DL, const TargetLibraryInfo *TLI);
/// Emit a call to the malloc function.
- Value *emitMalloc(Value *Num, IRBuilder<> &B, const DataLayout &DL,
+ Value *emitMalloc(Value *Num, IRBuilderBase &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// Emit a call to the calloc function.
Value *emitCalloc(Value *Num, Value *Size, const AttributeList &Attrs,
- IRBuilder<> &B, const TargetLibraryInfo &TLI);
-
- /// Emit a call to the fwrite_unlocked function. This assumes that Ptr is a
- /// pointer, Size is an 'intptr_t', N is nmemb and File is a pointer to FILE.
- Value *emitFWriteUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
- IRBuilder<> &B, const DataLayout &DL,
- const TargetLibraryInfo *TLI);
-
- /// Emit a call to the fgetc_unlocked function. File is a pointer to FILE.
- Value *emitFGetCUnlocked(Value *File, IRBuilder<> &B,
- const TargetLibraryInfo *TLI);
-
- /// Emit a call to the fgets_unlocked function. Str is required to be a
- /// pointer, Size is an i32 and File is a pointer to FILE.
- Value *emitFGetSUnlocked(Value *Str, Value *Size, Value *File, IRBuilder<> &B,
- const TargetLibraryInfo *TLI);
-
- /// Emit a call to the fread_unlocked function. This assumes that Ptr is a
- /// pointer, Size is an 'intptr_t', N is nmemb and File is a pointer to FILE.
- Value *emitFReadUnlocked(Value *Ptr, Value *Size, Value *N, Value *File,
- IRBuilder<> &B, const DataLayout &DL,
- const TargetLibraryInfo *TLI);
+ IRBuilderBase &B, const TargetLibraryInfo &TLI);
}
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h
new file mode 100644
index 000000000000..22954b469186
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallGraphUpdater.h
@@ -0,0 +1,109 @@
+//===- CallGraphUpdater.h - A (lazy) call graph update helper ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file provides interfaces used to manipulate a call graph, regardless
+/// if it is a "old style" CallGraph or an "new style" LazyCallGraph.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CALLGRAPHUPDATER_H
+#define LLVM_TRANSFORMS_UTILS_CALLGRAPHUPDATER_H
+
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
+#include "llvm/Analysis/LazyCallGraph.h"
+
+namespace llvm {
+
+/// Wrapper to unify "old style" CallGraph and "new style" LazyCallGraph. This
+/// simplifies the interface and the call sites, e.g., new and old pass manager
+/// passes can share the same code.
+class CallGraphUpdater {
+ /// Containers for functions which we did replace or want to delete when
+ /// `finalize` is called. This can happen explicitly or as part of the
+ /// destructor. Dead functions in comdat sections are tracked separately
+ /// because a function with discardable linakage in a COMDAT should only
+ /// be dropped if the entire COMDAT is dropped, see git ac07703842cf.
+ ///{
+ SmallPtrSet<Function *, 16> ReplacedFunctions;
+ SmallVector<Function *, 16> DeadFunctions;
+ SmallVector<Function *, 16> DeadFunctionsInComdats;
+ ///}
+
+ /// Old PM variables
+ ///{
+ CallGraph *CG = nullptr;
+ CallGraphSCC *CGSCC = nullptr;
+ ///}
+
+ /// New PM variables
+ ///{
+ LazyCallGraph *LCG = nullptr;
+ LazyCallGraph::SCC *SCC = nullptr;
+ CGSCCAnalysisManager *AM = nullptr;
+ CGSCCUpdateResult *UR = nullptr;
+ FunctionAnalysisManager *FAM = nullptr;
+ ///}
+
+public:
+ CallGraphUpdater() {}
+ ~CallGraphUpdater() { finalize(); }
+
+ /// Initializers for usage outside of a CGSCC pass, inside a CGSCC pass in
+ /// the old and new pass manager (PM).
+ ///{
+ void initialize(CallGraph &CG, CallGraphSCC &SCC) {
+ this->CG = &CG;
+ this->CGSCC = &SCC;
+ }
+ void initialize(LazyCallGraph &LCG, LazyCallGraph::SCC &SCC,
+ CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR) {
+ this->LCG = &LCG;
+ this->SCC = &SCC;
+ this->AM = &AM;
+ this->UR = &UR;
+ FAM =
+ &AM.getResult<FunctionAnalysisManagerCGSCCProxy>(SCC, LCG).getManager();
+ }
+ ///}
+
+ /// Finalizer that will trigger actions like function removal from the CG.
+ bool finalize();
+
+ /// Remove \p Fn from the call graph.
+ void removeFunction(Function &Fn);
+
+ /// After an CGSCC pass changes a function in ways that affect the call
+ /// graph, this method can be called to update it.
+ void reanalyzeFunction(Function &Fn);
+
+ /// If a new function was created by outlining, this method can be called
+ /// to update the call graph for the new function. Note that the old one
+ /// still needs to be re-analyzed or manually updated.
+ void registerOutlinedFunction(Function &NewFn);
+
+ /// Replace \p OldFn in the call graph (and SCC) with \p NewFn. The uses
+ /// outside the call graph and the function \p OldFn are not modified.
+ /// Note that \p OldFn is also removed from the call graph
+ /// (\see removeFunction).
+ void replaceFunctionWith(Function &OldFn, Function &NewFn);
+
+ /// Remove the call site \p CS from the call graph.
+ void removeCallSite(CallBase &CS);
+
+ /// Replace \p OldCS with the new call site \p NewCS.
+ /// \return True if the replacement was successful, otherwise False. In the
+ /// latter case the parent function of \p OldCB needs to be re-analyzed.
+ bool replaceCallSite(CallBase &OldCS, CallBase &NewCS);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_CALLGRAPHUPDATER_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
index d9d171c6d8bd..daa88981d3bf 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CallPromotionUtils.h
@@ -14,9 +14,11 @@
#ifndef LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
#define LLVM_TRANSFORMS_UTILS_CALLPROMOTIONUTILS_H
-#include "llvm/IR/CallSite.h"
-
namespace llvm {
+class CallBase;
+class CastInst;
+class Function;
+class MDNode;
/// Return true if the given indirect call site can be made to call \p Callee.
///
@@ -25,7 +27,7 @@ namespace llvm {
/// match exactly, they must at least be bitcast compatible. If \p FailureReason
/// is non-null and the indirect call cannot be promoted, the failure reason
/// will be stored in it.
-bool isLegalToPromote(CallSite CS, Function *Callee,
+bool isLegalToPromote(const CallBase &CB, Function *Callee,
const char **FailureReason = nullptr);
/// Promote the given indirect call site to unconditionally call \p Callee.
@@ -35,8 +37,8 @@ bool isLegalToPromote(CallSite CS, Function *Callee,
/// of the callee, bitcast instructions are inserted where appropriate. If \p
/// RetBitCast is non-null, it will be used to store the return value bitcast,
/// if created.
-Instruction *promoteCall(CallSite CS, Function *Callee,
- CastInst **RetBitCast = nullptr);
+CallBase &promoteCall(CallBase &CB, Function *Callee,
+ CastInst **RetBitCast = nullptr);
/// Promote the given indirect call site to conditionally call \p Callee.
///
@@ -45,8 +47,31 @@ Instruction *promoteCall(CallSite CS, Function *Callee,
/// indirect call site is promoted, placed in the "then" block, and returned. If
/// \p BranchWeights is non-null, it will be used to set !prof metadata on the
/// new conditional branch.
-Instruction *promoteCallWithIfThenElse(CallSite CS, Function *Callee,
- MDNode *BranchWeights = nullptr);
+CallBase &promoteCallWithIfThenElse(CallBase &CB, Function *Callee,
+ MDNode *BranchWeights = nullptr);
+
+/// Try to promote (devirtualize) a virtual call on an Alloca. Return true on
+/// success.
+///
+/// Look for a pattern like:
+///
+/// %o = alloca %class.Impl
+/// %1 = getelementptr %class.Impl, %class.Impl* %o, i64 0, i32 0, i32 0
+/// store i32 (...)** bitcast (i8** getelementptr inbounds
+/// ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV4Impl, i64 0, inrange i32 0, i64 2)
+/// to i32 (...)**), i32 (...)*** %1
+/// %2 = getelementptr inbounds %class.Impl, %class.Impl* %o, i64 0, i32 0
+/// %3 = bitcast %class.Interface* %2 to void (%class.Interface*)***
+/// %vtable.i = load void (%class.Interface*)**, void (%class.Interface*)*** %3
+/// %4 = load void (%class.Interface*)*, void (%class.Interface*)** %vtable.i
+/// call void %4(%class.Interface* nonnull %2)
+///
+/// @_ZTV4Impl = linkonce_odr dso_local unnamed_addr constant { [3 x i8*] }
+/// { [3 x i8*]
+/// [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI4Impl to i8*),
+/// i8* bitcast (void (%class.Impl*)* @_ZN4Impl3RunEv to i8*)] }
+///
+bool tryPromoteCall(CallBase &CB);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h
new file mode 100644
index 000000000000..3481a098abd7
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CanonicalizeFreezeInLoops.h
@@ -0,0 +1,33 @@
+//==- CanonicalizeFreezeInLoop.h - Canonicalize freezes in a loop-*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file canonicalizes freeze instructions in a loop.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CANONICALIZE_FREEZES_IN_LOOPS_H
+#define LLVM_TRANSFORMS_UTILS_CANONICALIZE_FREEZES_IN_LOOPS_H
+
+#include "llvm/Analysis/LoopAnalysisManager.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class LPMUpdater;
+
+/// A pass that canonicalizes freeze instructions in a loop.
+class CanonicalizeFreezeInLoopsPass
+ : public PassInfoMixin<CanonicalizeFreezeInLoopsPass> {
+public:
+ PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
+ LoopStandardAnalysisResults &AR, LPMUpdater &U);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_CANONICALIZE_FREEZES_IN_LOOPS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Cloning.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Cloning.h
index 872ab9cab85c..dffb7801bc8e 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Cloning.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Cloning.h
@@ -19,10 +19,8 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/InlineCost.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
#include <functional>
@@ -31,6 +29,7 @@
namespace llvm {
+class AAResults;
class AllocaInst;
class BasicBlock;
class BlockFrequencyInfo;
@@ -172,19 +171,19 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
/// the auxiliary results produced by it.
class InlineFunctionInfo {
public:
- explicit InlineFunctionInfo(CallGraph *cg = nullptr,
- std::function<AssumptionCache &(Function &)>
- *GetAssumptionCache = nullptr,
- ProfileSummaryInfo *PSI = nullptr,
- BlockFrequencyInfo *CallerBFI = nullptr,
- BlockFrequencyInfo *CalleeBFI = nullptr)
+ explicit InlineFunctionInfo(
+ CallGraph *cg = nullptr,
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache = nullptr,
+ ProfileSummaryInfo *PSI = nullptr,
+ BlockFrequencyInfo *CallerBFI = nullptr,
+ BlockFrequencyInfo *CalleeBFI = nullptr)
: CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI),
CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {}
/// If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- std::function<AssumptionCache &(Function &)> *GetAssumptionCache;
+ function_ref<AssumptionCache &(Function &)> GetAssumptionCache;
ProfileSummaryInfo *PSI;
BlockFrequencyInfo *CallerBFI, *CalleeBFI;
@@ -201,7 +200,7 @@ public:
/// 'InlineFunction' fills this in by scanning the inlined instructions, and
/// only if CG is null. If CG is non-null, instead the value handle
/// `InlinedCalls` above is used.
- SmallVector<CallSite, 8> InlinedCallSites;
+ SmallVector<CallBase *, 8> InlinedCallSites;
void reset() {
StaticAllocas.clear();
@@ -229,10 +228,7 @@ public:
/// and all varargs at the callsite will be passed to any calls to
/// ForwardVarArgsTo. The caller of InlineFunction has to make sure any varargs
/// are only used by ForwardVarArgsTo.
-InlineResult InlineFunction(CallBase *CB, InlineFunctionInfo &IFI,
- AAResults *CalleeAAR = nullptr,
- bool InsertLifetime = true);
-InlineResult InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
+InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI,
AAResults *CalleeAAR = nullptr,
bool InsertLifetime = true,
Function *ForwardVarArgsTo = nullptr);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeExtractor.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
index 8a1ab796734e..1d9f2d135488 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -140,9 +140,11 @@ public:
Function *extractCodeRegion(const CodeExtractorAnalysisCache &CEAC);
/// Verify that assumption cache isn't stale after a region is extracted.
- /// Returns false when verifier finds errors. AssumptionCache is passed as
+ /// Returns true when verifier finds errors. AssumptionCache is passed as
/// parameter to make this function stateless.
- static bool verifyAssumptionCache(const Function& F, AssumptionCache *AC);
+ static bool verifyAssumptionCache(const Function &OldFunc,
+ const Function &NewFunc,
+ AssumptionCache *AC);
/// Test whether this code extractor is eligible.
///
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
index 32eb7cc2ab04..630f936471f2 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/CodeMoverUtils.h
@@ -23,33 +23,44 @@ class Instruction;
class PostDominatorTree;
/// Return true if \p I0 and \p I1 are control flow equivalent.
-/// Two instructions are control flow equivalent if when one executes,
-/// the other is guaranteed to execute. This is determined using dominators
-/// and post-dominators: if A dominates B and B post-dominates A then A and B
-/// are control-flow equivalent.
+/// Two instructions are control flow equivalent if their basic blocks are
+/// control flow equivalent.
bool isControlFlowEquivalent(const Instruction &I0, const Instruction &I1,
const DominatorTree &DT,
const PostDominatorTree &PDT);
/// Return true if \p BB0 and \p BB1 are control flow equivalent.
/// Two basic blocks are control flow equivalent if when one executes, the other
-/// is guaranteed to execute. This is determined using dominators and
-/// post-dominators: if A dominates B and B post-dominates A then A and B are
-/// control-flow equivalent.
+/// is guaranteed to execute.
bool isControlFlowEquivalent(const BasicBlock &BB0, const BasicBlock &BB1,
const DominatorTree &DT,
const PostDominatorTree &PDT);
/// Return true if \p I can be safely moved before \p InsertPoint.
bool isSafeToMoveBefore(Instruction &I, Instruction &InsertPoint,
- const DominatorTree &DT, const PostDominatorTree &PDT,
- DependenceInfo &DI);
-
-/// Move instructions from \p FromBB bottom up to the beginning of \p ToBB
-/// when proven safe.
-void moveInstsBottomUp(BasicBlock &FromBB, BasicBlock &ToBB,
- const DominatorTree &DT, const PostDominatorTree &PDT,
- DependenceInfo &DI);
+ DominatorTree &DT,
+ const PostDominatorTree *PDT = nullptr,
+ DependenceInfo *DI = nullptr);
+
+/// Return true if all instructions (except the terminator) in \p BB can be
+/// safely moved before \p InsertPoint.
+bool isSafeToMoveBefore(BasicBlock &BB, Instruction &InsertPoint,
+ DominatorTree &DT,
+ const PostDominatorTree *PDT = nullptr,
+ DependenceInfo *DI = nullptr);
+
+/// Move instructions, in an order-preserving manner, from \p FromBB to the
+/// beginning of \p ToBB when proven safe.
+void moveInstructionsToTheBeginning(BasicBlock &FromBB, BasicBlock &ToBB,
+ DominatorTree &DT,
+ const PostDominatorTree &PDT,
+ DependenceInfo &DI);
+
+/// Move instructions, in an order-preserving manner, from \p FromBB to the end
+/// of \p ToBB when proven safe.
+void moveInstructionsToTheEnd(BasicBlock &FromBB, BasicBlock &ToBB,
+ DominatorTree &DT, const PostDominatorTree &PDT,
+ DependenceInfo &DI);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Debugify.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Debugify.h
index 0b5ec738750d..6f11d0a7d062 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Debugify.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Debugify.h
@@ -17,6 +17,28 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/IR/PassManager.h"
+namespace llvm {
+class DIBuilder;
+
+/// Add synthesized debug information to a module.
+///
+/// \param M The module to add debug information to.
+/// \param Functions A range of functions to add debug information to.
+/// \param Banner A prefix string to add to debug/error messages.
+/// \param ApplyToMF A call back that will add debug information to the
+/// MachineFunction for a Function. If nullptr, then the
+/// MachineFunction (if any) will not be modified.
+bool applyDebugifyMetadata(
+ Module &M, iterator_range<Module::iterator> Functions, StringRef Banner,
+ std::function<bool(DIBuilder &, Function &)> ApplyToMF);
+
+/// Strip out all of the metadata and debug info inserted by debugify. If no
+/// llvm.debugify module-level named metadata is present, this is a no-op.
+/// Returns true if any change was made.
+bool stripDebugifyMetadata(Module &M);
+
+} // namespace llvm
+
llvm::ModulePass *createDebugifyModulePass();
llvm::FunctionPass *createDebugifyFunctionPass();
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Evaluator.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Evaluator.h
index bffd65f71b2e..31034d950c81 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Evaluator.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Evaluator.h
@@ -17,8 +17,8 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/CallSite.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include <cassert>
@@ -73,15 +73,6 @@ public:
ValueStack.back()[V] = C;
}
- /// Given call site return callee and list of its formal arguments
- Function *getCalleeWithFormalArgs(CallSite &CS,
- SmallVector<Constant *, 8> &Formals);
-
- /// Given call site and callee returns list of callee formal argument
- /// values converting them when necessary
- bool getFormalParams(CallSite &CS, Function *F,
- SmallVector<Constant *, 8> &Formals);
-
/// Casts call result to a type of bitcast call expression
Constant *castCallResultIfNeeded(Value *CallExpr, Constant *RV);
@@ -94,6 +85,15 @@ public:
}
private:
+ /// Given call site return callee and list of its formal arguments
+ Function *getCalleeWithFormalArgs(CallBase &CB,
+ SmallVectorImpl<Constant *> &Formals);
+
+ /// Given call site and callee returns list of callee formal argument
+ /// values converting them when necessary
+ bool getFormalParams(CallBase &CB, Function *F,
+ SmallVectorImpl<Constant *> &Formals);
+
Constant *ComputeLoadResult(Constant *P);
/// As we compute SSA register values, we store their contents here. The back
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionComparator.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
index 4e2571b1d0b6..e808a50b320f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionComparator.h
@@ -332,7 +332,7 @@ private:
int cmpInlineAsm(const InlineAsm *L, const InlineAsm *R) const;
int cmpAttrs(const AttributeList L, const AttributeList R) const;
int cmpRangeMetadata(const MDNode *L, const MDNode *R) const;
- int cmpOperandBundlesSchema(const Instruction *L, const Instruction *R) const;
+ int cmpOperandBundlesSchema(const CallBase &LCS, const CallBase &RCS) const;
/// Compare two GEPs for equivalent pointer arithmetic.
/// Parts to be compared for each comparison stage,
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
index 2c6c3adc8dad..acdd8fffa1c1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/FunctionImportUtils.h
@@ -39,6 +39,19 @@ class FunctionImportGlobalProcessing {
/// as part of a different backend compilation process.
bool HasExportedFunctions = false;
+ /// Set to true (only applicatable to ELF -fpic) if dso_local should be
+ /// dropped for a declaration.
+ ///
+ /// On ELF, the assembler is conservative and assumes a global default
+ /// visibility symbol can be interposable. No direct access relocation is
+ /// allowed, if the definition is not in the translation unit, even if the
+ /// definition is available in the linkage unit. Thus we need to clear
+ /// dso_local to disable direct access.
+ ///
+ /// This flag should not be set for -fno-pic or -fpie, which would
+ /// unnecessarily disable direct access.
+ bool ClearDSOLocalOnDeclarations;
+
/// Set of llvm.*used values, in order to validate that we don't try
/// to promote any non-renamable values.
SmallPtrSet<GlobalValue *, 8> Used;
@@ -85,10 +98,11 @@ class FunctionImportGlobalProcessing {
GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV, bool DoPromote);
public:
- FunctionImportGlobalProcessing(
- Module &M, const ModuleSummaryIndex &Index,
- SetVector<GlobalValue *> *GlobalsToImport = nullptr)
- : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) {
+ FunctionImportGlobalProcessing(Module &M, const ModuleSummaryIndex &Index,
+ SetVector<GlobalValue *> *GlobalsToImport,
+ bool ClearDSOLocalOnDeclarations)
+ : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport),
+ ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {
// If we have a ModuleSummaryIndex but no function to import,
// then this is the primary module being compiled in a ThinLTO
// backend compilation, and we need to see if it has functions that
@@ -111,6 +125,7 @@ public:
/// exported local functions renamed and promoted for ThinLTO.
bool renameModuleForThinLTO(
Module &M, const ModuleSummaryIndex &Index,
+ bool ClearDSOLocalOnDeclarations,
SetVector<GlobalValue *> *GlobalsToImport = nullptr);
/// Compute synthetic function entry counts.
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Local.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Local.h
index d1dc0b3e46b9..f55e336f1f6a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/Local.h
@@ -19,35 +19,37 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/DomTreeUpdater.h"
#include "llvm/Analysis/Utils/Local.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Dominators.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Casting.h"
#include <cstdint>
#include <limits>
namespace llvm {
+class AAResults;
class AllocaInst;
class AssumptionCache;
class BasicBlock;
class BranchInst;
+class CallBase;
class CallInst;
+class DbgDeclareInst;
class DbgVariableIntrinsic;
class DbgValueInst;
class DIBuilder;
+class DomTreeUpdater;
class Function;
class Instruction;
-class LazyValueInfo;
+class InvokeInst;
class LoadInst;
class MDNode;
class MemorySSAUpdater;
@@ -66,18 +68,25 @@ struct SimplifyCFGOptions {
bool ConvertSwitchToLookupTable;
bool NeedCanonicalLoop;
bool SinkCommonInsts;
+ bool SimplifyCondBranch;
+ bool FoldTwoEntryPHINode;
+
AssumptionCache *AC;
SimplifyCFGOptions(unsigned BonusThreshold = 1,
bool ForwardSwitchCond = false,
bool SwitchToLookup = false, bool CanonicalLoops = true,
bool SinkCommon = false,
- AssumptionCache *AssumpCache = nullptr)
+ AssumptionCache *AssumpCache = nullptr,
+ bool SimplifyCondBranch = true,
+ bool FoldTwoEntryPHINode = true)
: BonusInstThreshold(BonusThreshold),
ForwardSwitchCondToPhi(ForwardSwitchCond),
ConvertSwitchToLookupTable(SwitchToLookup),
NeedCanonicalLoop(CanonicalLoops),
SinkCommonInsts(SinkCommon),
+ SimplifyCondBranch(SimplifyCondBranch),
+ FoldTwoEntryPHINode(FoldTwoEntryPHINode),
AC(AssumpCache) {}
// Support 'builder' pattern to set members by name at construction time.
@@ -105,6 +114,15 @@ struct SimplifyCFGOptions {
AC = Cache;
return *this;
}
+ SimplifyCFGOptions &setSimplifyCondBranch(bool B) {
+ SimplifyCondBranch = B;
+ return *this;
+ }
+
+ SimplifyCFGOptions &setFoldTwoEntryPHINode(bool B) {
+ FoldTwoEntryPHINode = B;
+ return *this;
+ }
};
//===----------------------------------------------------------------------===//
@@ -153,7 +171,15 @@ bool RecursivelyDeleteTriviallyDeadInstructions(
/// `DeadInsts` will be used as scratch storage for this routine and will be
/// empty afterward.
void RecursivelyDeleteTriviallyDeadInstructions(
- SmallVectorImpl<Instruction *> &DeadInsts,
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts,
+ const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr);
+
+/// Same functionality as RecursivelyDeleteTriviallyDeadInstructions, but allow
+/// instructions that are not trivially dead. These will be ignored.
+/// Returns true if any changes were made, i.e. any instructions trivially dead
+/// were found and deleted.
+bool RecursivelyDeleteTriviallyDeadInstructionsPermissive(
+ SmallVectorImpl<WeakTrackingVH> &DeadInsts,
const TargetLibraryInfo *TLI = nullptr, MemorySSAUpdater *MSSAU = nullptr);
/// If the specified value is an effectively dead PHI node, due to being a
@@ -162,7 +188,8 @@ void RecursivelyDeleteTriviallyDeadInstructions(
/// operands trivially dead, delete them too, recursively. Return true if a
/// change was made.
bool RecursivelyDeleteDeadPHINode(PHINode *PN,
- const TargetLibraryInfo *TLI = nullptr);
+ const TargetLibraryInfo *TLI = nullptr,
+ MemorySSAUpdater *MSSAU = nullptr);
/// Scan the specified basic block and try to simplify any instructions in it
/// and recursively delete dead instructions.
@@ -226,7 +253,7 @@ bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
/// This function is used to flatten a CFG. For example, it uses parallel-and
/// and parallel-or mode to collapse if-conditions and merge if-regions with
/// identical statements.
-bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
+bool FlattenCFG(BasicBlock *BB, AAResults *AA = nullptr);
/// If this basic block is ONLY a setcc and a branch, and if a predecessor
/// branches to us and one of our successors, fold the setcc into the
@@ -257,18 +284,18 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
/// so if alignment is important, a more reliable approach is to simply align
/// all global variables and allocation instructions to their preferred
/// alignment from the beginning.
-unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const DataLayout &DL,
- const Instruction *CxtI = nullptr,
- AssumptionCache *AC = nullptr,
- const DominatorTree *DT = nullptr);
+Align getOrEnforceKnownAlignment(Value *V, MaybeAlign PrefAlign,
+ const DataLayout &DL,
+ const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
+ const DominatorTree *DT = nullptr);
/// Try to infer an alignment for the specified pointer.
-inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
- const Instruction *CxtI = nullptr,
- AssumptionCache *AC = nullptr,
- const DominatorTree *DT = nullptr) {
- return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
+inline Align getKnownAlignment(Value *V, const DataLayout &DL,
+ const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
+ const DominatorTree *DT = nullptr) {
+ return getOrEnforceKnownAlignment(V, MaybeAlign(), DL, CxtI, AC, DT);
}
/// Create a call that matches the invoke \p II in terms of arguments,
@@ -312,6 +339,10 @@ void insertDebugValuesForPHIs(BasicBlock *BB,
/// dbg.addr intrinsics.
TinyPtrVector<DbgVariableIntrinsic *> FindDbgAddrUses(Value *V);
+/// Like \c FindDbgAddrUses, but only returns dbg.declare intrinsics, not
+/// dbg.addr.
+TinyPtrVector<DbgDeclareInst *> FindDbgDeclareUses(Value *V);
+
/// Finds the llvm.dbg.value intrinsics describing a value.
void findDbgValues(SmallVectorImpl<DbgValueInst *> &DbgValues, Value *V);
@@ -323,20 +354,9 @@ void findDbgUsers(SmallVectorImpl<DbgVariableIntrinsic *> &DbgInsts, Value *V);
/// additional DW_OP_deref is prepended to the expression. If Offset
/// is non-zero, a constant displacement is added to the expression
/// (between the optional Deref operations). Offset can be negative.
-bool replaceDbgDeclare(Value *Address, Value *NewAddress,
- Instruction *InsertBefore, DIBuilder &Builder,
+bool replaceDbgDeclare(Value *Address, Value *NewAddress, DIBuilder &Builder,
uint8_t DIExprFlags, int Offset);
-/// Replaces llvm.dbg.declare instruction when the alloca it describes
-/// is replaced with a new value. If Deref is true, an additional
-/// DW_OP_deref is prepended to the expression. If Offset is non-zero,
-/// a constant displacement is added to the expression (between the
-/// optional Deref operations). Offset can be negative. The new
-/// llvm.dbg.declare is inserted immediately after AI.
-bool replaceDbgDeclareForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
- DIBuilder &Builder, uint8_t DIExprFlags,
- int Offset);
-
/// Replaces multiple llvm.dbg.value instructions when the alloca it describes
/// is replaced with a new value. If Offset is non-zero, a constant displacement
/// is added to the expression (after the mandatory Deref). Offset can be
@@ -350,17 +370,16 @@ AllocaInst *findAllocaForValue(Value *V,
DenseMap<Value *, AllocaInst *> &AllocaForValue);
/// Assuming the instruction \p I is going to be deleted, attempt to salvage
-/// debug users of \p I by writing the effect of \p I in a DIExpression.
-/// Returns true if any debug users were updated.
-bool salvageDebugInfo(Instruction &I);
+/// debug users of \p I by writing the effect of \p I in a DIExpression. If it
+/// cannot be salvaged changes its debug uses to undef.
+void salvageDebugInfo(Instruction &I);
-/// Salvage all debug users of the instruction \p I or mark it as undef if it
-/// cannot be salvaged.
-void salvageDebugInfoOrMarkUndef(Instruction &I);
/// Implementation of salvageDebugInfo, applying only to instructions in
-/// \p Insns, rather than all debug users of \p I.
-bool salvageDebugInfoForDbgValues(Instruction &I,
+/// \p Insns, rather than all debug users from findDbgUsers( \p I).
+/// Returns true if any debug users were updated.
+/// Mark undef if salvaging cannot be completed.
+void salvageDebugInfoForDbgValues(Instruction &I,
ArrayRef<DbgVariableIntrinsic *> Insns);
/// Given an instruction \p I and DIExpression \p DIExpr operating on it, write
@@ -530,6 +549,13 @@ void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI,
/// value?
bool canReplaceOperandWithVariable(const Instruction *I, unsigned OpIdx);
+//===----------------------------------------------------------------------===//
+// Value helper functions
+//
+
+/// Invert the given true/false value, possibly reusing an existing copy.
+Value *invertCondition(Value *Condition);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_LOCAL_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopSimplify.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopSimplify.h
index 2c1df7942f63..d017fd12026d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopSimplify.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopSimplify.h
@@ -38,14 +38,16 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOOPSIMPLIFY_H
#define LLVM_TRANSFORMS_UTILS_LOOPSIMPLIFY_H
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/Dominators.h"
#include "llvm/IR/PassManager.h"
namespace llvm {
+class AssumptionCache;
+class DominatorTree;
+class Loop;
+class LoopInfo;
class MemorySSAUpdater;
+class ScalarEvolution;
/// This pass is responsible for loop canonicalization.
class LoopSimplifyPass : public PassInfoMixin<LoopSimplifyPass> {
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopUtils.h
index 9ed96809ed99..60446bca5317 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopUtils.h
@@ -13,42 +13,44 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
#define LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/DemandedBits.h"
-#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/IVDescriptors.h"
-#include "llvm/Analysis/MustExecute.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InstrTypes.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/IR/ValueHandle.h"
-#include "llvm/Support/Casting.h"
+#include "llvm/Transforms/Utils/ValueMapper.h"
namespace llvm {
+template <typename T> class DomTreeNodeBase;
+using DomTreeNode = DomTreeNodeBase<BasicBlock>;
+class AAResults;
class AliasSet;
class AliasSetTracker;
class BasicBlock;
-class DataLayout;
+class IRBuilderBase;
class Loop;
class LoopInfo;
class MemoryAccess;
+class MemorySSA;
class MemorySSAUpdater;
class OptimizationRemarkEmitter;
-class PredicatedScalarEvolution;
class PredIteratorCache;
class ScalarEvolution;
class SCEV;
+class SCEVExpander;
class TargetLibraryInfo;
class TargetTransformInfo;
+class LPPassManager;
+class Instruction;
+struct RuntimeCheckingPtrGroup;
+typedef std::pair<const RuntimeCheckingPtrGroup *,
+ const RuntimeCheckingPtrGroup *>
+ RuntimePointerCheck;
+
+template <typename T> class Optional;
+template <typename T, unsigned N> class SmallSetVector;
+template <typename T, unsigned N> class SmallVector;
+template <typename T> class SmallVectorImpl;
+template <typename T, unsigned N> class SmallPriorityWorklist;
BasicBlock *InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI,
MemorySSAUpdater *MSSAU, bool PreserveLCSSA);
@@ -73,7 +75,7 @@ bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
///
/// Returns true if any modifications are made.
bool formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
- DominatorTree &DT, LoopInfo &LI,
+ const DominatorTree &DT, const LoopInfo &LI,
ScalarEvolution *SE);
/// Put loop into LCSSA form.
@@ -88,7 +90,8 @@ bool formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
/// If ScalarEvolution is passed in, it will be preserved.
///
/// Returns true if any modifications are made to the loop.
-bool formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE);
+bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
+ ScalarEvolution *SE);
/// Put a loop nest into LCSSA form.
///
@@ -99,7 +102,7 @@ bool formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE);
/// If ScalarEvolution is passed in, it will be preserved.
///
/// Returns true if any modifications are made to the loop.
-bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
+bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI,
ScalarEvolution *SE);
struct SinkAndHoistLICMFlags {
@@ -114,11 +117,11 @@ struct SinkAndHoistLICMFlags {
/// dominated by the specified block, and that are in the current loop) in
/// reverse depth first order w.r.t the DominatorTree. This allows us to visit
/// uses before definitions, allowing us to sink a loop body in one pass without
-/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
-/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
+/// iteration. Takes DomTreeNode, AAResults, LoopInfo, DominatorTree,
+/// TargetLibraryInfo, Loop, AliasSet information for all
/// instructions of the loop and loop safety information as
/// arguments. Diagnostics is emitted via \p ORE. It returns changed status.
-bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
+bool sinkRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
TargetLibraryInfo *, TargetTransformInfo *, Loop *,
AliasSetTracker *, MemorySSAUpdater *, ICFLoopSafetyInfo *,
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *);
@@ -127,11 +130,11 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// dominated by the specified block, and that are in the current loop) in depth
/// first order w.r.t the DominatorTree. This allows us to visit definitions
/// before uses, allowing us to hoist a loop body in one pass without iteration.
-/// Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree, DataLayout,
+/// Takes DomTreeNode, AAResults, LoopInfo, DominatorTree,
/// TargetLibraryInfo, Loop, AliasSet information for all instructions of the
/// loop and loop safety information as arguments. Diagnostics is emitted via \p
/// ORE. It returns changed status.
-bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
+bool hoistRegion(DomTreeNode *, AAResults *, LoopInfo *, DominatorTree *,
TargetLibraryInfo *, Loop *, AliasSetTracker *,
MemorySSAUpdater *, ScalarEvolution *, ICFLoopSafetyInfo *,
SinkAndHoistLICMFlags &, OptimizationRemarkEmitter *);
@@ -143,12 +146,12 @@ bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// - The loop needs to have a Preheader
/// - A unique dedicated exit block must exist
///
-/// This also updates the relevant analysis information in \p DT, \p SE, and \p
-/// LI if pointers to those are provided.
+/// This also updates the relevant analysis information in \p DT, \p SE, \p LI
+/// and \p MSSA if pointers to those are provided.
/// It also updates the loop PM if an updater struct is provided.
void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
- LoopInfo *LI);
+ LoopInfo *LI, MemorySSA *MSSA = nullptr);
/// Try to promote memory values to scalars by sinking stores out of
/// the loop and moving loads to before the loop. We do this by looping over
@@ -261,10 +264,22 @@ TransformationMode hasLICMVersioningTransformation(Loop *L);
void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
unsigned V = 0);
-/// Get a loop's estimated trip count based on branch weight metadata.
+/// Returns a loop's estimated trip count based on branch weight metadata.
+/// In addition if \p EstimatedLoopInvocationWeight is not null it is
+/// initialized with weight of loop's latch leading to the exit.
/// Returns 0 when the count is estimated to be 0, or None when a meaningful
/// estimate can not be made.
-Optional<unsigned> getLoopEstimatedTripCount(Loop *L);
+Optional<unsigned>
+getLoopEstimatedTripCount(Loop *L,
+ unsigned *EstimatedLoopInvocationWeight = nullptr);
+
+/// Set a loop's branch weight metadata to reflect that loop has \p
+/// EstimatedTripCount iterations and \p EstimatedLoopInvocationWeight exits
+/// through latch. Returns true if metadata is successfully updated, false
+/// otherwise. Note that loop must have a latch block which controls loop exit
+/// in order to succeed.
+bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount,
+ unsigned EstimatedLoopInvocationWeight);
/// Check inner loop (L) backedge count is known to be invariant on all
/// iterations of its outer loop. If the loop has no parent, this is trivially
@@ -294,20 +309,20 @@ bool canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
OptimizationRemarkEmitter *ORE = nullptr);
/// Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
-Value *createMinMaxOp(IRBuilder<> &Builder,
+Value *createMinMaxOp(IRBuilderBase &Builder,
RecurrenceDescriptor::MinMaxRecurrenceKind RK,
Value *Left, Value *Right);
/// Generates an ordered vector reduction using extracts to reduce the value.
Value *
-getOrderedReduction(IRBuilder<> &Builder, Value *Acc, Value *Src, unsigned Op,
+getOrderedReduction(IRBuilderBase &Builder, Value *Acc, Value *Src, unsigned Op,
RecurrenceDescriptor::MinMaxRecurrenceKind MinMaxKind =
RecurrenceDescriptor::MRK_Invalid,
ArrayRef<Value *> RedOps = None);
/// Generates a vector reduction using shufflevectors to reduce the value.
/// Fast-math-flags are propagated using the IRBuilder's setting.
-Value *getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
+Value *getShuffleReduction(IRBuilderBase &Builder, Value *Src, unsigned Op,
RecurrenceDescriptor::MinMaxRecurrenceKind
MinMaxKind = RecurrenceDescriptor::MRK_Invalid,
ArrayRef<Value *> RedOps = None);
@@ -318,7 +333,7 @@ Value *getShuffleReduction(IRBuilder<> &Builder, Value *Src, unsigned Op,
/// The target is queried to determine if intrinsics or shuffle sequences are
/// required to implement the reduction.
/// Fast-math-flags are propagated using the IRBuilder's setting.
-Value *createSimpleTargetReduction(IRBuilder<> &B,
+Value *createSimpleTargetReduction(IRBuilderBase &B,
const TargetTransformInfo *TTI,
unsigned Opcode, Value *Src,
TargetTransformInfo::ReductionFlags Flags =
@@ -329,7 +344,7 @@ Value *createSimpleTargetReduction(IRBuilder<> &B,
/// The target is queried to determine if intrinsics or shuffle sequences are
/// required to implement the reduction.
/// Fast-math-flags are propagated using the RecurrenceDescriptor.
-Value *createTargetReduction(IRBuilder<> &B, const TargetTransformInfo *TTI,
+Value *createTargetReduction(IRBuilderBase &B, const TargetTransformInfo *TTI,
RecurrenceDescriptor &Desc, Value *Src,
bool NoNaN = false);
@@ -357,6 +372,77 @@ bool cannotBeMaxInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
bool cannotBeMinInLoop(const SCEV *S, const Loop *L, ScalarEvolution &SE,
bool Signed);
+enum ReplaceExitVal { NeverRepl, OnlyCheapRepl, NoHardUse, AlwaysRepl };
+
+/// If the final value of any expressions that are recurrent in the loop can
+/// be computed, substitute the exit values from the loop into any instructions
+/// outside of the loop that use the final values of the current expressions.
+/// Return the number of loop exit values that have been replaced, and the
+/// corresponding phi node will be added to DeadInsts.
+int rewriteLoopExitValues(Loop *L, LoopInfo *LI, TargetLibraryInfo *TLI,
+ ScalarEvolution *SE, const TargetTransformInfo *TTI,
+ SCEVExpander &Rewriter, DominatorTree *DT,
+ ReplaceExitVal ReplaceExitValue,
+ SmallVector<WeakTrackingVH, 16> &DeadInsts);
+
+/// Set weights for \p UnrolledLoop and \p RemainderLoop based on weights for
+/// \p OrigLoop and the following distribution of \p OrigLoop iteration among \p
+/// UnrolledLoop and \p RemainderLoop. \p UnrolledLoop receives weights that
+/// reflect TC/UF iterations, and \p RemainderLoop receives weights that reflect
+/// the remaining TC%UF iterations.
+///
+/// Note that \p OrigLoop may be equal to either \p UnrolledLoop or \p
+/// RemainderLoop in which case weights for \p OrigLoop are updated accordingly.
+/// Note also behavior is undefined if \p UnrolledLoop and \p RemainderLoop are
+/// equal. \p UF must be greater than zero.
+/// If \p OrigLoop has no profile info associated nothing happens.
+///
+/// This utility may be useful for such optimizations as unroller and
+/// vectorizer as it's typical transformation for them.
+void setProfileInfoAfterUnrolling(Loop *OrigLoop, Loop *UnrolledLoop,
+ Loop *RemainderLoop, uint64_t UF);
+
+/// Utility that implements appending of loops onto a worklist given a range.
+/// We want to process loops in postorder, but the worklist is a LIFO data
+/// structure, so we append to it in *reverse* postorder.
+/// For trees, a preorder traversal is a viable reverse postorder, so we
+/// actually append using a preorder walk algorithm.
+template <typename RangeT>
+void appendLoopsToWorklist(RangeT &&, SmallPriorityWorklist<Loop *, 4> &);
+/// Utility that implements appending of loops onto a worklist given a range.
+/// It has the same behavior as appendLoopsToWorklist, but assumes the range of
+/// loops has already been reversed, so it processes loops in the given order.
+template <typename RangeT>
+void appendReversedLoopsToWorklist(RangeT &&,
+ SmallPriorityWorklist<Loop *, 4> &);
+
+/// Utility that implements appending of loops onto a worklist given LoopInfo.
+/// Calls the templated utility taking a Range of loops, handing it the Loops
+/// in LoopInfo, iterated in reverse. This is because the loops are stored in
+/// RPO w.r.t. the control flow graph in LoopInfo. For the purpose of unrolling,
+/// loop deletion, and LICM, we largely want to work forward across the CFG so
+/// that we visit defs before uses and can propagate simplifications from one
+/// loop nest into the next. Calls appendReversedLoopsToWorklist with the
+/// already reversed loops in LI.
+/// FIXME: Consider changing the order in LoopInfo.
+void appendLoopsToWorklist(LoopInfo &, SmallPriorityWorklist<Loop *, 4> &);
+
+/// Recursively clone the specified loop and all of its children,
+/// mapping the blocks with the specified map.
+Loop *cloneLoop(Loop *L, Loop *PL, ValueToValueMapTy &VM,
+ LoopInfo *LI, LPPassManager *LPM);
+
+/// Add code that checks at runtime if the accessed arrays in \p PointerChecks
+/// overlap.
+///
+/// Returns a pair of instructions where the first element is the first
+/// instruction generated in possibly a sequence of instructions and the
+/// second value is the final comparator value or NULL if no check is needed.
+std::pair<Instruction *, Instruction *>
+addRuntimeChecks(Instruction *Loc, Loop *TheLoop,
+ const SmallVectorImpl<RuntimePointerCheck> &PointerChecks,
+ ScalarEvolution *SE);
+
} // end namespace llvm
#endif // LLVM_TRANSFORMS_UTILS_LOOPUTILS_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopVersioning.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
index 355c4d7dc6d8..1efdcc65b39a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LoopVersioning.h
@@ -15,7 +15,6 @@
#ifndef LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
#define LLVM_TRANSFORMS_UTILS_LOOPVERSIONING_H
-#include "llvm/Analysis/LoopAccessAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Transforms/Utils/LoopUtils.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
@@ -26,6 +25,12 @@ class Loop;
class LoopAccessInfo;
class LoopInfo;
class ScalarEvolution;
+struct RuntimeCheckingPtrGroup;
+typedef std::pair<const RuntimeCheckingPtrGroup *,
+ const RuntimeCheckingPtrGroup *>
+ RuntimePointerCheck;
+
+template <typename T> class ArrayRef;
/// This class emits a version of the loop where run-time checks ensure
/// that may-alias pointers can't overlap.
@@ -71,8 +76,7 @@ public:
Loop *getNonVersionedLoop() { return NonVersionedLoop; }
/// Sets the runtime alias checks for versioning the loop.
- void setAliasChecks(
- SmallVector<RuntimePointerChecking::PointerCheck, 4> Checks);
+ void setAliasChecks(ArrayRef<RuntimePointerCheck> Checks);
/// Sets the runtime SCEV checks for versioning the loop.
void setSCEVChecks(SCEVUnionPredicate Check);
@@ -122,22 +126,20 @@ private:
ValueToValueMapTy VMap;
/// The set of alias checks that we are versioning for.
- SmallVector<RuntimePointerChecking::PointerCheck, 4> AliasChecks;
+ SmallVector<RuntimePointerCheck, 4> AliasChecks;
/// The set of SCEV checks that we are versioning for.
SCEVUnionPredicate Preds;
/// Maps a pointer to the pointer checking group that the pointer
/// belongs to.
- DenseMap<const Value *, const RuntimePointerChecking::CheckingPtrGroup *>
- PtrToGroup;
+ DenseMap<const Value *, const RuntimeCheckingPtrGroup *> PtrToGroup;
/// The alias scope corresponding to a pointer checking group.
- DenseMap<const RuntimePointerChecking::CheckingPtrGroup *, MDNode *>
- GroupToScope;
+ DenseMap<const RuntimeCheckingPtrGroup *, MDNode *> GroupToScope;
/// The list of alias scopes that a pointer checking group can't alias.
- DenseMap<const RuntimePointerChecking::CheckingPtrGroup *, MDNode *>
+ DenseMap<const RuntimeCheckingPtrGroup *, MDNode *>
GroupToNonAliasingScopeList;
/// Analyses used.
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
index 8e9d7b522c78..8d0956033d9f 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/LowerMemIntrinsics.h
@@ -23,12 +23,13 @@ class MemMoveInst;
class MemSetInst;
class TargetTransformInfo;
class Value;
+struct Align;
/// Emit a loop implementing the semantics of llvm.memcpy where the size is not
/// a compile-time constant. Loop will be insterted at \p InsertBefore.
void createMemCpyLoopUnknownSize(Instruction *InsertBefore, Value *SrcAddr,
Value *DstAddr, Value *CopyLen,
- unsigned SrcAlign, unsigned DestAlign,
+ Align SrcAlign, Align DestAlign,
bool SrcIsVolatile, bool DstIsVolatile,
const TargetTransformInfo &TTI);
@@ -36,11 +37,10 @@ void createMemCpyLoopUnknownSize(Instruction *InsertBefore, Value *SrcAddr,
/// compile time constant. Loop is inserted at \p InsertBefore.
void createMemCpyLoopKnownSize(Instruction *InsertBefore, Value *SrcAddr,
Value *DstAddr, ConstantInt *CopyLen,
- unsigned SrcAlign, unsigned DestAlign,
+ Align SrcAlign, Align DestAlign,
bool SrcIsVolatile, bool DstIsVolatile,
const TargetTransformInfo &TTI);
-
/// Expand \p MemCpy as a loop. \p MemCpy is not deleted.
void expandMemCpyAsLoop(MemCpyInst *MemCpy, const TargetTransformInfo &TTI);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
index c2da86406e71..65added8b7e1 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -13,7 +13,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
#define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <utility> // for std::pair
@@ -24,9 +24,7 @@ class Module;
class Function;
class FunctionCallee;
class GlobalValue;
-class GlobalVariable;
class Constant;
-class StringRef;
class Value;
class Type;
@@ -44,6 +42,10 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority,
FunctionCallee declareSanitizerInitFunction(Module &M, StringRef InitName,
ArrayRef<Type *> InitArgTypes);
+/// Creates sanitizer constructor function.
+/// \return Returns pointer to constructor.
+Function *createSanitizerCtor(Module &M, StringRef CtorName);
+
/// Creates sanitizer constructor function, and calls sanitizer's init
/// function from it.
/// \return Returns pair of pointers to constructor, and init functions
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PredicateInfo.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
index 7c7a8eb04a2c..657b97c67a8b 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PredicateInfo.h
@@ -51,45 +51,21 @@
#define LLVM_TRANSFORMS_UTILS_PREDICATEINFO_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
-#include "llvm/ADT/iterator.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/OrderedInstructions.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/OperandTraits.h"
-#include "llvm/IR/Type.h"
-#include "llvm/IR/Use.h"
-#include "llvm/IR/User.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueHandle.h"
#include "llvm/Pass.h"
-#include "llvm/PassAnalysisSupport.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <iterator>
-#include <memory>
-#include <utility>
namespace llvm {
+class AssumptionCache;
class DominatorTree;
class Function;
-class Instruction;
-class MemoryAccess;
-class LLVMContext;
+class IntrinsicInst;
class raw_ostream;
enum PredicateType { PT_Branch, PT_Assume, PT_Switch };
@@ -103,6 +79,10 @@ public:
// This can be use by passes, when destroying predicateinfo, to know
// whether they can just drop the intrinsic, or have to merge metadata.
Value *OriginalOp;
+ // The renamed operand in the condition used for this predicate. For nested
+ // predicates, this is different to OriginalOp which refers to the initial
+ // operand.
+ Value *RenamedOp;
PredicateBase(const PredicateBase &) = delete;
PredicateBase &operator=(const PredicateBase &) = delete;
PredicateBase() = delete;
@@ -189,26 +169,9 @@ public:
}
};
-// This name is used in a few places, so kick it into their own namespace
-namespace PredicateInfoClasses {
-struct ValueDFS;
-}
-
/// Encapsulates PredicateInfo, including all data associated with memory
/// accesses.
class PredicateInfo {
-private:
- // Used to store information about each value we might rename.
- struct ValueInfo {
- // Information about each possible copy. During processing, this is each
- // inserted info. After processing, we move the uninserted ones to the
- // uninserted vector.
- SmallVector<PredicateBase *, 4> Infos;
- SmallVector<PredicateBase *, 4> UninsertedInfos;
- };
- // This owns the all the predicate infos in the function, placed or not.
- iplist<PredicateBase> AllInfos;
-
public:
PredicateInfo(Function &, DominatorTree &, AssumptionCache &);
~PredicateInfo();
@@ -226,42 +189,18 @@ protected:
// Used by PredicateInfo annotater, dumpers, and wrapper pass.
friend class PredicateInfoAnnotatedWriter;
friend class PredicateInfoPrinterLegacyPass;
+ friend class PredicateInfoBuilder;
private:
- void buildPredicateInfo();
- void processAssume(IntrinsicInst *, BasicBlock *, SmallVectorImpl<Value *> &);
- void processBranch(BranchInst *, BasicBlock *, SmallVectorImpl<Value *> &);
- void processSwitch(SwitchInst *, BasicBlock *, SmallVectorImpl<Value *> &);
- void renameUses(SmallVectorImpl<Value *> &);
- using ValueDFS = PredicateInfoClasses::ValueDFS;
- typedef SmallVectorImpl<ValueDFS> ValueDFSStack;
- void convertUsesToDFSOrdered(Value *, SmallVectorImpl<ValueDFS> &);
- Value *materializeStack(unsigned int &, ValueDFSStack &, Value *);
- bool stackIsInScope(const ValueDFSStack &, const ValueDFS &) const;
- void popStackUntilDFSScope(ValueDFSStack &, const ValueDFS &);
- ValueInfo &getOrCreateValueInfo(Value *);
- void addInfoFor(SmallVectorImpl<Value *> &OpsToRename, Value *Op,
- PredicateBase *PB);
- const ValueInfo &getValueInfo(Value *) const;
Function &F;
- DominatorTree &DT;
- AssumptionCache &AC;
- OrderedInstructions OI;
+
+ // This owns the all the predicate infos in the function, placed or not.
+ iplist<PredicateBase> AllInfos;
+
// This maps from copy operands to Predicate Info. Note that it does not own
// the Predicate Info, they belong to the ValueInfo structs in the ValueInfos
// vector.
DenseMap<const Value *, const PredicateBase *> PredicateMap;
- // This stores info about each operand or comparison result we make copies
- // of. The real ValueInfos start at index 1, index 0 is unused so that we can
- // more easily detect invalid indexing.
- SmallVector<ValueInfo, 32> ValueInfos;
- // This gives the index into the ValueInfos array for a given Value. Because
- // 0 is not a valid Value Info index, you can use DenseMap::lookup and tell
- // whether it returned a valid result.
- DenseMap<Value *, unsigned int> ValueInfoNums;
- // The set of edges along which we can only handle phi uses, due to critical
- // edges.
- DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeUsesOnly;
// The set of ssa_copy declarations we created with our custom mangling.
SmallSet<AssertingVH<Function>, 20> CreatedDeclarations;
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
index b2b4507bbc74..f827ffd3e676 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -19,7 +19,6 @@ namespace llvm {
template <typename T> class ArrayRef;
class AllocaInst;
class DominatorTree;
-class AliasSetTracker;
class AssumptionCache;
/// Return true if this alloca is legal for promotion.
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
index 5d17d6f3d285..3a78e22b7e94 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SSAUpdaterBulk.h
@@ -14,7 +14,6 @@
#define LLVM_TRANSFORMS_UTILS_SSAUPDATERBULK_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/PredIteratorCache.h"
diff --git a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
index b4d727449fbe..0c88f9f79e76 100644
--- a/contrib/llvm-project/llvm/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/ScalarEvolutionExpander.h
@@ -16,14 +16,17 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
#include "llvm/Analysis/TargetFolder.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/CommandLine.h"
namespace llvm {
- class TargetTransformInfo;
+ extern cl::opt<unsigned> SCEVCheapExpansionBudget;
/// Return true if the given expression is safe to expand in the sense that
/// all materialized values are safe to speculate anywhere their operands are
@@ -171,16 +174,31 @@ namespace llvm {
ChainedPhis.clear();
}
- /// Return true for expressions that may incur non-trivial cost to evaluate
- /// at runtime.
+ /// Return true for expressions that can't be evaluated at runtime
+ /// within given \b Budget.
///
- /// At is an optional parameter which specifies point in code where user is
- /// going to expand this expression. Sometimes this knowledge can lead to a
- /// more accurate cost estimation.
- bool isHighCostExpansion(const SCEV *Expr, Loop *L,
- const Instruction *At = nullptr) {
+ /// At is a parameter which specifies point in code where user is going to
+ /// expand this expression. Sometimes this knowledge can lead to
+ /// a less pessimistic cost estimation.
+ bool isHighCostExpansion(const SCEV *Expr, Loop *L, unsigned Budget,
+ const TargetTransformInfo *TTI,
+ const Instruction *At) {
+ assert(TTI && "This function requires TTI to be provided.");
+ assert(At && "This function requires At instruction to be provided.");
+ if (!TTI) // In assert-less builds, avoid crashing
+ return true; // by always claiming to be high-cost.
+ SmallVector<const SCEV *, 8> Worklist;
SmallPtrSet<const SCEV *, 8> Processed;
- return isHighCostExpansionHelper(Expr, L, At, Processed);
+ int BudgetRemaining = Budget * TargetTransformInfo::TCC_Basic;
+ Worklist.emplace_back(Expr);
+ while (!Worklist.empty()) {
+ const SCEV *S = Worklist.pop_back_val();
+ if (isHighCostExpansionHelper(S, L, *At, BudgetRemaining, *TTI,
+ Processed, Worklist))
+ return true;
+ }
+ assert(BudgetRemaining >= 0 && "Should have returned from inner loop.");
+ return false;
}
/// This method returns the canonical induction variable of the specified
@@ -323,8 +341,10 @@ namespace llvm {
/// Recursive helper function for isHighCostExpansion.
bool isHighCostExpansionHelper(const SCEV *S, Loop *L,
- const Instruction *At,
- SmallPtrSetImpl<const SCEV *> &Processed);
+ const Instruction &At, int &BudgetRemaining,
+ const TargetTransformInfo &TTI,
+ SmallPtrSetImpl<const SCEV *> &Processed,
+ SmallVectorImpl<const SCEV *> &Worklist);
/// Insert the specified binary operator, doing a small amount of work to
/// avoid inserting an obviously redundant operation, and hoisting to an
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
index dec73ef057e8..53b15e4aa66c 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyIndVar.h
@@ -26,6 +26,7 @@ class LoopInfo;
class PHINode;
class ScalarEvolution;
class SCEVExpander;
+class TargetTransformInfo;
/// Interface for visiting interesting IV users that are recognized but not
/// simplified by this utility.
@@ -46,13 +47,15 @@ public:
/// simplifyUsersOfIV - Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
- LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead,
+ LoopInfo *LI, const TargetTransformInfo *TTI,
+ SmallVectorImpl<WeakTrackingVH> &Dead,
SCEVExpander &Rewriter, IVVisitor *V = nullptr);
/// SimplifyLoopIVs - Simplify users of induction variables within this
/// loop. This does not actually change or add IVs.
bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
- LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead);
+ LoopInfo *LI, const TargetTransformInfo *TTI,
+ SmallVectorImpl<WeakTrackingVH> &Dead);
} // end namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 610668adcfa5..d6ee19365c72 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -16,7 +16,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/IRBuilder.h"
namespace llvm {
class StringRef;
@@ -24,8 +23,8 @@ class Value;
class CallInst;
class DataLayout;
class Instruction;
+class IRBuilderBase;
class TargetLibraryInfo;
-class BasicBlock;
class Function;
class OptimizationRemarkEmitter;
class BlockFrequencyInfo;
@@ -50,25 +49,26 @@ public:
/// optimal value to replace the instruction with or 0 if a more
/// optimal form can't be found.
/// The call must not be an indirect call.
- Value *optimizeCall(CallInst *CI);
+ Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
- Value *optimizeMemCpyChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemMoveChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemSetChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemCpyChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemMoveChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemSetChk(CallInst *CI, IRBuilderBase &B);
/// Str/Stp cpy are similar enough to be handled in the same functions.
- Value *optimizeStrpCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
- Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilder<> &B, LibFunc Func);
- Value *optimizeMemCCpyChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSNPrintfChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSPrintfChk(CallInst *CI,IRBuilder<> &B);
- Value *optimizeStrCatChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrLCat(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrNCatChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrLCpyChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeVSNPrintfChk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeVSPrintfChk(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrpCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
+ Value *optimizeStrpNCpyChk(CallInst *CI, IRBuilderBase &B, LibFunc Func);
+ Value *optimizeStrLenChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemCCpyChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSNPrintfChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSPrintfChk(CallInst *CI,IRBuilderBase &B);
+ Value *optimizeStrCatChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrLCat(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNCatChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrLCpyChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeVSNPrintfChk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeVSPrintfChk(CallInst *CI, IRBuilderBase &B);
/// Checks whether the call \p CI to a fortified libcall is foldable
/// to the non-fortified version.
@@ -132,7 +132,7 @@ private:
eraseFromParent(I);
}
- Value *foldMallocMemset(CallInst *Memset, IRBuilder<> &B);
+ Value *foldMallocMemset(CallInst *Memset, IRBuilderBase &B);
public:
LibCallSimplifier(
@@ -150,99 +150,96 @@ public:
/// other instructions that use the given instruction were modified
/// and the given instruction is dead.
/// The call must not be an indirect call.
- Value *optimizeCall(CallInst *CI);
+ Value *optimizeCall(CallInst *CI, IRBuilderBase &B);
private:
// String and Memory Library Call Optimizations
- Value *optimizeStrCat(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrNCat(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrChr(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrRChr(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrCmp(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrNCmp(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrNDup(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStpCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrNCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrLen(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrPBrk(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrTo(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrSpn(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemChr(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemRChr(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
- Value *optimizeBCmp(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemCCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemPCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
- Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B);
- Value *optimizeRealloc(CallInst *CI, IRBuilder<> &B);
- Value *optimizeWcslen(CallInst *CI, IRBuilder<> &B);
- Value *optimizeBCopy(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStrCat(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNCat(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrChr(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrRChr(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrCmp(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNCmp(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNDup(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStpCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrNCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrLen(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrPBrk(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrTo(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrSpn(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrCSpn(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrStr(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemChr(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemRChr(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemCmp(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeBCmp(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemCmpBCmpCommon(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemCCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemPCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemCpy(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemMove(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeMemSet(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeRealloc(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeWcslen(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeBCopy(CallInst *CI, IRBuilderBase &B);
// Wrapper for all String/Memory Library Call Optimizations
- Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilderBase &B);
// Math Library Optimizations
- Value *optimizeCAbs(CallInst *CI, IRBuilder<> &B);
- Value *optimizePow(CallInst *CI, IRBuilder<> &B);
- Value *replacePowWithExp(CallInst *Pow, IRBuilder<> &B);
- Value *replacePowWithSqrt(CallInst *Pow, IRBuilder<> &B);
- Value *optimizeExp2(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFMinFMax(CallInst *CI, IRBuilder<> &B);
- Value *optimizeLog(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
- Value *optimizeTan(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeCAbs(CallInst *CI, IRBuilderBase &B);
+ Value *optimizePow(CallInst *CI, IRBuilderBase &B);
+ Value *replacePowWithExp(CallInst *Pow, IRBuilderBase &B);
+ Value *replacePowWithSqrt(CallInst *Pow, IRBuilderBase &B);
+ Value *optimizeExp2(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFMinFMax(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeLog(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSqrt(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSinCosPi(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeTan(CallInst *CI, IRBuilderBase &B);
// Wrapper for all floating point library call optimizations
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
- IRBuilder<> &B);
+ IRBuilderBase &B);
// Integer Library Call Optimizations
- Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFls(CallInst *CI, IRBuilder<> &B);
- Value *optimizeAbs(CallInst *CI, IRBuilder<> &B);
- Value *optimizeIsDigit(CallInst *CI, IRBuilder<> &B);
- Value *optimizeIsAscii(CallInst *CI, IRBuilder<> &B);
- Value *optimizeToAscii(CallInst *CI, IRBuilder<> &B);
- Value *optimizeAtoi(CallInst *CI, IRBuilder<> &B);
- Value *optimizeStrtol(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeFFS(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFls(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeAbs(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeIsDigit(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeIsAscii(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeToAscii(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeAtoi(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeStrtol(CallInst *CI, IRBuilderBase &B);
// Formatting and IO Library Call Optimizations
- Value *optimizeErrorReporting(CallInst *CI, IRBuilder<> &B,
+ Value *optimizeErrorReporting(CallInst *CI, IRBuilderBase &B,
int StreamArg = -1);
- Value *optimizePrintF(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSPrintF(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSnPrintF(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFPrintF(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFWrite(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFRead(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFPuts(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFGets(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFPutc(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFGetc(CallInst *CI, IRBuilder<> &B);
- Value *optimizePuts(CallInst *CI, IRBuilder<> &B);
+ Value *optimizePrintF(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSPrintF(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSnPrintF(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFPrintF(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFWrite(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFPuts(CallInst *CI, IRBuilderBase &B);
+ Value *optimizePuts(CallInst *CI, IRBuilderBase &B);
// Helper methods
- Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B);
+ Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
+ IRBuilderBase &B);
void classifyArgUse(Value *Val, Function *F, bool IsFloat,
SmallVectorImpl<CallInst *> &SinCalls,
SmallVectorImpl<CallInst *> &CosCalls,
SmallVectorImpl<CallInst *> &SinCosCalls);
- Value *optimizePrintFString(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSPrintFString(CallInst *CI, IRBuilder<> &B);
- Value *optimizeSnPrintFString(CallInst *CI, IRBuilder<> &B);
- Value *optimizeFPrintFString(CallInst *CI, IRBuilder<> &B);
+ Value *optimizePrintFString(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSPrintFString(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeSnPrintFString(CallInst *CI, IRBuilderBase &B);
+ Value *optimizeFPrintFString(CallInst *CI, IRBuilderBase &B);
/// hasFloatVersion - Checks if there is a float version of the specified
/// function by checking for an existing function with name FuncName + f
bool hasFloatVersion(StringRef FuncName);
/// Shared code to optimize strlen+wcslen.
- Value *optimizeStringLength(CallInst *CI, IRBuilder<> &B, unsigned CharSize);
+ Value *optimizeStringLength(CallInst *CI, IRBuilderBase &B, unsigned CharSize);
};
} // End llvm namespace
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h
index 1137c89195a6..08d963475f23 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h
@@ -21,6 +21,9 @@ extern llvm::cl::opt<bool> EnablePGSO;
extern llvm::cl::opt<bool> PGSOLargeWorkingSetSizeOnly;
extern llvm::cl::opt<bool> PGSOIRPassOrTestOnly;
extern llvm::cl::opt<bool> PGSOColdCodeOnly;
+extern llvm::cl::opt<bool> PGSOColdCodeOnlyForInstrPGO;
+extern llvm::cl::opt<bool> PGSOColdCodeOnlyForSamplePGO;
+extern llvm::cl::opt<bool> PGSOColdCodeOnlyForPartialSamplePGO;
extern llvm::cl::opt<bool> ForcePGSO;
extern llvm::cl::opt<int> PgsoCutoffInstrProf;
extern llvm::cl::opt<int> PgsoCutoffSampleProf;
@@ -30,7 +33,6 @@ namespace llvm {
class BasicBlock;
class BlockFrequencyInfo;
class Function;
-class ProfileSummaryInfo;
enum class PGSOQueryType {
IRPass, // A query call from an IR-level transform pass.
@@ -38,6 +40,16 @@ enum class PGSOQueryType {
Other, // Others.
};
+static inline bool isPGSOColdCodeOnly(ProfileSummaryInfo *PSI) {
+ return PGSOColdCodeOnly ||
+ (PSI->hasInstrumentationProfile() && PGSOColdCodeOnlyForInstrPGO) ||
+ (PSI->hasSampleProfile() &&
+ ((!PSI->hasPartialSampleProfile() && PGSOColdCodeOnlyForSamplePGO) ||
+ (PSI->hasPartialSampleProfile() &&
+ PGSOColdCodeOnlyForPartialSamplePGO))) ||
+ (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize());
+}
+
template<typename AdapterT, typename FuncT, typename BFIT>
bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI,
BFIT *BFI, PGSOQueryType QueryType) {
@@ -53,20 +65,20 @@ bool shouldFuncOptimizeForSizeImpl(const FuncT *F, ProfileSummaryInfo *PSI,
if (PGSOIRPassOrTestOnly && !(QueryType == PGSOQueryType::IRPass ||
QueryType == PGSOQueryType::Test))
return false;
- if (PGSOColdCodeOnly ||
- (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize())) {
- // Even if the working set size isn't large, size-optimize cold code.
+ if (isPGSOColdCodeOnly(PSI))
return AdapterT::isFunctionColdInCallGraph(F, PSI, *BFI);
- }
- return !AdapterT::isFunctionHotInCallGraphNthPercentile(
- PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
- F, PSI, *BFI);
+ if (PSI->hasSampleProfile())
+ // The "isCold" check seems to work better for Sample PGO as it could have
+ // many profile-unannotated functions.
+ return AdapterT::isFunctionColdInCallGraphNthPercentile(
+ PgsoCutoffSampleProf, F, PSI, *BFI);
+ return !AdapterT::isFunctionHotInCallGraphNthPercentile(PgsoCutoffInstrProf,
+ F, PSI, *BFI);
}
-template<typename AdapterT, typename BlockT, typename BFIT>
-bool shouldOptimizeForSizeImpl(const BlockT *BB, ProfileSummaryInfo *PSI,
+template<typename AdapterT, typename BlockTOrBlockFreq, typename BFIT>
+bool shouldOptimizeForSizeImpl(BlockTOrBlockFreq BBOrBlockFreq, ProfileSummaryInfo *PSI,
BFIT *BFI, PGSOQueryType QueryType) {
- assert(BB);
if (!PSI || !BFI || !PSI->hasProfileSummary())
return false;
if (ForcePGSO)
@@ -78,14 +90,15 @@ bool shouldOptimizeForSizeImpl(const BlockT *BB, ProfileSummaryInfo *PSI,
if (PGSOIRPassOrTestOnly && !(QueryType == PGSOQueryType::IRPass ||
QueryType == PGSOQueryType::Test))
return false;
- if (PGSOColdCodeOnly ||
- (PGSOLargeWorkingSetSizeOnly && !PSI->hasLargeWorkingSetSize())) {
- // Even if the working set size isn't large, size-optimize cold code.
- return AdapterT::isColdBlock(BB, PSI, BFI);
- }
- return !AdapterT::isHotBlockNthPercentile(
- PSI->hasSampleProfile() ? PgsoCutoffSampleProf : PgsoCutoffInstrProf,
- BB, PSI, BFI);
+ if (isPGSOColdCodeOnly(PSI))
+ return AdapterT::isColdBlock(BBOrBlockFreq, PSI, BFI);
+ if (PSI->hasSampleProfile())
+ // The "isCold" check seems to work better for Sample PGO as it could have
+ // many profile-unannotated functions.
+ return AdapterT::isColdBlockNthPercentile(PgsoCutoffSampleProf,
+ BBOrBlockFreq, PSI, BFI);
+ return !AdapterT::isHotBlockNthPercentile(PgsoCutoffInstrProf, BBOrBlockFreq,
+ PSI, BFI);
}
/// Returns true if function \p F is suggested to be size-optimized based on the
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
index b8a4fe72ea25..ff70446e163d 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -18,10 +18,11 @@
#define LLVM_TRANSFORMS_UTILS_UNIFYFUNCTIONEXITNODES_H
#include "llvm/Pass.h"
-#include "llvm/PassRegistry.h"
namespace llvm {
+class BasicBlock;
+
struct UnifyFunctionExitNodes : public FunctionPass {
BasicBlock *ReturnBlock = nullptr;
BasicBlock *UnwindBlock = nullptr;
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UniqueInternalLinkageNames.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UniqueInternalLinkageNames.h
new file mode 100644
index 000000000000..637b5d8e8e51
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UniqueInternalLinkageNames.h
@@ -0,0 +1,31 @@
+//===-- UniqueInternalLinkageNames.h - Uniq. Int. Linkage Names -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements unique naming of internal linkage symbols with option
+// -funique-internal-linkage-symbols.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_UNIQUEINTERNALLINKAGENAMES_H
+#define LLVM_TRANSFORMS_UTILS_UNIQUEINTERNALLINKAGENAMES_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Simple pass that provides a name to every anonymous globals.
+class UniqueInternalLinkageNamesPass
+ : public PassInfoMixin<UniqueInternalLinkageNamesPass> {
+public:
+ PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_UTILS_UNIQUEINTERNALLINKAGENAMES_H
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnrollLoop.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
index 02b81b4b7ee2..bb3d02b95956 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/UnrollLoop.h
@@ -16,9 +16,7 @@
#define LLVM_TRANSFORMS_UTILS_UNROLLLOOP_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
namespace llvm {
@@ -33,6 +31,8 @@ class MDNode;
class ProfileSummaryInfo;
class OptimizationRemarkEmitter;
class ScalarEvolution;
+class StringRef;
+class Value;
using NewLoopsMap = SmallDenseMap<const Loop *, Loop *, 4>;
@@ -80,19 +80,21 @@ struct UnrollLoopOptions {
LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI,
ScalarEvolution *SE, DominatorTree *DT,
- AssumptionCache *AC, OptimizationRemarkEmitter *ORE,
- bool PreserveLCSSA, Loop **RemainderLoop = nullptr);
-
-bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count,
- bool AllowExpensiveTripCount,
- bool UseEpilogRemainder, bool UnrollRemainder,
- bool ForgetAllSCEV, LoopInfo *LI,
- ScalarEvolution *SE, DominatorTree *DT,
- AssumptionCache *AC, bool PreserveLCSSA,
- Loop **ResultLoop = nullptr);
+ AssumptionCache *AC,
+ const llvm::TargetTransformInfo *TTI,
+ OptimizationRemarkEmitter *ORE, bool PreserveLCSSA,
+ Loop **RemainderLoop = nullptr);
+
+bool UnrollRuntimeLoopRemainder(
+ Loop *L, unsigned Count, bool AllowExpensiveTripCount,
+ bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV,
+ LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC,
+ const TargetTransformInfo *TTI, bool PreserveLCSSA,
+ Loop **ResultLoop = nullptr);
void computePeelCount(Loop *L, unsigned LoopSize,
TargetTransformInfo::UnrollingPreferences &UP,
+ TargetTransformInfo::PeelingPreferences &PP,
unsigned &TripCount, ScalarEvolution &SE);
bool canPeel(Loop *L);
@@ -104,11 +106,12 @@ LoopUnrollResult UnrollAndJamLoop(Loop *L, unsigned Count, unsigned TripCount,
unsigned TripMultiple, bool UnrollRemainder,
LoopInfo *LI, ScalarEvolution *SE,
DominatorTree *DT, AssumptionCache *AC,
+ const TargetTransformInfo *TTI,
OptimizationRemarkEmitter *ORE,
Loop **EpilogueLoop = nullptr);
bool isSafeToUnrollAndJam(Loop *L, ScalarEvolution &SE, DominatorTree &DT,
- DependenceInfo &DI);
+ DependenceInfo &DI, LoopInfo &LI);
bool computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
DominatorTree &DT, LoopInfo *LI, ScalarEvolution &SE,
@@ -117,13 +120,14 @@ bool computeUnrollCount(Loop *L, const TargetTransformInfo &TTI,
unsigned MaxTripCount, bool MaxOrZero,
unsigned &TripMultiple, unsigned LoopSize,
TargetTransformInfo::UnrollingPreferences &UP,
- bool &UseUpperBound);
+ TargetTransformInfo::PeelingPreferences &PP,
-void remapInstruction(Instruction *I, ValueToValueMapTy &VMap);
+ bool &UseUpperBound);
void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI,
ScalarEvolution *SE, DominatorTree *DT,
- AssumptionCache *AC);
+ AssumptionCache *AC,
+ const TargetTransformInfo *TTI);
MDNode *GetUnrollMetadata(MDNode *LoopID, StringRef Name);
@@ -132,9 +136,13 @@ TargetTransformInfo::UnrollingPreferences gatherUnrollingPreferences(
BlockFrequencyInfo *BFI, ProfileSummaryInfo *PSI, int OptLevel,
Optional<unsigned> UserThreshold, Optional<unsigned> UserCount,
Optional<bool> UserAllowPartial, Optional<bool> UserRuntime,
- Optional<bool> UserUpperBound, Optional<bool> UserAllowPeeling,
- Optional<bool> UserAllowProfileBasedPeeling,
- Optional<unsigned> UserFullUnrollMaxCount);
+ Optional<bool> UserUpperBound, Optional<unsigned> UserFullUnrollMaxCount);
+
+TargetTransformInfo::PeelingPreferences
+gatherPeelingPreferences(Loop *L, ScalarEvolution &SE,
+ const TargetTransformInfo &TTI,
+ Optional<bool> UserAllowPeeling,
+ Optional<bool> UserAllowProfileBasedPeeling);
unsigned ApproximateLoopSize(const Loop *L, unsigned &NumCalls,
bool &NotDuplicatable, bool &Convergent,
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/VNCoercion.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/VNCoercion.h
index f67b9ed0afdd..1cc751d1e78a 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/VNCoercion.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/VNCoercion.h
@@ -20,14 +20,14 @@
#ifndef LLVM_TRANSFORMS_UTILS_VNCOERCION_H
#define LLVM_TRANSFORMS_UTILS_VNCOERCION_H
-#include "llvm/IR/IRBuilder.h"
namespace llvm {
-class Function;
+class Constant;
class StoreInst;
class LoadInst;
class MemIntrinsic;
class Instruction;
+class IRBuilderBase;
class Value;
class Type;
class DataLayout;
@@ -44,7 +44,7 @@ bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy,
///
/// If we can't do it, return null.
Value *coerceAvailableValueToLoadType(Value *StoredVal, Type *LoadedTy,
- IRBuilder<> &IRB, const DataLayout &DL);
+ IRBuilderBase &IRB, const DataLayout &DL);
/// This function determines whether a value for the pointer LoadPtr can be
/// extracted from the store at DepSI.
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize.h
index bca78d073003..bc7514267778 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize.h
@@ -138,6 +138,12 @@ bool vectorizeBasicBlock(Pass *P, BasicBlock &BB,
//
Pass *createLoadStoreVectorizerPass();
+//===----------------------------------------------------------------------===//
+//
+// Optimize partial vector operations using target cost models.
+//
+Pass *createVectorCombinePass();
+
} // End llvm namespace
#endif
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
index d1e7acc877bf..c6c3450f7760 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorizationLegality.h
@@ -198,7 +198,7 @@ class LoopVectorizationLegality {
public:
LoopVectorizationLegality(
Loop *L, PredicatedScalarEvolution &PSE, DominatorTree *DT,
- TargetTransformInfo *TTI, TargetLibraryInfo *TLI, AliasAnalysis *AA,
+ TargetTransformInfo *TTI, TargetLibraryInfo *TLI, AAResults *AA,
Function *F, std::function<const LoopAccessInfo &(Loop &)> *GetLAA,
LoopInfo *LI, OptimizationRemarkEmitter *ORE,
LoopVectorizationRequirements *R, LoopVectorizeHints *H, DemandedBits *DB,
@@ -208,7 +208,7 @@ public:
/// ReductionList contains the reduction descriptors for all
/// of the reductions that were found in the loop.
- using ReductionList = DenseMap<PHINode *, RecurrenceDescriptor>;
+ using ReductionList = MapVector<PHINode *, RecurrenceDescriptor>;
/// InductionList saves induction variables and maps them to the
/// induction descriptor.
@@ -235,13 +235,13 @@ public:
PHINode *getPrimaryInduction() { return PrimaryInduction; }
/// Returns the reduction variables found in the loop.
- ReductionList *getReductionVars() { return &Reductions; }
+ ReductionList &getReductionVars() { return Reductions; }
/// Returns the induction variables found in the loop.
- InductionList *getInductionVars() { return &Inductions; }
+ InductionList &getInductionVars() { return Inductions; }
/// Return the first-order recurrences found in the loop.
- RecurrenceSet *getFirstOrderRecurrences() { return &FirstOrderRecurrences; }
+ RecurrenceSet &getFirstOrderRecurrences() { return FirstOrderRecurrences; }
/// Return the set of instructions to sink to handle first-order recurrences.
DenseMap<Instruction *, Instruction *> &getSinkAfter() { return SinkAfter; }
@@ -312,6 +312,12 @@ public:
// Returns true if the NoNaN attribute is set on the function.
bool hasFunNoNaNAttr() const { return HasFunNoNaNAttr; }
+ /// Returns all assume calls in predicated blocks. They need to be dropped
+ /// when flattening the CFG.
+ const SmallPtrSetImpl<Instruction *> &getConditionalAssumes() const {
+ return ConditionalAssumes;
+ }
+
private:
/// Return true if the pre-header, exiting and latch blocks of \p Lp and all
/// its nested loops are considered legal for vectorization. These legal
@@ -468,6 +474,10 @@ private:
/// While vectorizing these instructions we have to generate a
/// call to the appropriate masked intrinsic
SmallPtrSet<const Instruction *, 8> MaskedOp;
+
+ /// Assume instructions in predicated blocks must be dropped if the CFG gets
+ /// flattened.
+ SmallPtrSet<Instruction *, 8> ConditionalAssumes;
};
} // namespace llvm
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
index ac6efc7c695f..ecb44a7b1518 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h
@@ -56,13 +56,13 @@
#ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
#define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
-#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include <functional>
namespace llvm {
+class AAResults;
class AssumptionCache;
class BlockFrequencyInfo;
class DemandedBits;
@@ -116,8 +116,18 @@ struct LoopVectorizeOptions {
}
};
+/// Storage for information about made changes.
+struct LoopVectorizeResult {
+ bool MadeAnyChange;
+ bool MadeCFGChange;
+
+ LoopVectorizeResult(bool MadeAnyChange, bool MadeCFGChange)
+ : MadeAnyChange(MadeAnyChange), MadeCFGChange(MadeCFGChange) {}
+};
+
/// The LoopVectorize Pass.
struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
+private:
/// If false, consider all loops for interleaving.
/// If true, only loops that explicitly request interleaving are considered.
bool InterleaveOnlyWhenForced;
@@ -126,9 +136,8 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
/// If true, only loops that explicitly request vectorization are considered.
bool VectorizeOnlyWhenForced;
- LoopVectorizePass(LoopVectorizeOptions Opts = {})
- : InterleaveOnlyWhenForced(Opts.InterleaveOnlyWhenForced),
- VectorizeOnlyWhenForced(Opts.VectorizeOnlyWhenForced) {}
+public:
+ LoopVectorizePass(LoopVectorizeOptions Opts = {});
ScalarEvolution *SE;
LoopInfo *LI;
@@ -137,7 +146,7 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
BlockFrequencyInfo *BFI;
TargetLibraryInfo *TLI;
DemandedBits *DB;
- AliasAnalysis *AA;
+ AAResults *AA;
AssumptionCache *AC;
std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
OptimizationRemarkEmitter *ORE;
@@ -146,12 +155,13 @@ struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
// Shim for old PM.
- bool runImpl(Function &F, ScalarEvolution &SE_, LoopInfo &LI_,
- TargetTransformInfo &TTI_, DominatorTree &DT_,
- BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_,
- DemandedBits &DB_, AliasAnalysis &AA_, AssumptionCache &AC_,
- std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
- OptimizationRemarkEmitter &ORE_, ProfileSummaryInfo *PSI_);
+ LoopVectorizeResult
+ runImpl(Function &F, ScalarEvolution &SE_, LoopInfo &LI_,
+ TargetTransformInfo &TTI_, DominatorTree &DT_,
+ BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_, DemandedBits &DB_,
+ AAResults &AA_, AssumptionCache &AC_,
+ std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
+ OptimizationRemarkEmitter &ORE_, ProfileSummaryInfo *PSI_);
bool processLoop(Loop *L);
};
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
index 237781dfe22e..77236dec75dc 100644
--- a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/SLPVectorizer.h
@@ -24,7 +24,6 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/IR/PassManager.h"
-#include "llvm/Support/CommandLine.h"
namespace llvm {
@@ -55,8 +54,6 @@ class BoUpSLP;
} // end namespace slpvectorizer
-extern cl::opt<bool> RunSLPVectorization;
-
struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
using StoreList = SmallVector<StoreInst *, 8>;
using StoreListMap = MapVector<Value *, StoreList>;
@@ -96,11 +93,15 @@ private:
bool tryToVectorizePair(Value *A, Value *B, slpvectorizer::BoUpSLP &R);
/// Try to vectorize a list of operands.
- /// \param UserCost Cost of the user operations of \p VL if they may affect
- /// the cost of the vectorization.
+ /// When \p InsertUses is provided and its entries are non-zero
+ /// then users of \p VL are known to be InsertElement instructions
+ /// each associated with same VL entry index. Their cost is then
+ /// used to adjust cost of the vectorization assuming instcombine pass
+ /// then optimizes ExtractElement-InsertElement sequence.
/// \returns true if a value was vectorized.
bool tryToVectorizeList(ArrayRef<Value *> VL, slpvectorizer::BoUpSLP &R,
- int UserCost = 0, bool AllowReorder = false);
+ bool AllowReorder = false,
+ ArrayRef<Value *> InsertUses = None);
/// Try to vectorize a chain that may start at the operands of \p I.
bool tryToVectorize(Instruction *I, slpvectorizer::BoUpSLP &R);
diff --git a/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/VectorCombine.h b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/VectorCombine.h
new file mode 100644
index 000000000000..15e2331141ff
--- /dev/null
+++ b/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/VectorCombine.h
@@ -0,0 +1,30 @@
+//===-------- VectorCombine.h - Optimize partial vector operations --------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass optimizes scalar/vector interactions using target cost models. The
+// transforms implemented here may not fit in traditional loop-based or SLP
+// vectorization passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_VECTOR_VECTORCOMBINE_H
+#define LLVM_TRANSFORMS_VECTOR_VECTORCOMBINE_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Optimize scalar/vector interactions in IR using target cost models.
+struct VectorCombinePass : public PassInfoMixin<VectorCombinePass> {
+public:
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &);
+};
+
+}
+#endif // LLVM_TRANSFORMS_VECTOR_VECTORCOMBINE_H
+
diff --git a/contrib/llvm-project/llvm/include/llvm/XRay/Graph.h b/contrib/llvm-project/llvm/include/llvm/XRay/Graph.h
index 004681512800..d368f7e724d8 100644
--- a/contrib/llvm-project/llvm/include/llvm/XRay/Graph.h
+++ b/contrib/llvm-project/llvm/include/llvm/XRay/Graph.h
@@ -126,14 +126,14 @@ private:
/// set.
template <bool IsConst, bool IsOut,
typename BaseIt = typename NeighborSetT::const_iterator,
- typename T = typename std::conditional<IsConst, const EdgeValueType,
- EdgeValueType>::type>
+ typename T =
+ std::conditional_t<IsConst, const EdgeValueType, EdgeValueType>>
class NeighborEdgeIteratorT
: public iterator_adaptor_base<
NeighborEdgeIteratorT<IsConst, IsOut>, BaseIt,
typename std::iterator_traits<BaseIt>::iterator_category, T> {
using InternalEdgeMapT =
- typename std::conditional<IsConst, const EdgeMapT, EdgeMapT>::type;
+ std::conditional_t<IsConst, const EdgeMapT, EdgeMapT>;
friend class NeighborEdgeIteratorT<false, IsOut, BaseIt, EdgeValueType>;
friend class NeighborEdgeIteratorT<true, IsOut, BaseIt,
@@ -144,7 +144,7 @@ private:
public:
template <bool IsConstDest,
- typename = typename std::enable_if<IsConstDest && !IsConst>::type>
+ typename = std::enable_if<IsConstDest && !IsConst>>
operator NeighborEdgeIteratorT<IsConstDest, IsOut, BaseIt,
const EdgeValueType>() const {
return NeighborEdgeIteratorT<IsConstDest, IsOut, BaseIt,
@@ -199,9 +199,9 @@ public:
public:
using iterator = NeighborEdgeIteratorT<isConst, isOut>;
using const_iterator = NeighborEdgeIteratorT<true, isOut>;
- using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+ using GraphT = std::conditional_t<isConst, const Graph, Graph>;
using InternalEdgeMapT =
- typename std::conditional<isConst, const EdgeMapT, EdgeMapT>::type;
+ std::conditional_t<isConst, const EdgeMapT, EdgeMapT>;
private:
InternalEdgeMapT &M;
@@ -272,10 +272,10 @@ public:
/// the number of elements in the range and whether the range is empty.
template <bool isConst> class VertexView {
public:
- using iterator = typename std::conditional<isConst, ConstVertexIterator,
- VertexIterator>::type;
+ using iterator =
+ std::conditional_t<isConst, ConstVertexIterator, VertexIterator>;
using const_iterator = ConstVertexIterator;
- using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+ using GraphT = std::conditional_t<isConst, const Graph, Graph>;
private:
GraphT &G;
@@ -309,10 +309,10 @@ public:
/// the number of elements in the range and whether the range is empty.
template <bool isConst> class EdgeView {
public:
- using iterator = typename std::conditional<isConst, ConstEdgeIterator,
- EdgeIterator>::type;
+ using iterator =
+ std::conditional_t<isConst, ConstEdgeIterator, EdgeIterator>;
using const_iterator = ConstEdgeIterator;
- using GraphT = typename std::conditional<isConst, const Graph, Graph>::type;
+ using GraphT = std::conditional_t<isConst, const Graph, Graph>;
private:
GraphT &G;
diff --git a/contrib/llvm-project/llvm/include/llvm/XRay/InstrumentationMap.h b/contrib/llvm-project/llvm/include/llvm/XRay/InstrumentationMap.h
index 5cbe5c44893b..aae90345cbb7 100644
--- a/contrib/llvm-project/llvm/include/llvm/XRay/InstrumentationMap.h
+++ b/contrib/llvm-project/llvm/include/llvm/XRay/InstrumentationMap.h
@@ -50,6 +50,8 @@ struct SledEntry {
/// Whether the sled was annotated to always be instrumented.
bool AlwaysInstrument;
+
+ unsigned char Version;
};
struct YAMLXRaySledEntry {
@@ -59,6 +61,7 @@ struct YAMLXRaySledEntry {
SledEntry::FunctionKinds Kind;
bool AlwaysInstrument;
std::string FunctionName;
+ unsigned char Version;
};
/// The InstrumentationMap represents the computed function id's and indicated
@@ -120,6 +123,7 @@ template <> struct MappingTraits<xray::YAMLXRaySledEntry> {
IO.mapRequired("kind", Entry.Kind);
IO.mapRequired("always-instrument", Entry.AlwaysInstrument);
IO.mapOptional("function-name", Entry.FunctionName);
+ IO.mapOptional("version", Entry.Version, 0);
}
static constexpr bool flow = true;
diff --git a/contrib/llvm-project/llvm/include/llvm/module.modulemap b/contrib/llvm-project/llvm/include/llvm/module.modulemap
index d281682ae003..b262311a96a0 100644
--- a/contrib/llvm-project/llvm/include/llvm/module.modulemap
+++ b/contrib/llvm-project/llvm/include/llvm/module.modulemap
@@ -29,7 +29,6 @@ module LLVM_Backend {
exclude header "CodeGen/LinkAllCodegenComponents.h"
// These are intended for (repeated) textual inclusion.
- textual header "CodeGen/CommandFlags.inc"
textual header "CodeGen/DIEValue.def"
}
}
@@ -47,6 +46,11 @@ module LLVM_Bitcode {
module * { export * }
}
+module LLVM_Bitstream {
+ requires cplusplus
+ umbrella "Bitstream"
+ module * { export * }
+}
module LLVM_BinaryFormat {
requires cplusplus
@@ -71,6 +75,7 @@ module LLVM_BinaryFormat {
textual header "BinaryFormat/ELFRelocs/RISCV.def"
textual header "BinaryFormat/ELFRelocs/Sparc.def"
textual header "BinaryFormat/ELFRelocs/SystemZ.def"
+ textual header "BinaryFormat/ELFRelocs/VE.def"
textual header "BinaryFormat/ELFRelocs/x86_64.def"
textual header "BinaryFormat/WasmRelocs.def"
textual header "BinaryFormat/MsgPack.def"
@@ -114,6 +119,7 @@ module LLVM_DebugInfo_PDB {
exclude header "DebugInfo/PDB/DIA/DIAEnumSourceFiles.h"
exclude header "DebugInfo/PDB/DIA/DIAEnumSymbols.h"
exclude header "DebugInfo/PDB/DIA/DIAEnumTables.h"
+ exclude header "DebugInfo/PDB/DIA/DIAError.h"
exclude header "DebugInfo/PDB/DIA/DIAFrameData.h"
exclude header "DebugInfo/PDB/DIA/DIAInjectedSource.h"
exclude header "DebugInfo/PDB/DIA/DIALineNumber.h"
@@ -208,8 +214,8 @@ module LLVM_Pass {
// PassSupport.h and PassAnalysisSupport.h are made available only through
// Pass.h.
header "Pass.h"
- header "PassSupport.h"
- header "PassAnalysisSupport.h"
+ textual header "PassSupport.h"
+ textual header "PassAnalysisSupport.h"
export *
}
@@ -230,10 +236,11 @@ module LLVM_intrinsic_gen {
extern module LLVM_Extern_IR_Attributes_Gen "module.extern.modulemap"
export *
}
- module IR_CallSite { header "IR/CallSite.h" export * }
+ module IR_AbstractCallSite { header "IR/AbstractCallSite.h" export * }
module IR_ConstantFolder { header "IR/ConstantFolder.h" export * }
module IR_GlobalVariable { header "IR/GlobalVariable.h" export * }
module IR_NoFolder { header "IR/NoFolder.h" export * }
+ module IRBuilderFolder { header "IR/IRBuilderFolder.h" export * }
module IR_Module { header "IR/Module.h" export * }
module IR_ModuleSummaryIndex { header "IR/ModuleSummaryIndex.h" export * }
module IR_ModuleSummaryIndexYAML { header "IR/ModuleSummaryIndexYAML.h" export * }
@@ -244,13 +251,15 @@ module LLVM_intrinsic_gen {
// Intrinsics.h
module IR_CFG { header "IR/CFG.h" export * }
- module IR_CFGDiff { header "IR/CFGDiff.h" export * }
module IR_ConstantRange { header "IR/ConstantRange.h" export * }
module IR_Dominators { header "IR/Dominators.h" export * }
module Analysis_PostDominators { header "Analysis/PostDominators.h" export * }
module Analysis_DomTreeUpdater { header "Analysis/DomTreeUpdater.h" export * }
module IR_IRBuilder { header "IR/IRBuilder.h" export * }
+ module IR_IRPrintingPasses { header "IR/IRPrintingPasses.h" export * }
+ module IR_MatrixBuilder { header "IR/MatrixBuilder.h" export * }
module IR_PassManager { header "IR/PassManager.h" export * }
+ module IR_PassManagerImpl { header "IR/PassManagerImpl.h" export * }
module IR_PredIteratorCache { header "IR/PredIteratorCache.h" export * }
module IR_Verifier { header "IR/Verifier.h" export * }
module IR_InstIterator { header "IR/InstIterator.h" export * }
@@ -282,6 +291,7 @@ module LLVM_IR {
textual header "IR/Metadata.def"
textual header "IR/FixedMetadataKinds.def"
textual header "IR/Value.def"
+ textual header "IR/VPIntrinsics.def"
textual header "IR/RuntimeLibcalls.def"
}
@@ -308,8 +318,6 @@ module LLVM_MC {
umbrella "MC"
module * { export * }
-
- textual header "MC/MCTargetOptionsCommandFlags.inc"
}
// Used by llvm-tblgen